如何使用 Wix 将文件安装到 D: 驱动器(并检查 D: 不是光驱)
How to install files with Wix to D: drive (and check D: is not 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]: PROPERTY CHANGE: Modifying INSTALLFOLDER property. Its current value is 'D:\Configurations'. Its new value: 'c:\Configurations'.
Property(S): INSTALLFOLDER = c:\Configurations\
但是文件仍然安装在D:\Configurations中!我做错了什么?
After="CostFinalize" 似乎来不及安排此类操作。
您可以尝试将其替换为:
<Custom Action='CheckDrive' Before='CostInitialize'>
在尝试了 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" />
我玩 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]: PROPERTY CHANGE: Modifying INSTALLFOLDER property. Its current value is 'D:\Configurations'. Its new value: 'c:\Configurations'.
Property(S): INSTALLFOLDER = c:\Configurations\
但是文件仍然安装在D:\Configurations中!我做错了什么?
After="CostFinalize" 似乎来不及安排此类操作。 您可以尝试将其替换为:
<Custom Action='CheckDrive' Before='CostInitialize'>
在尝试了 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" />