我有一个 WPF 应用程序。为了赋予其使用 UWP API 的身份,我添加了 sparse 包支持。这可以很好地使用我的 WPF 应用程序安装/卸载/更新(我们不使用 MSIX),并且我的应用程序正在使用身份运行。它显示在任务管理器中,并在我的进程中列出了
Package Name
。
现在我正在尝试按照 Microsoft 文档添加上下文菜单支持。
我创建了一个 shell 扩展,它将在打开任何文件和文件夹的上下文菜单时显示,这几乎是 其示例的副本,具有不同的
GetIcon()
、GetTitle()
和 Invoke()
实现 IExplorerCommand
.
我在
AppxManifest.xml
中指定了这一点(匿名值):
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type="*">
<desktop5:Verb Id="MyFileCommand" Clsid="file-guid"/>
</desktop5:ItemType>
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="MyFolderCommand" Clsid="folder-guid"/>
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="SSVerbHandler">
<com:Class Id="file-guid" Path="my-shell-extension.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
<com:SurrogateServer DisplayName="SSVerbHandler">
<com:Class Id="folder-guid" Path="my-shell-extension.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
这有效,我的上下文菜单条目已列出并按预期执行操作。但问题是:每次第一次打开上下文菜单时,它都会杀死我的 WPF 应用程序已在运行的实例。第一次,我的意思是重新启动
explorer.exe
并右键单击文件或文件夹。
我的直觉是这与 UWP 方面的事情有关。这是因为最初当右键单击打开上下文菜单时,它会always杀死我的应用程序。但经过一些尝试和错误,我通过在我的 AppxManifest.xml
中配置
多实例支持解决了这个问题:
<Package
...
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:iot2="http://schemas.microsoft.com/appx/manifest/iot/windows10/2"
IgnorableNamespaces="uap mp desktop4 iot2">
...
<Applications>
<Application Id="App"
...
desktop4:SupportsMultipleInstances="true"
iot2:SupportsMultipleInstances="true">
...
</Application>
</Applications>
...
</Package>
我希望有人能提出任何故障排除的想法,因为我现在正在苦苦挣扎。
我在
MessageBox
、DllMain
和 DllCanUnloadNow
的 shell 扩展中添加了一些值得信赖的 DllGetClassObject
函数。但对于第一次加载尝试,没有显示消息框,没有列出上下文菜单项,并且我的应用程序仍然被终止。
我在事件查看器中浏览了一下,希望看到最近列出的任何错误或警告,以及
Applications and Service Logs\Microsoft\Windows\Appx*
和 Applications and Service Logs\Microsoft\Windows\AppModel-Runtime
。没有任何事情让我惊讶。
根据这个SO anwser,如果shell扩展本身有错误,它可能不会显示。这确实合适,但我对此表示怀疑,因为它始终适用于后续尝试以及之前解决的 UWP 杀毒问题。
在我的应用程序停止的情况下,使用这些 powershell 命令我得到:
$process = Start-Process .\MyApp.exe -PassThru -Wait
$process.ExitCode
1
我的应用程序中确实有崩溃日志记录,但没有记录任何内容。这是 WPF 应用程序中唯一调用
Environment.Exit(1)
的地方。
我确实在 WPF 应用程序上尝试过 GFlags 中的“静默监控检测”,但似乎无法触发它。仅当我手动关闭应用程序时。 (测试时未选中Ignore Self Exits
)。我不确定这是否是因为退出代码是 1。当运行
进程监视器时发生错误时,我可以在最后一个ThreadExit
之前看到很多
ProcessExit
,退出代码为1。这意味着它正在干净地退出,而我的应用程序本身返回1?还值得一提的是,在过去十年左右的时间里,我一直生活在托管/.NET 领域,我对 C++(或一般的非托管语言)或 UWP 没有太多经验,这是我第一次尝试编写一个 shell 扩展。