【问题标题】:WIX: delete permanent files with a custom action under program files on Windows 7?WIX:在 Windows 7 的程序文件下使用自定义操作删除永久文件?
【发布时间】:2011-11-18 15:08:05
【问题描述】:

我们分发了旧版本的 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

或者如果我们从管理员 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# 编写的 CustomAction 来执行此删除操作,该操作与我们使用的其他工具一样标有 CustomActionAttribute。也没有成功。

    [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)

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

【问题讨论】:

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


    【解决方案1】:

    您应该将自定义操作设置为 deferredno impersonation

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

    【讨论】:

    • 我们测试了它,正如我在问题中所说的那样,没有成功。还是谢谢你。
    【解决方案2】:

    最后,我们使用之前使用过的二进制 WixCA 中的 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]"/>
    

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

    卸载和请求删除会显示两次 UAC(一次用于卸载,一次用于这些自定义操作)以及这些操作的本地 Windows 配置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多