首页 > 解决方案 > 如何使用 Wix 将文件安装到 D:驱动器(并检查 D:不是 CD ROM)

问题描述

我现在正在玩 WiX 几个星期,如果它不是 CD-ROM 驱动器,我想将文件安装到 D:-驱动器。否则它必须安装到 C:。

我创建了这个自定义操作来查看驱动器是否已修复并准备就绪:

    [CustomAction]
    public static ActionResult CheckDataDrive(Session session)
    {
        ActionResult retVal;

        session.Log("Begin CheckDataDrive");
        if (TrySetTargetDir("D", session))
        {
            retVal = ActionResult.Success;
        }
        else if (TrySetTargetDir("C", session))
        {
            retVal = ActionResult.Success;
        }
        else
        {
            retVal = ActionResult.Failure;
        }
        session.Log("End CheckDataDrive");

        return retVal;
    }

    private static bool TrySetTargetDir(string driveLetter, Session session)
    {
        var driveInfo = new DriveInfo(driveLetter);
        if (driveInfo.DriveType != DriveType.Fixed || !driveInfo.IsReady)
            return false;

        // Set the INSTALLFOLDER
        session["INSTALLFOLDER"] = session["INSTALLFOLDER"].Replace(session["TARGETDIR"], $"{driveLetter}:\\");
        session.Log($"INSTALLFOLDER changed to {session["INSTALLFOLDER"]}");
        return true;
    }

这就是我在 Wix 产品中所拥有的:

    <Feature Id="ProductFeature" Title="SetupGatewayFiles" Level="1">
        <ComponentGroupRef Id="ConfigFiles" />
    </Feature>

  <InstallExecuteSequence>
  <!-- Sets TARGETDIR to either D:\ or C:\ -->
    <Custom Action='CheckDrive' After="CostFinalize" />
  </InstallExecuteSequence>

其余的都在这个片段中:

<Fragment>
  <Binary Id="CustomActionBinary" SourceFile="$(var.CustomAction1.TargetDir)$(var.CustomAction1.TargetName).CA.dll" />
  <CustomAction Id="CheckDrive" BinaryKey="CustomActionBinary" DllEntry="CheckDataDrive" Return="check" />

  <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="INSTALLFOLDER" Name="Configurations" />
    </Directory>

  <ComponentGroup Id="ConfigFiles" Directory="INSTALLFOLDER">
    <Component Guid="{C5AF7E80-4D59-47CD-A537-2BC4BE90FDE3}" Id="ProductComponent" >
      <File Source ="Application.xml" />
    </Component>
  </ComponentGroup>
</Fragment>

自定义操作似乎有效,因为这是我在日志文件中看到的:

MSI (s) (14!B4) [18:49:46:510]:属性更改:修改 INSTALLFOLDER 属性。它的当前值为“D:\Configurations”。它的新值:'c:\Configurations'。

属性(S):INSTALLFOLDER = c:\Configurations\

但该文件仍安装在 D:\Configurations 中!我究竟做错了什么?

标签: wixcustom-action

解决方案


在尝试了 Robert 的回答后,我发现 TARGETDIR 在 CostFinalize 之前没有初始化(因此在 CostInitialize 之前),所以我得到一个异常 TARGETDIR 为空。在 CostFinalize 之后为时已晚。所以我尝试了一种不同的方法:我不想重用属性 TARGETDIR 和 INSTALLFOLDER 的一部分,所以我在 de CustomAction 中完全硬编码了路径。我按照罗伯特的解决方案更早地设置了值。所以这就是我最终的结果:

    private static bool TrySetTargetDir(string driveLetter, Session session)
    {
        var driveInfo = new DriveInfo(driveLetter);
        if (driveInfo.DriveType != DriveType.Fixed || !driveInfo.IsReady)
            return false;

        // Set the INSTALLFOLDER
        session["INSTALLFOLDER"] = $@"{driveLetter}:\Configurations";
        session.Log($"INSTALLFOLDER changed to {session["INSTALLFOLDER"]}");
        return true;
    }

并在序列的前面执行自定义操作:

<Custom Action='CheckDrive' Before='CostInitialize'>

并将 INSTALLFOLDER 设置为不可用的值:

<Directory Id="INSTALLFOLDER" Name="tbdInCustomAction" />

推荐阅读