使用 uwp 应用程序打开不受支持的文件类型扩展名

Open unsupported file type extensions with uwp app

This 是一个 uwp 文本编辑器应用程序的 PR,我在其中实现桌面扩展以让用户选择打开未在清单中声明关联的文件。用户可以选择打开带有扩展名的文件,然后使用 uwp 应用程序启动文件。但是我遇到了以下问题:

  1. StorageFile.GetFileFromPathAsync() 不适用于隐藏文件。尝试使用 this 文章处理文件激活会出现以下错误:

    System.Exception HResult=0xD0000225 Message=The text associated with this error code could not be found.

    The text associated with this error code could not be found.

    Source=Windows.ApplicationModel StackTrace: at Windows.ApplicationModel.AppInstance.GetActivatedEventArgs()

  2. 使用 Launcher.LaunchFileAsync() 启动也不适用于不受支持的扩展。

关于这些问题有什么帮助吗??

在 Windows 10 2004(内部版本 19041)中,微软在程序包清单中引入了 uap10:FileType 属性,并提供 * 作为应用程序在打开所有类型的菜单时可用的值文件甚至没有任何扩展名的文件。要使用它,只需将以下代码添加到您的清单中:

xmlns:uap10="http://schemas.microsoft.com/appx/manifest/uap/windows10/10"
...
<uap:Extension Category="windows.fileTypeAssociation">
  <uap:FileTypeAssociation Name="anyfile">
    <uap:Logo>Assets\mylogo.png</uap:Logo>
    <uap:SupportedFileTypes>
      <uap:FileType>.txt</uap:FileType>
      <uap10:FileType>*</uap10:FileType>
    </uap:SupportedFileTypes>
  </uap:FileTypeAssociation>
</uap:Extension>

这仅适用于 Windows 10 build 19041 及更高版本。如果应用的最低版本低于 19041 才能通过清单验证,则需要额外的 uap:FileType,否则可以省略。

更新 1

对于早于 build 19041 的 Windows10 版本,可以提供使用 IApplicationActivationManager::ActivateForFile 将文件激活重定向到 UWP 应用程序的桌面组件。 C++/WinRT 中的示例代码如下所示:

init_apartment();

LPWSTR* szArglist = NULL;
INT nArgs;
szArglist = CommandLineToArgvW(GetCommandLine(), &nArgs);
if (szArglist && nArgs > 1)
{
    INT ct = nArgs - 1;
    HRESULT hr = E_OUTOFMEMORY;
    com_ptr<IShellItemArray> ppsia = NULL;
    PIDLIST_ABSOLUTE* rgpidl = new(std::nothrow) PIDLIST_ABSOLUTE[ct];
    if (rgpidl)
    {
        hr = S_OK;
        INT cpidl;
        for (cpidl = 0; SUCCEEDED(hr) && cpidl < ct; cpidl++)
        {
            hr = SHParseDisplayName(szArglist[cpidl + 1], NULL, &rgpidl[cpidl], 0, NULL);
        }

        if (cpidl > 0 && SUCCEEDED(SHCreateShellItemArrayFromIDLists(cpidl, rgpidl, ppsia.put())))
        {
            com_ptr<IApplicationActivationManager> appActivationMgr = NULL;
            if (SUCCEEDED(CoCreateInstance(CLSID_ApplicationActivationManager, NULL, CLSCTX_LOCAL_SERVER, __uuidof(appActivationMgr), appActivationMgr.put_void())))
            {
                DWORD pid = 0;
                appActivationMgr->ActivateForFile(AUMID, ppsia.get(), NULL, &pid);
            }
            appActivationMgr.~com_ptr();
        }

        for (INT i = 0; i < cpidl; i++)
        {
            CoTaskMemFree(rgpidl[i]);
        }
    }

    ppsia.~com_ptr();
    delete[] rgpidl;
}

LocalFree(szArglist);
uninit_apartment();

使用上述方法重定向激活的另一个好处是用户甚至可以直接使用 UWP 应用程序打开受限制的文件类型(即 .cmd、.bat 等)。