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

时间:2011-11-18 15:08:05

标签: c# windows-7 wix custom-action

我们已经分发了旧版本的wix安装程序,其中一些文件安装为Permanent =“yes”组件。但现在我们要求用户在unistall上保留或删除这些文件。此文件位于Program Files文件夹中。我们得到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(是/否)和执行(立即/延迟)设置不同的值而不会获得成功。

此外,我们尝试通过具有RemoveFiles的组件或使用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)

是否可以实现删除先前版本中安装的永久文件的功能?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您应将自定义操作设置为延迟,并且无模仿

<CustomAction Id="DeleteFiles" ExeCommand='Company.CustomActions.ExeActions.exe' Directory="INSTALLDIR" Return="check" Impersonate="no" Execute="deferred" />

答案 1 :(得分:0)

最后,我们使用二进制WixCA中的WixShellExec,我们之前(时间,而不是执行)使用WixShellExec来启动特权应用程序,在安排每个WixShellExec cutom操作之前设置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]"/>

虽然Company.CustomActions.ExeActions.exe清单确实需要管理员权限(requestedExecutionLevel requireAdministrator),但未使用PrincipalPermissionAttribute修饰DeleteAll()方法。

卸载并要求删除显示两次UAC(一次用于卸载,另一次用于这些自定义操作),使用我的本地Windows配置执行这些操作。