Game explorer: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m (Added/fixed links)
 
(13 intermediate revisions by 6 users not shown)
Line 4: Line 4:
Microsoft Windows Vista ships with a feature called Game Explorer that allows a developer to list games in a central explorer location. This page contains code that allows a NSIS installer to add  and remove a game from the Game Explorer.
Microsoft Windows Vista ships with a feature called Game Explorer that allows a developer to list games in a central explorer location. This page contains code that allows a NSIS installer to add  and remove a game from the Game Explorer.


Before using this code, a game with an implemented GDF must already be prepared. GDF stands for Game Definition File and is actually a XML embedded as a resource in the game executable. The resource type should be named DATA and the resource itself should be named __GDF_XML. For more information, see MSDN.
Before using this code, a game with an implemented GDF must already be prepared. GDF stands for [https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ee417681(v=vs.85) Game Definition File] and is actually a XML embedded as a resource in the game executable. The resource type should be named DATA and the resource itself should be named __GDF_XML. For more information, see MSDN.


== Code ==
== Code ==
Line 86: Line 86:
   !else if ${CONTEXT} == user
   !else if ${CONTEXT} == user


     System::Call "$1->${IGameExplorer_AddGame}(w R1, w R0, i ${GIS_CURRENT_USER}, g R2) i .r0"
     System::Call "$1->${IGameExplorer_AddGame}(w R0, w R1, i ${GIS_CURRENT_USER}, g R2) i .r0"


   !else
   !else
Line 105: Line 105:


       SetShellVarContext all
       SetShellVarContext all
      CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0
      CreateShortcut $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk $R3


    !else if if ${CONTEXT} == user


       SetShellVarContext user
    !else if ${CONTEXT} == user
 
       SetShellVarContext current
      CreateDirectory $LocalAPPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0
      CreateShortcut $LocalAPPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk $R3


     !endif
     !endif
 
      
     CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0
    CreateShortcut $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk $R3
 
   ${EndIf}
   ${EndIf}


Line 232: Line 234:
=== Additional Tasks ===
=== Additional Tasks ===


'''GameExplorer_AddGame''' creates only one task by default - the ''Play'' task. To create more, a shortcut must be created in a numbered directory under ''$APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\PlayTasks\<task number>'' or ''$APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\SupportTasks\<task number>''. The ''Play'' task is numbered 0 under PlayTasks, so the next play task should be numbered 1, while the next support task should be numbered 0.
'''GameExplorer_AddGame''' creates only one [https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ee417686(v=vs.85) task] by default - the ''Play'' task. To create more, a shortcut must be created in a numbered directory under ''$APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\PlayTasks\<task number>'' or ''$APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\SupportTasks\<task number>''. The ''Play'' task is numbered 0 under PlayTasks, so the next play task should be numbered 1, while the next support task should be numbered 0.


<highlight-nsis># restore instance GUID to $0 somehow
<highlight-nsis>
SetShellVarContext all
# restore instance GUID to $0 somehow
CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1
CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1
CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1\Network Play.lnk" \
CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1\Network Play.lnk" \
Line 263: Line 267:
== Related MSDN Pages ==
== Related MSDN Pages ==


*[http://msdn2.microsoft.com/en-us/library/bb206359.aspx#Integrating_into_an_Installer Integrating Windows Game Explorer into an Installer]
*[https://learn.microsoft.com/en-us/windows/win32/dxtecharts/windows-game-explorer-integration#http://msdn2.microsoft.com/en-us/library/bb206359.aspx#Integrating_into_an_Installer Integrating Windows Game Explorer into an Installer]
*[http://msdn2.microsoft.com/en-us/library/bb173435.aspx Game Definition File Editor]
*[http://msdn2.microsoft.com/en-us/library/bb173435.aspx Game Definition File Editor]


Line 269: Line 273:
[[Games plug-in]] A plug-in for NSIS that will help you register your game with Games Explorer as well as Media Center.
[[Games plug-in]] A plug-in for NSIS that will help you register your game with Games Explorer as well as Media Center.


[http://www.extensiblesoft.com/gamex/GameExplorerManager10beta6.zip Games Explorer Manager] ([http://www.extensiblesoft.com/gamex/Screen.png Screenshot]) For someone who doesn't need to build an installer.  Allows user to add any program or game currently installed into the Games Explorer.
[http://www.extensiblesoft.com/gamex/ Games Explorer Manager] ([http://www.extensiblesoft.com/gamex/Screen.png Screenshot]) For someone who doesn't need to build an installer.  Allows user to add any program or game currently installed into the Games Explorer.
 
[[Games_Explorer_Manager_Install]] for the Games Explorer Manager
 
[https://github.com/walbourn/directx-sdk-samples/blob/main/GDFTrace/ratings.xml#https://code.msdn.microsoft.com/GDF-Trace-5389d1b4/sourcecode?fileId=92718&pathId=490147704 ratings.xml] (GDF file must be signed)
 
[https://code.msdn.microsoft.com/GameuxInstallHelper-6a9335ca#https://github.com/walbourn/directx-sdk-samples Gameux Install Helper (DX SDK)]
 
[https://github.com/iryoku/smaa/blob/master/Demo/DXUT/Core/DXUTmisc.cpp DXUTReLaunchMediaCenter]


[[Category:Code Examples]]
[[Category:Code Examples]]

Latest revision as of 23:55, 5 November 2022

Author: codev (talk, contrib)


Description

Microsoft Windows Vista ships with a feature called Game Explorer that allows a developer to list games in a central explorer location. This page contains code that allows a NSIS installer to add and remove a game from the Game Explorer.

Before using this code, a game with an implemented GDF must already be prepared. GDF stands for Game Definition File and is actually a XML embedded as a resource in the game executable. The resource type should be named DATA and the resource itself should be named __GDF_XML. For more information, see MSDN.

Code

# user interface
 
!define GameExplorer_GenerateGUID '!insertmacro GameExplorer_GenerateGUID'
!define GameExplorer_AddGame      '!insertmacro GameExplorer_AddGame'
!define GameExplorer_UpdateGame   '!insertmacro GameExplorer_UpdateGame'
!define GameExplorer_RemoveGame   '!insertmacro GameExplorer_RemoveGame'
 
# internal stuff
 
!define CLSCTX_INPROC_SERVER 1
!define IID_IGameExplorer  {E7B2FB72-D728-49B3-A5F2-18EBF5F1349E}
!define CLSID_GameExplorer {9A5EA990-3034-4D6F-9128-01F3C61022BC}
 
!define GIS_CURRENT_USER 2
!define GIS_ALL_USERS    3
 
!define IGameExplorer_QueryInterface 0
!define IGameExplorer_AddRef         1
!define IGameExplorer_Release        2
!define IGameExplorer_AddGame        3
!define IGameExplorer_RemoveGame     4
!define IGameExplorer_UpdateGame     5
!define IGameExplorer_VerifyAccess   6
 
# includes
 
!include LogicLib.nsh
 
# the actual code
 
!macro GameExplorer_GenerateGUID
 
  System::Call 'ole32::CoCreateGuid(g .s)'
 
!macroend
 
!macro GameExplorer_AddGame CONTEXT GDF INSTDIR EXE GUID
 
  !define __GAME_EXPLORER_UNIQUE "${__LINE__}${__FILE__}"
 
  Push $0
  Push $1
 
  Push $R0
  Push $R1
  Push $R2
  Push $R3
 
  Push "${EXE}"
  Push "${GUID}"
  Push "${INSTDIR}"
  Push "${GDF}"
 
  Pop $R0 # == ${GDF}
  Pop $R1 # == ${INSTDIR}
  Pop $R2 # == ${GUID}
  Pop $R3 # == ${EXE}
 
  ClearErrors
 
  System::Call "ole32::CoCreateInstance( \
    g '${CLSID_GameExplorer}', i 0, \
    i ${CLSCTX_INPROC_SERVER}, \
    g '${IID_IGameExplorer}', *i .r1) i .r0"
 
  ${If} $0 != 0 # S_OK
 
    SetErrors
    Goto "done_${__GAME_EXPLORER_UNIQUE}"
 
  ${EndIf}
 
  !if ${CONTEXT} == all
 
    System::Call "$1->${IGameExplorer_AddGame}(w R0, w R1, i ${GIS_ALL_USERS}, g R2) i .r0"
 
  !else if ${CONTEXT} == user
 
    System::Call "$1->${IGameExplorer_AddGame}(w R0, w R1, i ${GIS_CURRENT_USER}, g R2) i .r0"
 
  !else
 
    !error "Invalid CONTEXT passed to GameExplorer_AddGame! Must be `user` or `all`."
 
  !endif
 
  ${If} $0 != 0 # S_OK
 
    SetErrors
 
  ${Else}
 
    # Create play task
 
    !if ${CONTEXT} == all
 
      SetShellVarContext all
      CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0
      CreateShortcut $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk $R3
 
 
    !else if ${CONTEXT} == user
 
      SetShellVarContext current
      CreateDirectory $LocalAPPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0
      CreateShortcut $LocalAPPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk $R3
 
    !endif
 
  ${EndIf}
 
  System::Call "$1->${IGameExplorer_Release}()"
 
  "done_${__GAME_EXPLORER_UNIQUE}:"
 
    Pop $R3
    Pop $R2
    Pop $R1
    Pop $R0
 
    Pop $1
    Pop $0
 
  !undef __GAME_EXPLORER_UNIQUE
 
!macroend
 
!macro _GameExplorer_GUID_Function Function GUID
 
  !define __GAME_EXPLORER_UNIQUE "${__LINE__}${__FILE__}"
 
  Push $0
  Push $1
  Push $2
  Push $3
  Push $4
  Push $5
 
  Push $R0
 
  Push "${GUID}"
 
  Pop $R0 # == ${GUID}
 
  System::Alloc 16
  Exch $R0
  System::Call "ole32::CLSIDFromString(w s, i R0)"
  System::Call "*$R0(i .r2, i .r3, i .r4, i .r5)"
  System::Free $R0
 
  ClearErrors
 
  System::Call "ole32::CoCreateInstance( \
    g '${CLSID_GameExplorer}', i 0, \
    i ${CLSCTX_INPROC_SERVER}, \
    g '${IID_IGameExplorer}', *i .r1) i .r0"
 
  ${If} $0 != 0 # S_OK
 
    SetErrors
    Goto "done_${__GAME_EXPLORER_UNIQUE}"
 
  ${EndIf}
 
  System::Call "$1->${Function}(i r2, i r3, i r4, i r5) i .r0"
 
  ${If} $0 != 0 # S_OK
 
    SetErrors
 
  ${EndIf}
 
  System::Call "$1->${IGameExplorer_Release}()"
 
  "done_${__GAME_EXPLORER_UNIQUE}:"
 
    Pop $R0
 
    Pop $5
    Pop $4
    Pop $3
    Pop $2
    Pop $1
    Pop $0
 
  !undef __GAME_EXPLORER_UNIQUE
 
!macroend
 
!macro GameExplorer_UpdateGame GUID
 
  !insertmacro _GameExplorer_GUID_Function ${IGameExplorer_UpdateGame} "${GUID}"
 
!macroend
 
!macro GameExplorer_RemoveGame GUID
 
  !insertmacro _GameExplorer_GUID_Function ${IGameExplorer_RemoveGame} "${GUID}"
 
!macroend

Usage

Save the code above in a file named GameExplorer.nsh and include it from your script before using the macros.

!include GameExplorer.nsh

Adding Games

First, an instance GUID for the game installation must be created with GameExplorer_GenerateGUID or any other GUID generation method. The generated instance GUID must be saved for later usage as it's required for the removal and updating of the game.

${GameExplorer_GenerateGUID}
Pop $0 # instance GUID saved to $0

Next, simply call GameExplorer_AddGame with all the details.

${GameExplorer_AddGame} all $INSTDIR\GDF.dll $INSTDIR $INSTDIR\Game.exe $0
  # `all` means installation for all users
  # `$INSTDIR\GDF.dll` is the path to the executable containing the GDF
  # `$INSTDIR` is the installation directory
  # `$INSTDIR\Game.exe` is the path to the main game executable
  # `$0` is the instance GUID

The error flag is set in case of an error.

Additional Tasks

GameExplorer_AddGame creates only one task by default - the Play task. To create more, a shortcut must be created in a numbered directory under $APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\PlayTasks\<task number> or $APPDATA\Microsoft\Windows\GameExplorer\<instance GUID>\SupportTasks\<task number>. The Play task is numbered 0 under PlayTasks, so the next play task should be numbered 1, while the next support task should be numbered 0.

SetShellVarContext all
# restore instance GUID to $0 somehow
CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1
CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\PlayTasks\1\Network Play.lnk" \
  "$INSTDIR\Game.exe" "-network"
 
CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0
CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0\Help.lnk" \
  "$INSTDIR\Support.exe"

Updating Games

Restore the instance GUID and pass it to GameExplorer_UpdateGame.

# restore instance GUID to $0 somehow
${GameExplorer_UpdateGame} $0

The error flag is set in case of an error.

Removing Games

Restore the instance GUID and pass it to GameExplorer_RemoveGame.

# restore instance GUID to $0 somehow
${GameExplorer_RemoveGame} $0

The error flag is set in case of an error.

Related MSDN Pages

See Also

Games plug-in A plug-in for NSIS that will help you register your game with Games Explorer as well as Media Center.

Games Explorer Manager (Screenshot) For someone who doesn't need to build an installer. Allows user to add any program or game currently installed into the Games Explorer.

Games_Explorer_Manager_Install for the Games Explorer Manager

ratings.xml (GDF file must be signed)

Gameux Install Helper (DX SDK)

DXUTReLaunchMediaCenter