You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让MSI安装至每次唯一的目录?若用自定义动作应置于何处?

如何让MSI每次安装都将文件部署到唯一目录?

我希望实现如下等效的WiX目录配置:

<Directory Id="TARGETDIR" Name="SourceDir">
    <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLDIR" Name="$(var.MyProductName)">
            <Directory Id="SXSBASEDIR" Name="SxS">
                <Directory Id="SXSDIR" Name="<<Unique-ID>>">
                    <Directory Id="BINDIR" Name="bin" />
                </Directory>
            </Directory>
        </Directory>
    </Directory>
</Directory>

其中<<Unique-ID>>必须在每次安装时都不同:首次安装后文件部署到\Program Files\MyProductName\SxS\<<Unique-ID-1>>\bin;卸载后重新安装同一MSI时,文件要部署到\Program Files\MyProductName\SxS\<<Unique-ID-2>>\bin。

我曾尝试用DATE和TIME变量生成<<Unique-ID>>,但它们包含文件名非法字符,且格式受区域设置影响。恳请提供实现建议;若只能使用自定义动作,请问应将其放置在InstallExecuteSequence的哪个位置?


需求背景

我开发了一款内核模式文件系统驱动(FSD),受Windows文件系统设计限制,FSD加载后难以卸载,导致卸载和升级操作必须重启系统。

为此我提出一种解决方案:将FSD安装到每次安装都唯一的目录,以此支持同时加载多个FSD实例(包括当前安装的实例和已卸载的旧实例,FSD已修改为支持并行运行)。

场景示例:

  1. 用户安装MyProductName.msi
    • FSD被安装到\Program Files\MyProductName\SxS\1\bin
  2. FSD被加载,且可能无法卸载
  3. 用户卸载MyProductName.msi
    • Windows安装程序将\Program Files\MyProductName\SxS\1\bin标记为待删除,但目录仍保留
  4. 用户重新安装同一MyProductName.msi
    • FSD被安装到\Program Files\MyProductName\SxS\2\bin
  5. FSD再次被加载
  6. 此时存在两个相同的FSD实例:
    • 原安装的FSD会在重启后消失,其所在目录\Program Files\MyProductName\SxS\1\bin已标记为待删除,重启后将被移除
    • 当前安装的FSD会在重启后保留,其所在目录为\Program Files\MyProductName\SxS\2\bin

实现方案

1. 生成合法的唯一目录名

推荐两种生成方式,都能避免非法字符和区域设置问题:

  • GUID截取法:在自定义动作中生成一个全新的GUID,去掉其中的-符号(比如把{12345678-1234-1234-1234-1234567890AB}转为123456781234123412341234567890AB),将这个字符串作为SXSDIR的Name属性值。GUID本身全球唯一,完全满足每次安装生成不同ID的需求,且不含任何非法字符。
  • 序号递增法:在自定义动作中遍历SxS目录下的所有子目录,提取其中的数字序号,找到最大值后加1作为新的ID(首次安装时目录为空,直接设为1)。这种方式生成的ID更直观,适合需要清晰序号的场景。

2. 自定义动作的位置要求

如果使用自定义动作来设置唯一目录,必须将其放置在InstallExecuteSequence的**CostInitialize之后、CostFinalize之前**,且设为**即时执行(immediate)**类型。

原因是:Windows Installer在CostInitialize阶段完成目录结构的初始化,此时可以修改目录属性;而CostFinalize阶段会计算磁盘空间、确定最终安装路径,因此必须在这之前完成唯一目录的设置,确保后续文件部署使用正确路径。

WiX配置示例:

<!-- 先定义自定义动作的DLL -->
<Binary Id="CustomActionsDLL" SourceFile="path/to/your/CustomActions.dll" />

<!-- 定义自定义动作 -->
<CustomAction Id="SetUniqueSXSDir" BinaryKey="CustomActionsDLL" DllEntry="SetUniqueSXSDir" Execute="immediate" />

<!-- 在执行序列中指定位置 -->
<InstallExecuteSequence>
    <Custom Action="SetUniqueSXSDir" After="CostInitialize" />
</InstallExecuteSequence>

内容的提问来源于stack exchange,提问作者Bill Zissimopoulos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 20:27:48