3D アプリ起動ツールの実装 (Win32 アプリ)

Note

この機能は、最新の Windows Insider フライト (RS5)、ビルド 17704 以降を実行している PC でのみ使用できます。

Windows Mixed Reality ホームは出発点であり、ユーザーはここに移動してからアプリケーションを起動します。 既定では、イマーシブ Win32 VR アプリとゲームはヘッドセットの外部から起動する必要があり、Windows Mixed Reality スタート メニューの [すべてのアプリ] の一覧に表示されません。 この記事に記載されている手順に従って 3D アプリ起動ツールを実装すると、Windows Mixed Reality のスタート メニューとホーム環境内からイマーシブ Win32 VR エクスペリエンスを起動できます。

これは、Steam の外部で配布されるイマーシブ Win32 VR エクスペリエンスの場合にのみ当てはまります。 Steam を介して配布される VR エクスペリエンスについては、最新の Windows Insider RS5 フライトと共に Windows Mixed Reality for SteamVR Beta を更新しました。既定の起動ツールを使うと Windows Mixed Reality のスタートメニューの [すべてのアプリ] の一覧に自動的に SteamVR のタイトルが表示されるようになりました。 言い換えると、この記事で説明されているメソッドは SteamVR のタイトルには不要であり、Windows Mixed Reality for SteamVR Beta の機能によってオーバーライドされます。

3D アプリ起動ツールの作成プロセス

3D アプリ起動ツールを作成するには、次の 3 つの手順を実行します。

  1. 設計と構想
  2. モデリングとエクスポート
  3. アプリケーションへの統合 (この記事)

アプリケーションの起動ツールとして使用する 3D アセットは、互換性を確保するために Windows Mixed Reality オーサリングのガイドラインを使用して作成する必要があります。 このオーサリング仕様に沿っていないアセットは、Windows Mixed Reality ホームにレンダリングされません。

3D 起動ツールの構成

3D アプリ起動ツールを作成すると、Win32 アプリケーションが Windows Mixed Reality のスタートメ ニューの [すべてのアプリ] の一覧に表示されます。 これを行うには、次の手順に従って、3D アプリ起動ツールを参照するビジュアル要素マニフェスト XML ファイルを作成します。

  1. 3D アプリ起動ツール アセットの GLB ファイルを作成します (「モデリングとエクスポート」を参照してください)。
  2. アプリケーションのビジュアル要素マニフェストを作成します。
    1. 下のサンプルを使って始めることができます。 詳細については、ビジュアル要素マニフェストに関するドキュメントを参照してください。
    2. アプリの PNG/JPG/GIF を使用して Square150x150LogoSquare70x70Logo を更新します。
      • こちらは、Windows Mixed Reality の [すべてのアプリ] の一覧とデスクトップのスタート メニューでアプリの 2D ロゴに使用されます。
      • ファイル パスは、ビジュアル要素マニフェストが格納されているフォルダーを基準としています。
      • ほかに、標準のメカニズムを使用して、アプリ用にデスクトップのスタート メニュー アイコンを指定する必要があります。 これは、実行可能ファイルに直接、または作成するショートカットに含めることができます。 たとえば、IShellLink::SetIconLocation を使用します。
      • 省略可能: さまざまな解像度スケールとハイ コントラスト テーマ用に複数のアセット サイズを提供する場合は、resources.pri ファイルを使用できます。
    3. MixedRealityModel パスを更新して、3D アプリ起動ツールの GLB を指すようにします。
    4. 実行可能ファイルと同じ名前でファイルを保存し、拡張子を ".VisualElementsManifest.xml" にして、同じディレクトリに保存します。 たとえば、実行可能ファイル "contoso.exe" の場合、付随する XML ファイルの名前は "contoso.visualelementsmanifest.xml" になります。
  3. デスクトップ Windows のスタート メニューにアプリケーションへのショートカットを追加します。 C++ での実装例については、下のサンプルをご覧ください。
    • %ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs (PC) または %APPDATA%\Microsoft\Windows\Start Menu\Programs (ユーザー) に作成します。
    • 更新によって、ビジュアル要素マニフェストまたはその参照先のアセットが変更された場合、更新プログラムまたはインストーラーによってショートカットが更新されて、マニフェストの再解析、キャッシュされたアセットの更新が行われます。
  4. 省略可能: デスクトップ ショートカットがアプリケーションの EXE を直接指していない場合 (たとえば、"myapp://" のようなカスタム プロトコル ハンドラーが呼び出される場合)、スタート メニューでアプリの VisualElementsManifest.xml ファイルが自動的に検索されません。 これを解決するには、System.AppUserModel.VisualElementsManifestHintPath () を使用して、ビジュアル要素マニフェストのファイル パスを指定する必要があります。 これは、System.AppUserModel.ID と同じ手法を使用して、ショートカットで設定できます。 System.AppUserModel.ID の使用は必須ではありませんが、アプリケーションの明示的なアプリケーション ユーザー モデル ID が使用されている場合は、それを一致させるためにショートカットで使用できます。 C++ のサンプルについては、下の「アプリ起動ツールのショートカットの作成サンプル」セクションを参照してください。

ビジュアル要素マニフェストのサンプル

<Application xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <VisualElements
    ShowNameOnSquare150x150Logo="on"
    Square150x150Logo="YOUR_APP_LOGO_150X150.png"
    Square70x70Logo=" YOUR_APP_LOGO_70X70.png"
    ForegroundText="light"
    BackgroundColor="#000000">
    <MixedRealityModel Path="YOUR_3D_APP_LAUNCHER_ASSET.glb">
        <SpatialBoundingBox Center="0,0,0" Extents="Auto" />
    </MixedRealityModel>
  </VisualElements>
</Application>

アプリ起動ツールのショートカットの作成サンプル

下のサンプル コードは、C++ でショートカットを作成する方法を示しています。ビジュアル要素マニフェスト XML ファイルへのパスのオーバーライドも含まれています。 なお、このオーバーライドは、ショートカットがマニフェストに関連付けられている EXE を直接指していない場合にのみ必要です (たとえば、ショートカットで "myapp://" のようなカスタム プロトコル ハンドラーが使用されている場合)。

.LNK ショートカットの作成のサンプル (C++)

#include <windows.h>
#include <propkey.h>
#include <shlobj_core.h>
#include <shlwapi.h>
#include <propvarutil.h>
#include <wrl.h>

#include <memory>

using namespace Microsoft::WRL;

#define RETURN_IF_FAILED(x) do { HRESULT hr = x; if (FAILED(hr)) { return hr; } } while(0)
#define RETURN_IF_WIN32_BOOL_FALSE(x) do { DWORD res = x; if (res == 0) { return HRESULT_FROM_WIN32(GetLastError()); } } while(0)

int wmain()
{
    RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED));

    ComPtr<IShellLink> shellLink;
    RETURN_IF_FAILED(CoCreateInstance(__uuidof(ShellLink), nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&shellLink)));
    RETURN_IF_FAILED(shellLink->SetPath(L"MyLauncher://launch/app-identifier"));

    // It is also possible to use an icon file in another location. For example, "C:\Program Files (x86)\MyLauncher\assets\app-identifier.ico".
    RETURN_IF_FAILED(shellLink->SetIconLocation(L"C:\\Program Files (x86)\\MyLauncher\\apps\\app-identifier\\game.exe", 0 /*iIcon*/));

    ComPtr<IPropertyStore> propStore;
    RETURN_IF_FAILED(shellLink.As(&propStore));

    {
        // Optional: If the application has an explict Application User Model ID, then you should usually specify it in the shortcut.
        PROPVARIANT propVar;
        RETURN_IF_FAILED(InitPropVariantFromString(L"ExplicitAppUserModelID", &propVar));
        RETURN_IF_FAILED(propStore->SetValue(PKEY_AppUserModel_ID, propVar));
        PropVariantClear(&propVar);
    }

    {
        // A hint path to the manifest is only necessary if the target path of the shortcut is not a file path to the executable.
        // By convention the manifest is named <executable name>.VisualElementsManifest.xml and is in the same folder as the executable
        // (and resources.pri if applicable). Assets referenced by the manifest are relative to the folder containing the manifest.

        //
        // PropKey.h
        //
        //  Name:     System.AppUserModel.VisualElementsManifestHintPath -- PKEY_AppUserModel_VisualElementsManifestHintPath
        //  Type:     String -- VT_LPWSTR  (For variants: VT_BSTR)
        //  FormatID: {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}, 31
        //  
        //  Suggests where to look for the VisualElementsManifest for a Win32 app
        //
        // DEFINE_PROPERTYKEY(PKEY_AppUserModel_VisualElementsManifestHintPath, 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, 31);
        // #define INIT_PKEY_AppUserModel_VisualElementsManifestHintPath { { 0x9F4C2855, 0x9F79, 0x4B39, 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3 }, 31 }

        PROPVARIANT propVar;
        RETURN_IF_FAILED(InitPropVariantFromString(L"C:\\Program Files (x86)\\MyLauncher\\apps\\app-identifier\\game.visualelementsmanifest.xml", &propVar));
        RETURN_IF_FAILED(propStore->SetValue(PKEY_AppUserModel_VisualElementsManifestHintPath, propVar));
        PropVariantClear(&propVar);
    }

    constexpr PCWSTR shortcutPath = L"%APPDATA%\\Microsoft\\Windows\\Start Menu\\Programs\\game.lnk";
    const DWORD requiredBufferLength = ExpandEnvironmentStrings(shortcutPath, nullptr, 0);
    RETURN_IF_WIN32_BOOL_FALSE(requiredBufferLength);

    const auto expandedShortcutPath = std::make_unique<wchar_t[]>(requiredBufferLength);
    RETURN_IF_WIN32_BOOL_FALSE(ExpandEnvironmentStrings(shortcutPath, expandedShortcutPath.get(), requiredBufferLength));

    ComPtr<IPersistFile> persistFile;
    RETURN_IF_FAILED(shellLink.As(&persistFile));
    RETURN_IF_FAILED(persistFile->Save(expandedShortcutPath.get(), FALSE));

    return 0;
}

.URL 起動ツールのショートカットのサンプル

[{9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}]
Prop31=C:\Program Files (x86)\MyLauncher\apps\app-identifier\game.visualelementsmanifest.xml
Prop5=ExplicitAppUserModelID

[{000214A0-0000-0000-C000-000000000046}]
Prop3=19,0

[InternetShortcut]
IDList=
URL=MyLauncher://launch/app-identifier
IconFile=C:\Program Files (x86)\MyLauncher\apps\app-identifier\game.exe
IconIndex=0

関連項目