Game explorer: Difference between revisions
(macro arguments, working removal and no more GameuxInstallHelper) |
m (Added/fixed links) |
||
(21 intermediate revisions by 8 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 == | ||
<highlight-nsis># user interface | <highlight-nsis># user interface | ||
!define GameExplorer_AddGame | !define GameExplorer_GenerateGUID '!insertmacro GameExplorer_GenerateGUID' | ||
!define GameExplorer_UpdateGame '!insertmacro GameExplorer_UpdateGame' | !define GameExplorer_AddGame '!insertmacro GameExplorer_AddGame' | ||
!define GameExplorer_RemoveGame '!insertmacro GameExplorer_RemoveGame' | !define GameExplorer_UpdateGame '!insertmacro GameExplorer_UpdateGame' | ||
!define GameExplorer_RemoveGame '!insertmacro GameExplorer_RemoveGame' | |||
# internal stuff | # internal stuff | ||
Line 52: | Line 54: | ||
Push $R1 | Push $R1 | ||
Push $R2 | Push $R2 | ||
Push $R3 | |||
Push "${EXE}" | |||
Push "${GUID}" | Push "${GUID}" | ||
Push "${INSTDIR}" | Push "${INSTDIR}" | ||
Line 60: | Line 64: | ||
Pop $R1 # == ${INSTDIR} | Pop $R1 # == ${INSTDIR} | ||
Pop $R2 # == ${GUID} | Pop $R2 # == ${GUID} | ||
Pop $R3 # == ${EXE} | |||
ClearErrors | ClearErrors | ||
Line 81: | Line 86: | ||
!else if ${CONTEXT} == user | !else if ${CONTEXT} == user | ||
System::Call "$1->${IGameExplorer_AddGame}(w | System::Call "$1->${IGameExplorer_AddGame}(w R0, w R1, i ${GIS_CURRENT_USER}, g R2) i .r0" | ||
!else | !else | ||
Line 100: | 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 | |||
SetShellVarContext | !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 | ||
${EndIf} | ${EndIf} | ||
Line 116: | Line 123: | ||
"done_${__GAME_EXPLORER_UNIQUE}:" | "done_${__GAME_EXPLORER_UNIQUE}:" | ||
Pop $R3 | |||
Pop $R2 | Pop $R2 | ||
Pop $R1 | Pop $R1 | ||
Line 202: | Line 210: | ||
== Usage == | == Usage == | ||
Save the code above in a file named '''GameExplorer.nsh''' and include it from your script before using the macros. | |||
<highlight-nsis>!include GameExplorer.nsh</highlight-nsis> | |||
=== Adding Games === | === Adding Games === | ||
Line 223: | 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 231: | Line 244: | ||
CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0 | CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0 | ||
CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0\ | CreateShortcut "$APPDATA\Microsoft\Windows\GameExplorer\$0\SupportTasks\0\Help.lnk" \ | ||
"$INSTDIR\Support.exe"</highlight-nsis> | "$INSTDIR\Support.exe"</highlight-nsis> | ||
Line 254: | 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] | ||
== 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. | |||
[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)