WiX – copy arbitrary files

590 views Asked by At

The folder where my setup.exe is located contains a subfolder CALhaving files named something like xyz1234.cal – their names vary from customer to customer. These files have to be copied into a folder CAL in the target directory. So I created a CustomAction and a C# dll which uses the File.Copy() function. My C# function receives the strings srcDir and destDir as parameters, e.g. D:\installation\CAL and C:\MyApp\CAL. However, when I check the existence of the folders with Directory.Exists(srcDir), an Exception is thrown, although the directory D:\installation\CAL exists:

ERROR in custom action myFunction System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSID839.tmp-\D:\installation\CAL'.

This happens no matter whether the CustomAcion is executed immediate or deferred. C:\Windows\Installer\MSID839.tmp-\ seems to be the path of the executed assembly, but I certainly don’t want to have it as a part of the FullPath. How can I get rid of it?

CustomAction and properties are defined like so: <CustomAction Id='myCA' BinaryKey='myCABin' DllEntry='myFunction' Execute="deferred" HideTarget="no" Impersonate="no"/> <Property Id="myCA" Value="Arg1=[CURRENTDIRECTORY];Arg2=[INSTALLDIR]" />

The parameters are used like so:

CustomActionData data = session.CustomActionData;
string srcDir = data["Arg1"]+ "\\CAL";
string destDir = data["Arg2"]+ "\\CAL";
if (Directory.Exists(srcDir))
    // copy files
2

There are 2 answers

5
sirdank On BEST ANSWER

I recreated your app and it works fine. Here is my wix code (it's inside my product node):

<CustomAction Id='Test' BinaryKey='RegistryHelperCA' DllEntry='Test' Execute="deferred" HideTarget="no" Impersonate="no"/>
<Property Id="Test" Value="Arg1=[CURRENTDIRECTORY];Arg2=[INSTALLDIR]" />

<InstallExecuteSequence>
  <Custom Action="Test" After="InstallFiles"></Custom>
</InstallExecuteSequence>

My custom action:

    [CustomAction("Test")]
    public static ActionResult Test(Session session)
    {
        string dir = session.CustomActionData["Arg1"];
        session.Log("DIRECTORY equals " + dir);

        if (Directory.Exists(dir))
            session.Log("Success");

        return ActionResult.Success;
    }

It spits out dir as C:\Users\user\Desktop. Verify you aren't assigning to your CURRENTDIRECTORY property anywhere and, if you don't find anything, try setting your custom action to Execute="immediate" and accessing the data like this

string srcDir = session["CURRENTDIRECTORY"]+ "\\CAL";

If that doesn't work, surely that property is being overwritten somewhere. Good luck!

0
Germany's next Dilbert On

After some trial-and-error-sessions I found that Directory.Exists(srcDir) and Directory.Exists(destDir) didn't work, because the not the values but the property names are passed as parameter to the Exist() function - in contrast to session.Log(srcDir) which properly yields the value.

Finally I ended up with setting execute="immediate" and retrieving the values like so:

srcDir = session["CURRENTDIRECTORY"];
destDir = session.GetTargetPath("INSTALLDIR");