WiX:如何重新启动 Windows Explorer 以安装/卸载 shell 扩展

WiX: How to restart Windows Explorer to install / uninstall a shell extension

我正在尝试编写一个包含托管图标 shell 扩展(使用 SharpShell)的 WiX 安装程序。我终于想出了如何通过 Wix 注册它(当通过 WiX 调用时我无法让 SharpShell 注册管理器工作)。

安装过程中出现如下对话框:

如果我 select“忽略”,图标 shell 扩展已成功安装并且 Window Explorer 会立即获取更改。我不确定它检测到哪些文件为“正在使用”。

卸载过程中出现如下对话框:

如果您 select“自动关闭并尝试重新启动”选项,它会关闭 Windows Explorer,但不会在安装结束时重新启动。我必须通过任务管理器手动重启它。

WiX 片段定义

定义shell扩展安装的WiX片段如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>
    <!-- This fragment was originally generated using heat with the following command line:
            "$(WIX)bin\heat.exe" dir "$(SolutionDir)Icon ShellExtension\bin$(ConfigurationName)" -dr IconShellExtensionDIR -cg IconShellExtension -var var.IconShellExtension.TargetDir -fips -g1 -gg -sfrag -srd -suid -template fragment -t "$(ProjectDir)AssemblyFileFilter.xslt" -out "$(ProjectDir)Fragments\IconShellExtension.wxs"
         
         It was then subsequently manually modified, as file associations are defined in a different component the default icon entry had to be removed.
    -->
    <Fragment>
    <DirectoryRef Id="IconShellExtensionDIR">
      <Component Id="IconShellExtension.dll" Guid="D609F6F2-52FB-4153-8D6A-3E2B7F8C4647">
        <Class Id="{A1C3600C-F3E5-300E-8167-541C62083DAA}" Context="InprocServer32" Description="IconShellExtension.UaProjectIconHandler" ThreadingModel="both" ForeignServer="mscoree.dll">
          <ProgId Id="IconShellExtension.UaProjectIconHandler" Description="UA Project File Icon Handler" />
        </Class>
        <util:RestartResource ProcessName="explorer.exe"/>
        <File Id="IconShellExtension.dll" KeyPath="yes" Source="$(var.IconShellExtension.TargetDir)\IconShellExtension.dll" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32.0.0.0" Name="Class" Value="IconShellExtension.UaProjectIconHandler" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32.0.0.0" Name="Assembly" Value="IconShellExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e9ad08f31c5e4fb" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32.0.0.0" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32.0.0.0" Name="CodeBase" Value="file:///[#IconShellExtension.dll]" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32" Name="Class" Value="IconShellExtension.UaProjectIconHandler" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32" Name="Assembly" Value="IconShellExtension, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9e9ad08f31c5e4fb" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="CLSID\{A1C3600C-F3E5-300E-8167-541C62083DAA}\InprocServer32" Name="CodeBase" Value="file:///[#IconShellExtension.dll]" Type="string" Action="write" />
        <RegistryValue Root="HKCR" Key="UserAppProject\ShellEx\IconHandler" Value="{a1c3600c-f3e5-300e-8167-541c62083daa}" Type="string" Action="write" />
        <RegistryValue Root="HKLM" Key="Software\Microsoft\Windows\CurrentVersion\Explorer" Name="GlobalAssocChangedCounter" Value="1" Type="integer" Action="write" />
      </Component>
      <Component Id="SharpShell.dll" Guid="174E147D-4744-492F-BC5C-F00DAA4925AA">
        <File Id="SharpShell.dll" KeyPath="yes" Source="$(var.IconShellExtension.TargetDir)\SharpShell.dll" />
      </Component>
    </DirectoryRef>
  </Fragment>
  <Fragment>
    <ComponentGroup Id="IconShellExtension">
      <ComponentRef Id="IconShellExtension.dll" />
      <ComponentRef Id="SharpShell.dll" />
    </ComponentGroup>
  </Fragment>
</Wix>

目标

我希望安装程序能够在不提示用户有关正在使用的文件的情况下安装或卸载,并且它会在此过程中自动关闭并重新启动 Windows Explorer。我的理解是重启管理器允许这样做,WixUtils RestartResource 标签应该为我做这件事。

如有任何帮助,我们将不胜感激!

更新

我尝试了各种不同的属性组合,并尝试 remove/disable FilesInUse 对话框。

我尝试按照 中的建议设置以下属性组合:

    <Property Id="MSIRMSHUTDOWN" Value="2"/>
    <Property Id="MSIDISABLERMRESTART" Value="0"/>
    <Property Id="MSIRESTARTMANAGERCONTROL" Value="0"/>

这会在卸载过程中重新启动 explorer.exe,一旦卸载序列完成(尽管资源管理器关闭的时间很长)。但是,我发现当我尝试重新安装时,它再次显示 FilesInUse 对话框。

我找到了一个适合我的解决方案,我将 post 作为接受的答案。

似乎有效且未显示任何不需要的对话框的最佳解决方案是删除 MSIRMSHUTDOWNMSIDISABLERMRESTART 属性并设置以下 属性:

    <!-- The following setting seems to suppress any restart dialogs -->
    <Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable"/>

这完全添加或删除了我的 shell 扩展。唯一的问题是 shell 扩展在我重新启动之前一直保持活动状态(因为这只是一个图标 Shell 扩展,所以我可以接受)。