Game explorer: Difference between revisions
(instructions on !include) |
(Added missing GenerateGUID macro) |
||
Line 10: | Line 10: | ||
<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 |
Revision as of 10:25, 20 April 2007
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 "${GUID}" Push "${INSTDIR}" Push "${GDF}" Pop $R0 # == ${GDF} Pop $R1 # == ${INSTDIR} Pop $R2 # == ${GUID} 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 R1, w R0, 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 !else if if ${CONTEXT} == user SetShellVarContext user !endif CreateDirectory $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0 CreateShortcut $APPDATA\Microsoft\Windows\GameExplorer\$R2\PlayTasks\0\Play.lnk "${EXE}" ${EndIf} System::Call "$1->${IGameExplorer_Release}()" "done_${__GAME_EXPLORER_UNIQUE}:" 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.
# 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.