WIX:在Windows 7的程序文件下使用自定义操作删除永久文件
本文关键字:文件 自定义 操作 删除 Windows WIX 程序 | 更新日期: 2023-09-27 18:15:02
我们已经发布了旧版本的wix安装程序,其中一些文件安装为Permanent="yes"组件。但是现在我们想要求用户在安装时保留或删除这些文件。此文件位于程序文件文件夹。我们在DELETE_ALL上获取用户响应。这是:
<InstallExecuteSequence>
<!-- more custom actions -->
<Custom Action="DeleteFiles" Before="InstallFinalize">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") AND (NOT (DELETE_ALL=0))</Custom>
</InstallExecuteSequence>
<CustomAction Id="DeleteFiles" ExeCommand='Company.CustomActions.ExeActions.exe' Directory="INSTALLDIR" Return="check" Impersonate="yes" Execute="immediate" />
Company.CustomActions.ExeActions.exe是一个简单的控制台应用程序,可以删除C:'Program Files (x86)'Company'Program1上的那些文件,并使用
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
在执行。msi时,我们得到这几行:
MSI (s) (20:88) [15:16:19:130]: MSI_LUA: Elevation required to install product, will prompt for credentials
MSI (s) (20:88) [15:16:21:798]: MSI_LUA: Credential Request return = 0x0
MSI (s) (20:88) [15:16:21:798]: MSI_LUA: Elevated credential consent provided. Install will run elevated
或者从Administrator cmd.exe启动:
MSI (c) (24:F8) [12:35:32:530]: MSI_LUA: Setting AdminUser property to 1 because this is the client or the user has already permitted elevation
我们尝试为我们的DeleteFiles自定义操作设置Impersonate (yes/no)和Execute (immediate/deferred)的不同值,但没有成功。
进一步,我们尝试通过一个带有RemoveFiles的组件或一个用c#编写的带有CustomActionAttribute标记的CustomAction来完成这个删除。也没有成功。
[CustomAction]
public static ActionResult DeleteAll(Session session) { /*...*/ }
或者从CustomAction调用到另一个方法:
[PrincipalPermission(SecurityAction.Demand, Role = @"BUILTIN'Administrators")]
private static void DeleteFiles() { /*...*/ }
我们得到一个期望:
Request for principal permission failed.
at System.Security.Permissions.PrincipalPermission.ThrowSecurityException()
at System.Security.Permissions.PrincipalPermission.Demand()
at System.Security.PermissionSet.DemandNonCAS()
at Company.CustomActions.DeleteFiles(Session session)
at Company.CustomActions.DeleteALL(Session session)
有可能实现一个功能,删除永久文件安装在以前的版本按需?任何想法?
您应该将自定义操作设置为延迟执行, 不进行模拟
<CustomAction Id="DeleteFiles" ExeCommand='Company.CustomActions.ExeActions.exe' Directory="INSTALLDIR" Return="check" Impersonate="no" Execute="deferred" />
最后,我们使用以前(及时,而不是在执行中)用于启动特权应用程序的二进制WixShellExec,在调度每个WixShellExec自定义操作之前设置WixShellExecTarget的值。
真正的问题是,这种方式不允许检索自定义操作的实际错误(不是WixShellExec调用上的错误,而是底层的错误)。到目前为止对我们来说是一个有效的场景。所以我们用这种方法解决了它。
的例子:
<InstallExecuteSequence>
<!-- more custom actions -->
<Custom Action="SetLaunchDeleteAll" Before="InstallFinalize">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") AND (NOT (DELETE_ALL=0))</Custom>
<Custom Action="DeleteFiles" Before="InstallFinalize">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL") AND (NOT (DELETE_ALL=0))</Custom>
</InstallExecuteSequence>
<InstallUISequence>
<!-- more custom actions -->
<Custom Action="SetLaunchProperty" Sequence="9990">CUSTOM_CONDITIONS</Custom>
</InstallUISequence>
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Impersonate="yes" Return="check" />
<!-- more custom actions -->
<CustomAction Id="DeleteFiles" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Impersonate="yes" Return="check" />
<CustomAction Id="SetLaunchProperty" Property="WixShellExecTarget" Value="[#Company.Program.exe]" />
<CustomAction Id="SetLaunchDeleteAll" Property="WixShellExecTarget" Value="[#Company.CustomActions.ExeActions.exe]" />
<UI>
<Publish Dialog="MyExitDialog" Control="Finish" Order="1" Event="DoAction" Value="LaunchApplication">CUSTOM_CONDITIONS</Publish>
</UI>
<Property Id="WixShellExecTarget" Value="[#Company.CustomActions.ExeActions.exe]"/>
DeleteAll()方法没有装饰PrincipalPermissionAttribute,尽管Company.CustomActions.ExeActions.exe清单确实需要管理员权限(requestedExecutionLevel requireadadministrator)。
卸载并要求删除显示两次UAC(一次用于卸载,另一次用于这些自定义操作),我的本地Windows配置用于这些操作。