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)

有可能实现一个功能,删除永久文件安装在以前的版本按需?任何想法?

WIX:在Windows 7的程序文件下使用自定义操作删除永久文件

您应该将自定义操作设置为延迟执行不进行模拟

<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配置用于这些操作。