【问题标题】:How do I prevent C# from prefixing the temporary path to my original path?如何防止 C# 将临时路径作为原始路径的前缀?
【发布时间】:2021-08-27 05:35:21
【问题描述】:

我正在尝试在自定义操作中编辑已安装的 cmd 文件:

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

它在PublishProduct 操作之后调用。 问题是,我找不到该文件,因为由于某种原因,当它使用诸如Directory.GetFiles(ABSOLUTE_PATH) 之类的方法时,它会在绝对路径之前添加临时安装程序目录的路径。以下是日志:

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)

正如我在日志中看到的,它将操作提取到 C:\Windows\Installer\MSI941A.tmp-\ 文件夹中,而不是 C# 方法将该文件夹添加到我传递给函数的任何路径中,如下所示:

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

而我经过的路径是C:\Program Files\SomeApp\

这是发生的代码:

 [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
 }

如何防止 C# 将临时路径作为原始路径的前缀?

编辑: 正如我所观察到的,这只发生在非常量变量上。如果我使用硬编码路径创建一个 const 变量,C# 不会预先添加该临时文件夹路径...

【问题讨论】:

    标签: c# wix windows-installer wix3


    【解决方案1】:

    延迟的自定义操作只能在执行序列表中的 InstallInitialize 和 InstallFinalize 操作之间进行排序。

    所以你有两个选择:

    1. 在 InstallInitialize 和 InstallFinalize 之间移动执行操作。

    2. 将执行更改为“立即”。 In some cases this way isn't recomended,一切看你的目的。

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

    并将您的 CustomAction 更改为

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

    【讨论】:

    • 我的错,我在PublishProduct 之后运行我的自定义操作,抱歉。对帖子进行了编辑
    • 但选项 2 仍然有效。如果您只是更改已安装的文件,而不是操作系统状态或其他可能依赖于其他软件的东西 - 没关系。
    • 如果我执行immediate 操作,cmd 文件由于某种原因尚未安装,所以我找不到它。但是通过 deferred 操作 - 它就在那里。
    【解决方案2】:

    问题在于方式,我正在将属性传递给我的自定义操作。

    我曾经通过 Property 元素来实现,但在延迟自定义操作的情况下,我必须通过另一个 CustomAction 元素来传递它们,如 answer 中所示。

    不幸的是,这仅适用于直接 CA,这意味着如果您想在延迟 CA 中使用此属性的值,您将需要有两个自定义操作:

    1. CA 1 将 CA 的 CustomActionData 设置为立即执行。 (请记住使用为您的 CustomAction 定义的相同名称来命名属性。
    2. CA 2 具有使用 CustomActionData 的特定逻辑的 CA。

    【讨论】:

      猜你喜欢
      • 2014-05-27
      • 2015-01-30
      • 2018-09-13
      • 2015-03-06
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-26
      相关资源
      最近更新 更多