简体   繁体   中英

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...

Deferred custom actions can only be sequenced between the InstallInitialize and InstallFinalize actions in execute sequence tables.

So you have two options:

  1. Move execution of your action between the InstallInitialize and InstallFinalize.

  2. Change execute to "immediate". In some cases this way isn't recomended , everything depends on your purposes.

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

and change your CustomAction to

[CustomAction]
public static ActionResult EditWebsharkScriptAction(Session session)
{            
    var install_dir = session["INSTALLFOLDER"];
    session.Log("CUSTOM_DEBUG: " + install_dir);
    var files = Directory.GetFiles(install_dir); 
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM