【发布时间】:2020-01-30 15:44:07
【问题描述】:
我目前有一个创建 MSI 的旧版 Visual Studio 安装项目项目。有了这个,我可以在命令行上指定“TARGETDIR="somepath"”并将其安装到“somepath”。现在使用 WIX,如果我没有在我的 wxs 中指定 ProgramFilesFolder,“TARGETDIR”仍然有效,但是在我的安装程序 UI 中,默认路径是“C:\Manufacturer\Product”,而我仍然希望它默认为 ProgramFilesFolder。必须支持“TARGETDIR”才能支持从应用程序本身升级到旧版 MSI。
我找到了一些将 UI 默认目录更改为 ProgramFilesFolder 的方法,但是 TARGETDIR 不会更改为此目录(或用户指定的目录),因此它仍会安装到 C:\Manufacturer\Product。
这里有人有什么想法吗?我猜某种自定义操作会做到这一点,但我觉得我已经尝试了大部分建议,例如:
- https://stackoverflow.com/a/13058798/9993088 但这会覆盖命令行中或命令行中的任何选定目录
- 我还尝试创建一个 WiX 属性“TARGETDIR”以在命令行上公开它,但由于这已经是一个内部属性,因此没有任何区别。
- How to set default value of WiX Msi install path in the ui to Program Files? 如前所述,这将阻止我在命令行上使用“TARGETDIR”
- https://wixtoolset.org//documentation/manual/v3/wixui/dialog_reference/wixui_advanced.html 然后使用自定义操作将“TARGETDIR”设置为“APPLICATIONFOLDER”。有了这个,我可以将默认位置设置为 ProgramFilesFolder,但是我还没有找到一种方法来在正确的时间设置“TARGETDIR”以使用命令行值或用户选择的值。我几乎需要一种方法来执行“如果 'APPLICATIONFOLDER' 不是默认值;使用它的值或者如果 'TARGETDIR' 不是默认值;使用它的值否则使用默认值”。这似乎也不允许变量扩展,所以我不能使用“[ProgramFilesFolder]”,我必须明确写出“C:\Program Files...”,这并不理想。
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="blah">
如前所述,我必须能够使用“TARGETDIR”而不是“INSTALLDIR”(尽管可以)。
如果我真的必须使用“INSTALLDIR”,那么我可以让它工作,但由于使用方式的性质,它使得维护旧版 MSI 和 WiX 变得很棘手。 p>
编辑
解决方案:
<Custom Action="SetINSTALLDIR" Before="AppSearch">Not Installed</Custom> 在 InstallExecuteSequence 和 InstallUISequence 中。
这指向:
<CustomAction Id="SetINSTALLDIR" BinaryKey="CustomActionsBinary" DllEntry="SetInstallDir" />
SetInstallDir 如下:
[CustomAction]
public static ActionResult SetInstallDir(Session session)
{
TraceLogger.yRTraceInfo(nameof(SetInstallDir));
string installDir = session["APPLICATIONFOLDER"];
string targetDir = string.Empty;
try
{
targetDir = session["TARGETDIR"];
}
catch (Exception e)
{
Console.log(e.Message);
}
if (string.IsNullOrEmpty(installDir) && !string.IsNullOrEmpty(targetDir))
{
session["APPLICATIONFOLDER"] = targetDir;
console.log($"Setting APPLICATIONFOLDER to {targetDir}");
}
return ActionResult.Success;
}
【问题讨论】: