Replacing existing files when installing a package (packagecreator)

Topics: Feature requests, General, Standard packages
Aug 28, 2011 at 11:57 AM
Edited Aug 28, 2011 at 3:31 PM

Hi,

I created a local package (how easy is that!!). But I need to replace an existing file which apparently the package installer does not allow.
Is that even possible (if not can it be added) or should I just add instructions to remove the file by hand before installing.

Really nice would it be if the package installer/creator could modify files (not an easy task i reckon) like adding (default)settings to the web.config.
Adding to that would it be convenient if some kind of wizard could be started when installing packages, i.e. let the user fill in some (default) values while installing.

UPDATE:
Found a solution by editing the package contents by hand, i.e. modify the install.xml in the package zip to set the allowOverwrite attribute to true.
A nice addition to the packagecreator would be to allow the creator to set that property while adding something to the package. 

UPDATE 2:
Overwriting existing files might render some unwanted results when uninstalling a package (when allowed) and the files are deleted. I modified the FilePackageFragmentInstaller and the FilePackageFragmentUninstaller in the Core.PackageSystem to make copies of the files being replaced to the package directory before overwriting. And copying them back when uninstalling before deleting the package content. Anyone interested in those modifications (about 30 lines of code)?

I also noticed that on uninstall the package directory and its containing directories are left on the file system (using DirectoryUtils.DeleteFilesRecursively in PackageManagerUninstallProcessFinalizeProcess). What is(are) the reason(s) for that?

mzZzl,
JamBo 

Aug 29, 2011 at 2:18 PM

 Hi iTouch,

Found a solution by editing the package contents by hand, i.e. modify the install.xml in the package zip to set the allowOverwrite attribute to true.

Thank you for bringing up this topic. At the moment, it requires manual editing of install.xml

We have updated the documentation with the instructions on how to do it: http://docs.composite.net/Composite.Tools.PackageCreator#allowOverwrite

(You don't need it, since you have figured that out for yourself :))

Really nice would it be if the package installer/creator could modify files (not an easy task i reckon) like adding (default)settings to the web.config.
Adding to that would it be convenient if some kind of wizard could be started when installing packages, i.e. let the user fill in some (default) values while installing.

Yes, you can actually modify files like web.config using your XSLT skills in your package's install.xml.  The documentation on XML format to use here is underway.

Once the doc is done,  I'll give the link to it here

/Vitaly

 

Aug 30, 2011 at 9:16 AM

Hi iTouch,

Here is a quick guide on modifying files like web.config via packages: http://docs.composite.net/Modifying-Files-via-Packages

/Vitaly

Sep 4, 2011 at 11:42 AM

Vitaly,

Thnx, I will give it a go.

mzZzl,
JamBo 

Sep 4, 2011 at 1:48 PM
Edited Sep 4, 2011 at 1:50 PM

For anyone wanting to modify the appSettings node...

After reading (and implementing) the link wysocki provided above and you want to modify appSettings:

Install.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" />
 
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>
  
  <!-- Match when no appSettings are available -->
  <xsl:template match="configuration">
    <xsl:copy>
      <xsl:if test="count(appSettings) = 0">
        <appSettings>
          <add key="yourSetting" value="yourValue"/>
        </appSettings>
      </xsl:if>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <!-- Match when appSettings are available, then match yourSetting -->
  <xsl:template match="configuration/appSettings">
    <xsl:copy>
      <xsl:if test="count(add[@key='yourSetting']) = 0">
          <add key="yourSetting" value="yourValue"/>
      </xsl:if>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Uninstall.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="configuration/appSettings/add[@key='yourSetting']" />
</xsl:stylesheet>

This way you add the appSettings node when it does not exist, or add the the 'yourSetting' key if it not exists (without messing with existing keys).

The unistall will only remove the 'yourSetting' key and if there are no more keys present it will leave an empty appSettings node.

XSLT is not my strong point, so this could probably be optimized.
Hope this helps anyone.

mzZzl,
JamBo 

Sep 4, 2011 at 7:28 PM
Edited Sep 4, 2011 at 7:28 PM

Just a small correction. While processing XSLT it's impossible to add a node and than an attribute. So instead of 

     <xsl:copy>

      <xsl:if test="count(add[@key='yourSetting']) = 0">
          <add key="yourSetting" value="yourValue"/>
      </xsl:if>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>

you should have

    <xsl:copy>
      <xsl:apply-templates select="@*" />
       <!-- new tag will be the first one -->
      <xsl:if test="count(add[@key='yourSetting']) = 0">
          <add key="yourSetting" value="yourValue"/>
      </xsl:if>
      <xsl:apply-templates select="node()" />
    </xsl:copy>

or
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
       <!-- new tag will be the last one -->
      <xsl:if test="count(add[@key='yourSetting']) = 0">
          <add key="yourSetting" value="yourValue"/>
      </xsl:if>
    </xsl:copy> 
Sep 5, 2011 at 7:54 AM

Dmitry,

Thnx for the update, i'll modify my code.

Is it possible to launch a dialog/wizard when installing a package? So the user can enter some default information.

mzZzl,
JamBo