Реализация средств запуска трехмерных приложений (приложения Win32)

Примечание

Эта функция доступна только для компьютеров с последними тестами программы предварительной оценки Windows (RS5), сборкой 17704 и более поздними версиями.

Windows Mixed Reality дома является отправной точкой, где пользователи приземлились перед запуском приложений. По умолчанию вам нужно запускать иммерсивные приложения и игры Виртуальной реальности Win32 из-за пределов гарнитуры и не будут отображаться в списке "Все приложения" в меню "Пуск" Windows Mixed Reality. Если вы следуйте инструкциям в этой статье по реализации средства запуска трехмерных приложений, вы можете запустить иммерсивный интерфейс Виртуальной реальности Win32 из меню "Пуск" Windows Mixed Reality и домашней среды.

Это справедливо только для иммерсивных интерфейсов Виртуальной реальности Win32, распределенных за пределами Steam. Для виртуальной реальности, распространяемой через Steam, мы обновили Windows Mixed Reality для бета-версии SteamVR вместе с последними тестами программы предварительной оценки Windows RS5, чтобы названия SteamVR отображались в меню Windows Mixed Reality Пуск в списке "Все приложения" автоматически с помощью средства запуска по умолчанию. Другими словами, метод, описанный в этой статье, не требуется для названий SteamVR и будет переопределен Windows Mixed Reality для функций SteamVR Beta.

Процесс создания средства запуска трехмерных приложений

Создание средства запуска трехмерных приложений выполняется в трех шагах:

  1. Проектирование и концепция
  2. Моделирование и экспорт
  3. Интеграция этого приложения в приложение (эта статья)

Трехмерные ресурсы, используемые в качестве средств запуска приложения, должны создаваться с использованием Windows Mixed Reality рекомендаций по разработке, чтобы обеспечить совместимость. Ресурсы, которые не соответствуют этой спецификации разработки, не будут отображаться в Windows Mixed Reality домашней странице.

Настройка средства запуска трехмерных параметров

Приложения Win32 будут отображаться в списке "Все приложения" в меню Windows Mixed Reality "Пуск", если вы создадите для них средство запуска трехмерных приложений. Для этого создайте XML-файл манифеста визуальных элементов , ссылающийся на средство запуска трехмерных приложений, выполнив следующие действия.

  1. Создайте GLB-файл ресурса средства запуска трехмерных приложений (см. статью Моделирование и экспорт).
  2. Создайте манифест визуальных элементов для приложения.
    1. Вы можете начать с примера ниже. Дополнительные сведения см. в полной документации по манифесту визуальных элементов .
    2. Обновите Square150x150Logo и Square70x70Logo с помощью PNG/JPG/GIF для приложения.
      • Они будут использоваться для двухD-логотипа приложения в списке Windows Mixed Reality Все приложения и меню "Пуск" на рабочем столе.
      • Путь к файлу основан на папке, содержащей манифест визуальных элементов.
      • Вам по-прежнему нужно предоставить значок меню "Пуск" для приложения с помощью стандартных механизмов. Это может быть либо непосредственно в исполняемом файле, либо в ярлыке, который вы создаете. Например, через IShellLink::SetIconLocation.
      • Дополнительные: Вы можете использовать файл resources.pri, если вы хотите, чтобы MRT предоставлял несколько размеров ресурсов для различных масштабов разрешения и тем с высокой контрастностью.
    3. Обновите путь MixedRealityModel , чтобы он указывал на GLB для средства запуска трехмерных приложений.
    4. Сохраните файл с тем же именем, что и исполняемый файл, с расширением ".VisualElementsManifest.xml" и сохраните его в том же каталоге. Например, для исполняемого файла "contoso.exe" сопутствующий XML-файл называется "contoso.visualelementsmanifest.xml".
  3. Добавьте ярлык в приложение в классическое меню "Пуск" Windows. Пример реализации C++ см. в примере ниже .
    • Создайте его в папке %ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs (компьютер) или %APPDATA%\Microsoft\Windows\Start Menu\Programs (пользователь)
    • Если обновление изменяет манифест визуальных элементов или ресурсы, на которые он ссылается, средство обновления или установщик должны обновить ярлык таким образом, чтобы манифест был повторно преобразован и кэшированные ресурсы были обновлены.
  4. Дополнительные: Если ярлык на рабочем столе не указывает непосредственно на EXE-файл приложения (например, если вызывается настраиваемый обработчик протокола, такой как "myapp://"), меню "Пуск" не найдет файл VisualElementsManifest.xml приложения автоматически. Чтобы устранить эту проблему, ярлык должен указать путь к файлу манифеста визуальных элементов с помощью System.AppUserModel.VisualElementsManifestHintPath (). Это можно задать в ярлыке, используя те же методы, что и System.AppUserModel.ID. Вы не обязаны использовать System.AppUserModel.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

См. также раздел