我有一个自定义操作“xxxx”,它通过命令提示符执行 rmdir 来删除目录。 ExeCommand="[SystemFolder]cmd.exe/C rmdir/Q/S "[DIR]""和 Execute="deferred"
在InstallExecuteSequence中添加如下
Custom Action="xxxx" After="InstallInitialize"
(NOT UPGRADINGPRODUCTCODE) AND REMOVE
Custom
如果该目录是由其他应用程序(例如命令行)打开的,则会抛出错误。
我读过很多类似的问题。但无法弄清楚
1)提示用户关闭应用程序 - 我读到添加
UI
DialogRef Id="FilesInUse"
DialogRef Id="MsiRMFilesInUse"
/UI
并使用自定义操作Before="InstallValidate"
显示关闭应用程序的提示。
2) 如何在服务停止后运行自定义操作并提示用户关闭应用程序? 它应该以延迟模式运行。
3) 如果我想以 Execute = deferred
方式运行,则无法使用 InstallValidate。因此我无法使用 FilesInUse。
4)还有其他好的方法吗?我不想引用 dll,因为我希望安装程序在卸载时删除整个目录。
最佳答案
最大的问题是为什么您需要删除该文件夹,因为通常不需要这样做。这意味着它一定被抛在了后面,但这只是一个猜测,所以我想说这就是要处理的问题 - 为什么它被抛在后面。您的问题是为什么您的解决方案不起作用。根本问题是,如果 Windows 决定需要一个 FilesInUse 对话框,InstallValidate 将提示一个 FilesInUse 对话框,而 Windows 不需要一个对话框(您需要这样做是因为您的自定义操作),这就是 FilesInUse UI 引用没有帮助的原因。
如果您想删除文件或文件夹,WiX RemoveFile 元素是常用方法,它发生在卸载中其他所有内容都已被删除的正确位置:
Wix RemoveFile and RemoveFolder for removing leftovers
如果您想告诉应用程序关闭,可以使用 WiX Util CloseApplication。
如果您确实想使用代码和 FilesInUse 提示解决文件夹问题(而不是解决该文件夹的根本问题),那么像这样的 C++ 自定义操作将在 InstallValidate 工作之前立即显示 FilesInUse 对话框,您需要一些 msi.h、msiquery.h 的包含:
UINT __stdcall ShowFilesInUse (MSIHANDLE hInstall)
{
PMSIHANDLE hRec = MsiCreateRecord(4);
MsiRecordSetString(hRec, 1, TEXT(" "));
MsiRecordSetString(hRec, 2, TEXT("Please use Task Manager to Terminate these programs:"));
MsiRecordSetString(hRec, 3, TEXT("something else"));
UINT res = 0;
do
{
res = MsiProcessMessage(hInstall, INSTALLMESSAGE_FILESINUSE, hRec);
}
while (res == IDRETRY);
if (IDOK==res) // 1 is the Continue button in VS
return 0;
if (IDCANCEL ==res) // The Exit button in VS
return ERROR_INSTALL_USEREXIT;
return 0;
}
关于c++ - 提示用户在卸载时关闭应用程序 - WIX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34277702/