Search code examples
c#wixwindows-installerwix3

How do I prevent C# from prefixing the temporary path to my original path?


I'm trying to edit my installed cmd file in my custom action:

<CustomAction
 Id="CA_EditScriptAction"
 Return="check"
 Execute="deferred"
 Impersonate="no"
 BinaryKey="CustomActions"
 DllEntry="EditScriptAction"
 />

It's called after PublishProduct action. The thing is, I can't find the file, because for some reason when it uses such methods as Directory.GetFiles(ABSOLUTE_PATH) it prepends to an absolute path a path of temporary installer directory. Here are the logs:

SFXCA: Extracting custom action to temporary directory: C:\Windows\Installer\MSI941A.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action MSIActions!MSIActions.CustomActions.EditScriptAction
CUSTOM_DEBUG: C:\Program Files\SomeApp\
ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileSystemEnumerableIterator`1.CommonInit()
   at System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
   at System.IO.Directory.GetFiles(String path)
   at MSIActions.CustomActions.EditScriptAction(Session session) in D:\Projects\Visual Studio\app\MSIActions\CustomAction.cs:line 57
CustomAction CA_EditScriptAction returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)

As I can see in the logs, it extracts the action into C:\Windows\Installer\MSI941A.tmp-\ folder, than C# methods prepend that folder to whatever path I pass to functions, like here:

ERROR in EditScriptAction: System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Windows\Installer\MSI941A.tmp-\C:\Program Files\SomeApp\'.

while the path I'm passing is C:\Program Files\SomeApp\.

Here's the code where it happens:

 [CustomAction]
 public static ActionResult EditWebsharkScriptAction(Session session)
 {            
     CustomActionData data = session.CustomActionData;
     var install_dir = data["INSTALLFOLDER"];
     session.Log("CUSTOM_DEBUG: " + install_dir);

     var files = Directory.GetFiles(install_dir); //Exception is thrown here

     //the rest of the code
 }

How do I prevent C# from prefixing the temporary path to my original path?

EDIT: As I observed, this happens only to non-const variables. If I make a const variable with a hard-coded path, C# doesn't prepend that temporary folder path...


Solution

  • The problem lied in the way, I was passing properties to my custom action.

    I've used to do it via Property element, but in case of deferred custom actions I must pass them via another CustomAction element as presented in this answer.

    Unfortunately this will work in immediate CA only, this means that if you want to use the value of this property in a deferred CA you will need to have two custom actions:

    1. CA 1 to set the CustomActionData for the CA executed as immediate. (Remember to name the property with the same name defined for your CustomAction.
    2. CA 2 the CA with the specific logic that consumes CustomActionData.