使用 WixSharp 如何在卸载时执行的自定义操作期间获取正确的 InstallDir 路径
Using WixSharp how to get the proper InstallDir path during a Custom Action which is executed at uninstall
我使用 WixSharp 创建了一个带有 WiX 的 msi 安装程序。它包括几个自定义操作。
例如,在安装期间,我正在执行一些正在安装和启动服务的批处理文件。在卸载过程中,它应该停止并再次卸载该服务。
var dir = new InstallDir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));
var project = new Project("MyProduct", dir) {
GUID = new Guid("7f22db65-2b23-4df2-b2b2-495f2d369c3d"),
Version = new Version(1, 0, 0, 0),
UI = WUI.WixUI_InstallDir,
Platform = Platform.x64
};
project.Actions = new WixSharp.Action[] {
new ElevatedManagedAction(CustomActions.InstallService,Return.check, When.Before, Step.InstallFinalize, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StartService,Return.check, When.After, Step.PreviousAction, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StopService,Return.check, When.Before, Step.RemoveFiles, Condition.Installed),
new ElevatedManagedAction(CustomActions.UninstallService,Return.check, When.After, Step.PreviousAction, Condition.Installed)
};
关键的部分来了。我需要在安装和卸载期间执行批处理文件,它位于 INSTALLDIR:
[CustomAction]
public static ActionResult StartService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this works on install even when using a custom path
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
[CustomAction]
public static ActionResult UninstallService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this does not give back the right path on uninstall in case the default path was changed during installation
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
使用默认路径安装时一切顺利。但是,如果我在安装过程中将默认安装路径更改为某个自定义路径,安装步骤会正确找到 .bat 并执行它,但在卸载过程中,它会在默认文件夹中搜索 .bat 文件。尽管卸载程序正确删除了正确位置上的文件。所以自定义安装路径必须保存在某个地方。如何正确访问它?
在 Oleg (https://github.com/oleg-shilo/wixsharp/issues/486) 的帮助下,我终于可以自己解决问题了。
由于 session.Property("INSTALLDIR")
实际上应该有效,所以我当时没有犯错,我可以找出根本原因,即通过使用 [=] 将 IsInstallDir
属性 设置为 true 13=] class 而不是 Dir
class。当卸载回到硬编码的默认路径时,它覆盖了 INSTALLDIR
属性。
这解释了为什么只要使用默认路径安装程序就可以正常工作,以及为什么它适用于所有安装自定义步骤,即使在使用自定义路径时也适用,但不再适用于卸载。之所以首先将 IsInstallDir
属性 设置为 true 是因为在使用通配符将所有文件添加到设置时出现了一些奇怪的行为。只要源目录中有多个文件和文件夹,它就会按预期工作,使所有路径正确等等。但是一旦源文件夹只包含一个单独的文件夹,然后在其中包含其余的设置文件,它会将内部文件夹设置为新的根文件夹(有点奇怪,但一旦你知道这种行为,事情就会开始有意义)等等搞砸了许多必要的路径。使用 InstallDir
而不是 Dir
解决了这个问题。
我可能会做一些工作来重组整个事情(如果这在我的用例中甚至是可能的),但现在只需在与单个内部文件夹相同的级别添加一个自述文件即可解决该问题,这样我就可以返回使用Dir
第一行:
var dir = new Dir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));
发生这种情况是因为您将操作 "after" 称为卸载。应该是 "When.Before"
new ManagedAction(CustomActions.UninstallService,Return.check, When.Before, Step.InstallFinalize, Condition.Installed)
我使用 WixSharp 创建了一个带有 WiX 的 msi 安装程序。它包括几个自定义操作。 例如,在安装期间,我正在执行一些正在安装和启动服务的批处理文件。在卸载过程中,它应该停止并再次卸载该服务。
var dir = new InstallDir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));
var project = new Project("MyProduct", dir) {
GUID = new Guid("7f22db65-2b23-4df2-b2b2-495f2d369c3d"),
Version = new Version(1, 0, 0, 0),
UI = WUI.WixUI_InstallDir,
Platform = Platform.x64
};
project.Actions = new WixSharp.Action[] {
new ElevatedManagedAction(CustomActions.InstallService,Return.check, When.Before, Step.InstallFinalize, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StartService,Return.check, When.After, Step.PreviousAction, Condition.NOT_Installed),
new ElevatedManagedAction(CustomActions.StopService,Return.check, When.Before, Step.RemoveFiles, Condition.Installed),
new ElevatedManagedAction(CustomActions.UninstallService,Return.check, When.After, Step.PreviousAction, Condition.Installed)
};
关键的部分来了。我需要在安装和卸载期间执行批处理文件,它位于 INSTALLDIR:
[CustomAction]
public static ActionResult StartService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this works on install even when using a custom path
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
[CustomAction]
public static ActionResult UninstallService(Session session) {
string installDir = session.Property("INSTALLDIR"); //<--this does not give back the right path on uninstall in case the default path was changed during installation
string workingDir = Path.Combine(installDir, @"\SomePathToTheBatchFile");
RunCmdMethode(workingDir, "something.bat -some arguments");
return ActionResult.Success;
}
使用默认路径安装时一切顺利。但是,如果我在安装过程中将默认安装路径更改为某个自定义路径,安装步骤会正确找到 .bat 并执行它,但在卸载过程中,它会在默认文件夹中搜索 .bat 文件。尽管卸载程序正确删除了正确位置上的文件。所以自定义安装路径必须保存在某个地方。如何正确访问它?
在 Oleg (https://github.com/oleg-shilo/wixsharp/issues/486) 的帮助下,我终于可以自己解决问题了。
由于 session.Property("INSTALLDIR")
实际上应该有效,所以我当时没有犯错,我可以找出根本原因,即通过使用 [=] 将 IsInstallDir
属性 设置为 true 13=] class 而不是 Dir
class。当卸载回到硬编码的默认路径时,它覆盖了 INSTALLDIR
属性。
这解释了为什么只要使用默认路径安装程序就可以正常工作,以及为什么它适用于所有安装自定义步骤,即使在使用自定义路径时也适用,但不再适用于卸载。之所以首先将 IsInstallDir
属性 设置为 true 是因为在使用通配符将所有文件添加到设置时出现了一些奇怪的行为。只要源目录中有多个文件和文件夹,它就会按预期工作,使所有路径正确等等。但是一旦源文件夹只包含一个单独的文件夹,然后在其中包含其余的设置文件,它会将内部文件夹设置为新的根文件夹(有点奇怪,但一旦你知道这种行为,事情就会开始有意义)等等搞砸了许多必要的路径。使用 InstallDir
而不是 Dir
解决了这个问题。
我可能会做一些工作来重组整个事情(如果这在我的用例中甚至是可能的),但现在只需在与单个内部文件夹相同的级别添加一个自述文件即可解决该问题,这样我就可以返回使用Dir
第一行:
var dir = new Dir(@"%ProgramFiles%\MyCompany\MyProduct",
new Files(@"..\..\..\AllMyFiles\*.*"));
发生这种情况是因为您将操作 "after" 称为卸载。应该是 "When.Before"
new ManagedAction(CustomActions.UninstallService,Return.check, When.Before, Step.InstallFinalize, Condition.Installed)