Implementar iniciadores de aplicações 3D (aplicações Win32)

Nota

Esta funcionalidade só está disponível para PCs com os voos mais recentes do Windows Insider (RS5), compilação 17704 e mais recentes.

O Windows Mixed Reality casa é o ponto de partida em que os utilizadores aterram antes de iniciar aplicações. Por predefinição, tem de iniciar aplicações e jogos win32 VR envolventes a partir de fora do headset e não aparecerá na lista "Todas as aplicações" no menu Iniciar Windows Mixed Reality. Se seguir as instruções neste artigo para implementar um iniciador de aplicações 3D, a experiência avançada do Win32 VR pode ser iniciada a partir do menu Iniciar Windows Mixed Reality e do ambiente doméstico.

Isto só se aplica a experiências avançadas do Win32 VR distribuídas fora do Steam. Para experiências vr distribuídas através do Steam, atualizámos o Windows Mixed Reality para SteamVR Beta juntamente com os voos mais recentes do Windows Insider RS5 para que os títulos do SteamVR apareçam no menu Windows Mixed Reality Iniciar na lista "Todas as aplicações" utilizando automaticamente um iniciador predefinido. Por outras palavras, o método descrito neste artigo é desnecessário para títulos steamVR e será substituído pela funcionalidade Windows Mixed Reality para SteamVR Beta.

Processo de criação do iniciador de aplicações 3D

Existem três passos para criar um iniciador de aplicações 3D:

  1. Estruturação e conceitos
  2. Modelação e exportação
  3. Integrá-la na sua aplicação (este artigo)

Os recursos 3D a utilizar como iniciadores para a sua aplicação devem ser criados com as diretrizes de criação Windows Mixed Reality para garantir a compatibilidade. Os recursos que não cumprirem esta especificação de criação não serão compostos na casa Windows Mixed Reality.

Configurar o iniciador 3D

As aplicações Win32 aparecerão na lista "Todas as aplicações" no menu Windows Mixed Reality Iniciar se criar um iniciador de aplicações 3D para as mesmas. Para tal, crie um ficheiro XML de Manifesto de Elementos Visuais que faça referência ao Iniciador de Aplicações 3D ao seguir estes passos:

  1. Crie um ficheiro GLB de recurso do Iniciador de Aplicações 3D (veja Modelação e exportação).
  2. Crie um Manifesto de Elementos Visuais para a sua aplicação.
    1. Pode começar com o exemplo abaixo. Veja a documentação completa do Manifesto de Elementos Visuais para obter mais detalhes.
    2. Atualize Square150x150Logo e Square70x70Logo com um PNG/JPG/GIF para a sua aplicação.
      • Estas serão utilizadas para o logótipo 2D da aplicação na lista Windows Mixed Reality Todas as Aplicações e para o Menu Iniciar no ambiente de trabalho.
      • O caminho do ficheiro baseia-se na pasta que contém o Manifesto de Elementos Visuais.
      • Ainda precisa de fornecer um ícone de Menu Iniciar para ambiente de trabalho para a sua aplicação através dos mecanismos padrão. Isto pode estar diretamente no executável ou no atalho que criar. Por exemplo, através de IShellLink::SetIconLocation.
      • Opcional: Pode utilizar um ficheiro resources.pri se quiser que o MRT forneça vários tamanhos de recursos para escalas de resolução diferentes e temas de alto contraste.
    3. Atualizar o Caminho MixedRealityModel para apontar para o GLB para o Iniciador de Aplicações 3D
    4. Guarde o ficheiro com o mesmo nome que o ficheiro executável, com uma extensão de ".VisualElementsManifest.xml" e guarde-o no mesmo diretório. Por exemplo, para o ficheiro executável "contoso.exe", o ficheiro XML que o acompanha tem o nome "contoso.visualelementsmanifest.xml".
  3. Adicione um atalho à sua aplicação ao Menu Iniciar do Windows para ambiente de trabalho. Veja o exemplo abaixo para obter um exemplo de implementação C++.
    • Crie-o em %ALLUSERSPROFILE%\Microsoft\Windows\Menu Iniciar\Programas (computador) ou %APPDATA%\Microsoft\Windows\Menu Iniciar\Programas (utilizador)
    • Se uma atualização alterar o manifesto dos elementos visuais ou os recursos referenciados pela mesma, o atualizador ou instalador deverá atualizar o atalho de modo a que o manifesto seja reparado e os recursos em cache sejam atualizados.
  4. Opcional: Se o atalho de ambiente de trabalho não apontar diretamente para o EXE da sua aplicação (por exemplo, se invocar um processador de protocolos personalizado como "myapp://"), o Menu Iniciar não encontrará automaticamente o ficheiro de VisualElementsManifest.xml da aplicação. Para resolver este problema, o atalho deve especificar o caminho de ficheiro do Manifesto de Elementos Visuais com System.AppUserModel.VisualElementsManifestHintPath (). Isto pode ser definido no atalho com as mesmas técnicas que System.AppUserModel.ID. Não tem de utilizar System.AppUserModel.ID, mas pode fazê-lo se quiser que o atalho corresponda ao ID explícito do Modelo de Utilizador da Aplicação da aplicação, se for utilizado. Veja a secção de criação de atalhos do iniciador de aplicações de exemplo abaixo para obter um exemplo de C++.

Manifesto de Elementos Visuais de Exemplo

<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>

Criação de atalho do iniciador de aplicações de exemplo

O código de exemplo abaixo mostra como pode criar um atalho em C++, incluindo substituir o caminho para o ficheiro XML do Manifesto de Elementos Visuais. Tenha em atenção que a substituição só é necessária nos casos em que o atalho não aponte diretamente para o EXE associado ao manifesto (por exemplo, o atalho utiliza um processador de protocolos personalizado como "myapp://").

Exemplo de . Criação de atalhos 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;
}

Exemplo de . Atalho do iniciador de 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

Ver também