- NSIS Discussion
- windows vista -> nsis using game explorer
Archive: windows vista -> nsis using game explorer
DOCa Cola
5th November 2006 22:36 UTC
windows vista -> nsis using game explorer
hi, could someone help using the igameexplorer interface from windows vista with nsis' system.dll?
i already have my executable modified with the gdf (game definition file) data as described in the ms directx sdk. now, the next step to take is registering the executable via an api call.
here is what the directx sdk readme states
Once the GDF and related files have been added to a binary resource, it is then possible to integrate the game with Game Explorer. It is strongly advised that games integrate with Game Explorer during the installation process. The outline to the integration process is as follows:[list=1][*]Install ALL files to the user's hard drive. The next step activates parental controls and could potentially lock the user out of the installation directory. [*]Create an instance to the IGameExplorer interface. [*]Call the VerifyAccess method, of the IGameExplorer interface and pass it the path to the GDF. [*]Call the AddGame method, of the IGameExplorer interface and pass it the path to the GDF, the path to the root installation directory, and a unique GUID called the game instance ID. [*]Create shortcuts, which are Game Explorer tasks, by using the game instance ID. Game Explorer tasks are explained in the next section.[/list=1]
game explorer:
http://windowssdk.msdn.microsoft.com.../ms687212.aspxinterface reference:
http://windowssdk.msdn.microsoft.com.../ms687221.aspx
kichik
6th November 2006 06:55 UTC
Completely untested.
!include WinVer.nsh
!define GDF $INSTDIR\game.exe
!define GIS_NOT_INSTALLED 0 # might be wrong value
!define GIS_CURRENT_USER 1 # might be wrong value
!define GIS_ALL_USERS 2 # might be wrong value
${If} ${AtLeastWinVista}
SetOutPath $PLUGINSDIR
File GameuxInstallHelper.dll # from dxsdk
System::Call "GameuxInstallHelper::GenerateGUID(*g .r0)"
System::Call "GameuxInstallHelper::AddToGameExplorer(t '${GDF}', t d, i ${GIS_ALL_USERS}, *g r0)"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, *g r0, i 0, i 0, t 'Play', t '${GDF}', t '')"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, *g r0, i 0, i 1, t 'Network Play', t '${GDF}', t '-network')"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, *g r0, i 0, i 2, t 'Safe Mode', t '${GDF}', t '-safe')"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, *g r0, i 1, i 0, t 'Supprt', t 'http://nsis.sf.net/', t '')"
System::Call "GameuxInstallHelper::SetupRichSavedGames(t '.ExampleSaveGame', t '${GDF}', t '%1')"
SetOutPath $INSTDIR
${EndIf}
# uninstall
${If} ${AtLeastWinVista}
System::Call "GameuxInstallHelper::RetrieveGUIDForApplication(t '${GDF}', *g .r0)"
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(*g .r0)"
System::Call "GameuxInstallHelper::RemoveTasks(*g .r0)"
System::Call "GameuxInstallHelper::RemoveRichSaveGames(t '.ExampleSaveGame')"
${EndIf}
dandaman32
6th November 2006 10:17 UTC
Great. From what I can tell there, Microsoft is now using something even more cryptic than the Registry. Now there's a "games database"?
<sarcastic>*sighs* don't you just love it when Microsoft's APIs insist on doing everything for you?</sarcastic>
-dandaman32
DOCa Cola
6th November 2006 19:26 UTC
thanks for your help kichik!
works quite well, except one thing. in my case the guid is generated before - in the game definition file editor.
i tried both, with the sample binary with gdf information and my own binary and both the last parameter of addline could be left empty or even should left empty. i am not much into the gdf thing yet, so i don't know why this last parameter is there anyway as in the vista registry the guid of the is taken anyway.
the line
System::Call "GameuxInstallHelper::GenerateGUID(*g .r0)"
crashes the installer. as i seem not to require it anyway i left it out, everything else seems to run smooth yet though i didn't try the uninstaller yet but looking at the lines you wrote that could be more a problem than
addline cause of the guid thing i do not totally understand ;)
DOCa Cola
edit: @dandaman32
and yes, quite complicated for a simple link with menu :P
kichik
6th November 2006 21:11 UTC
GenerateGUID might need an allocated buffer like CoCreateGuid. In which case, its usage should be:
System::Alloc 16
System::Call "GameuxInstallHelper::GenerateGUID(i sr0)"
or even:
System::Call "GameuxInstallHelper::GenerateGUID(g .r0)"
I'd need the DLL to verify. Could you attach it? Though you're probably correct that it just generates a new GUID. It doesn't take any parameters relating to the game.
DOCa Cola
6th November 2006 22:29 UTC
here you go. :)
thanks for your time
kichik
6th November 2006 22:44 UTC
As I thought, it just calls CoCreateGuid. The last usage example I wrote should work. It'd probably have the same effect if you generate the GUID in advance on your computer, but I can't be sure of that. According to MSDN, it's the InstanceID, so it's probably per-computer after all.
MSDN also says:
Callers should store the instanceID returned by this call as it is necessary to call RemoveGame or UpdateGame, and to create tasks for the game within the Game Explorer.
If the call is made to upgrade a legacy title to a supported title the ID returned in pguidInstanceID will be the same as the legacy entry.
It seems AddGame would return a different GUID then the one passed, if the game is already installed. All `*g r0` instances in the script above should therefore be changed to `gr0` and the first instance, in the call to AddToGameExplorer should be changed to `gr0r0` so that AddToGameExplorer would be able to change the GUID.
DOCa Cola
8th November 2006 11:43 UTC
great, installing works now without any problems. the uninstaller is the next step.
thanks for your help kichik!
kichik
8th November 2006 17:58 UTC
Mind creating a page on the Wiki with examples and functions/macros for adding games to the Game Explorer?
DOCa Cola
11th November 2006 11:45 UTC
yea, as soon as i got this 100% running.
today i played with the uninstaller and couldn't get it working. i forgot to copy the gameuxinstallhelper.dll in the first place but i added it later so the uninstaller part does now look like that
${If} ${AtLeastWinVista}
SetOutPath $PLUGINSDIR
File GameuxInstallHelper.dll # from dxsdk
System::Call "GameuxInstallHelper::RetrieveGUIDForApplication(t '${GDF}', *g .r0)"
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(*g .r0)"
System::Call "GameuxInstallHelper::RemoveTasks(*g .r0)"
System::Call "GameuxInstallHelper::RemoveRichSaveGames(t '.ExampleSaveGame')"
SetOutPath $INSTDIR
${EndIf}
i tested it and the path to ${GDF} is also correct set to the gdf binary.
Another problem i am experiencing are random crashes sometimes the installer calls the dll functions - both with the installer and uninstaller
http://img170.imageshack.us/my.php?i...6123647py9.png
kichik
11th November 2006 11:51 UTC
You need to convert `*g .r0` to `g .r0` for the first call and to `g r0` for the others, just like with the installer code.
DOCa Cola
11th November 2006 12:43 UTC
damn, i already tried changing the first call but forgot about the others ;) thx i will try it
DOCa Cola
12th November 2006 09:31 UTC
still no success with
${If} ${AtLeastWinVista}
SetOutPath $PLUGINSDIR
File GameuxInstallHelper.dll # from dxsdk
System::Call "GameuxInstallHelper::RetrieveGUIDForApplication(t '${GDF}', g .r0)"
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(*g r0)"
System::Call "GameuxInstallHelper::RemoveTasks(*g r0)"
System::Call "GameuxInstallHelper::RemoveRichSaveGames(t '.ExampleSaveGame')"
SetOutPath $INSTDIR
${EndIf}
the uninstaller seems to run fine but the game doesn't seem to be removed from the game browser...
kichik
14th November 2006 18:49 UTC
You still have an asterisk before `g`. It should be `gr0` for the last two calls.
kverity
5th December 2006 19:51 UTC
including .dlls in Setup package.
How can I pack the GameuxInstallHelper.dll into the AppNameSetup.exe?
Is is necessary for our users to only download one file and I need to have the .dll accessible so the calls to the Game Explorer work correctly.
Any help would be appreciated,
Thanks,
Keith
necrophilissimo
8th January 2007 18:26 UTC
Okay, I know I'm asking dumb questions, but has anyone made a tutorial on this subject? :D
Comm@nder21
8th January 2007 20:32 UTC
does the dll not exist on every vista system?
if it does exist on every vista system, you should not include it in your setup but rather check, whether the user has the dll already and then call the functions or don't, if he has no windows vista (because then they're all useless).
if it is not installed on vista by default you should indeed include the dll into your installer.
this is quite simple:
SetOutPath $PLUGINSDIR
File GameuxInstallHelper.dll
you may need to modify your dll calls to:
system::call '$PLUGINSDIR\GameuxInstallHelper.dll::blabla()'
ashre
21st February 2007 21:04 UTC
I've recently written an installer integrating with Game Explorer, thanks for the help kichik and Doca!
I've put up a wiki page with the code at:
http://nsis.sourceforge.net/Game_explorer
One thing of interest I discovered is that if you try and create a game explorer link for the current user it fails unless you are an administrator as it tries to write to HKLM - this is in conflict with what the documentation says but there's very little other information about Game Explorer at the moment.
--
Marc Sutton
www.codev.co.uk
THiRD
14th March 2007 23:28 UTC
I've been reading through these forums and I have been able to get my game to install in game explorer. My problem is that I can not uninstall the game from Game Explorer now. This is the GameEx code that I am using:
!define GDF gdf_wheel.dll
!define GIS_NOT_INSTALLED 0 # might be wrong value
!define GIS_CURRENT_USER 1 # might be wrong value
!define GIS_ALL_USERS 2 # might be wrong value
..Other code omitted
Install Code
${If} ${AtLeastWinVista}
SetOutPath $PLUGINSDIR
File GameuxInstallHelper.dll # from dxsdk
System::Call "GameuxInstallHelper::GenerateGUID(*g .r0)"
System::Call "GameuxInstallHelper::AddToGameExplorer(t '${GDF}', t d, i ${GIS_ALL_USERS}, *g r0)"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, *g r0, i 0, i 0, t 'Play', t '${GDF}', t '')"
SetOutPath $INSTDIR
${EndIf}
Uninstall Code
${If} ${AtLeastWinVista}
System::Call "GameuxInstallHelper::RetrieveGUIDForApplication(t '${GDF}', *g .r0)"
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(*g .r0)"
System::Call "GameuxInstallHelper::RemoveTasks(*g .r0)"
${EndIf}
I'm not sure where to go from here I've read the NSIS wiki on game explorer and I still can not get my game removed from game explorer. So my first step is to actually get the game removed then figure out how to set up the installer/uninstaller correctly.
ashre
15th March 2007 09:52 UTC
Hi Third,
You need to use code more like that in the wiki. For a start the defines at the top of your code are incorrect. Also you need to RequestUserLevel admin at the top (it seems that applies even if you are trying to install for a current user).
Also you need to generate a GUID and store it in the registry when you install, then use that value to uninstall. Copying the code from the wiki entry at:
http://nsis.sourceforge.net/Game_explorer
should make it work. Hope that helps,
--
Marc Sutton
http://www.codev.co.uk
THiRD
15th March 2007 19:52 UTC
I tried the code from the wiki, but I think my problem is that I can't get the old game to uninstall from gameEx so the code from the wiki doesn't work. Also I have a gid inside my GDF file do I need to generate one the way you said or should I be able to pull it from the GDF?
Thanks
THiRD
15th March 2007 21:07 UTC
Okay some how i managed to get the old game removed from GameEx I am now using the code from the wiki, but it is not installing GameEx. I have the GameuxInstallHelper.dll and my gdf.dll in the directory with the installer. My script compiles fine it just doesn't seem to be running the GameEx functions.
!define GDF "gdf_wheel.dll"
!define PRODUCT "MyGame"
!define FILES "files"
!define STUDIO "MyStudio"
;Directory selection page
InstallDir "$PROGRAMFILES\${STUDIO}\${PRODUCT}"
Function GameExplorer
Pop $0
; Check if we have Vista or later
ClearErrors
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors finished
StrCpy $0 $0 1
IntCmp $0 6 0 finished
; Register with Game Explorer if so
;SetOutPath $PLUGINSDIR
File "GameuxInstallHelper.dll"
; Remove first to avoid duplication
ReadRegStr $0 HKCU "Software\${PRODUCT}" "GameExplorer"
StrCmp $0 '' skipUninstall
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(g r0)"
System::Call "GameuxInstallHelper::RemoveTasks(g r0)"
skipUninstall:
; Now add to GE
System::Call "GameuxInstallHelper::GenerateGUID(g .r0)"
WriteRegStr HKCU "Software\${PRODUCT}" "GameExplorer" $0
System::Call "GameuxInstallHelper::AddToGameExplorer(t ${GDF}, t '$INSTDIR\${PRODUCT}.exe', i ${GIS_ALL_USERS}, g r0 r0)"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, g r0, i 0, i 0, t 'Play', t '$INSTDIR\${PRODUCT}.exe', t '')"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, g r0, i 1, i 0, t 'Support', t 'http://www.MySite.com/', t '')"
finished:
Pop $0
FunctionEnd
Function un.GameExplorer
Push $0
; Check if we have Vista or later
ClearErrors
ReadRegStr $0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors finished
StrCpy $0 $0 1
IntCmp $0 6 0 finished
; Remove from game explorer
;SetOutPath $Temp
File "GameuxInstallHelper.dll"
ReadRegStr $0 HKCU "Software\${PRODUCT}" "GameExplorer"
StrCmp $0 '' finished
System::Call "GameuxInstallHelper::RemoveFromGameExplorer(g r0)"
System::Call "GameuxInstallHelper::RemoveTasks(g r0)"
finished:
Pop $0
FunctionEnd
Sorry for all of the code just wasn't sure if i was missing something. Like I said, I have the dll's in the same directory as the install script and I also copied them into the directory of the app just to make sure they were found but still no luck.
Thanks
oborstad
5th April 2007 17:44 UTC
Umm.. Does anyone have any ideas why I might be getting empty GUIDs from the System::Call "GameuxInstallHelper::GenerateGUID(g .r0)" line? I'm not getting "", but "{00000000-0000-0000-000000000000}" as a GUID...?
Owen.
Comm@nder21
5th April 2007 17:48 UTC
GenerateGUID does not take a GUID as argument, but the POINTER TO AN GUID.
try GenerateGUID(i .r0)
oborstad
5th April 2007 18:06 UTC
GenerateGUID(i .r0) returns simply 0 instead of an empty GUID
Also, this was taken from above and the wiki, so it seems to have worked for others...
Owen.
Comm@nder21
5th April 2007 21:13 UTC
you may try GenerateGUID(g r0)
Comm@nder21
5th April 2007 21:27 UTC
untested:
System
::Call "*(g 0) i .r0" # allocate memory for the GUID
>System::Call "GameuxInstallHelper::GenerateGUID (i .r0)" # pass the pointer to the allocated memory to the function
>System::Call "*$0(g .r1)" # read the new data from the pointer
>System::Free $0 # free the allocated memory
>DetailPrint "$1" # ouput the data
oborstad
5th April 2007 21:55 UTC
Your code with GenerateGUID (i r0) (no period), gives me a blank GUID again... (not "", "{00000000-0000-0000-000000000000}") This was the same as simply doing the GenerateGUID(g .r0) (which gave the same thing, all 0's)
I'm wondering if there's something borked on the vista box I'm using... (or flavour, or... sigh)
Owen.
oborstad
6th April 2007 00:20 UTC
Well, I found the problem. There are 2 versions of the GameuxInstallHelper. One's a 32 bit dll, one's a 64 bit dll. The 32 bit one works, but if you try to call the 64 bit one, it returns an empty GUID. So. Moral of this story. If you are getting totally weird results, double check you have the right files.
For other people's sanity:
32 bit version of GameuxInstallerHelper is around 77 k
64 bit version of GameuxInstallerHelper is around 100 k
Owen.
Welshman101
8th April 2007 01:07 UTC
If anyone has an install script/s that succesfully add an entry to game explorer I would appreciate it if they would share it with me as I am currently unable to create one of my own.
I've followed the code in the wiki but for some reason my app does not get added to Game Explorer.
mauvecloud
28th March 2008 18:49 UTC
I was able to add an entry to game explorer using the GUID extracted from the GDF resource beforehand, and code like the following:
;--------------------------------
Function GE_AddGame
SetOutPath $PLUGINSDIR
File "GameuxInstallHelper.dll"
System::Call 'GameuxInstallHelper::AddToGameExplorerStrGUID(t "$INSTDIR\${GDF_BINARY}", t "$INSTDIR\", i 3, t "${GAME_GUID}")'
FunctionEnd
;--------------------------------
Function GE_AddTasks
SetShellVarContext all
System::Call 'GameuxInstallHelper::CreateTaskStrGUID(i 3, t "${GAME_GUID}", i 0, i 0, t "Play", t "$INSTDIR\${GAME_EXE}", t "")'
SetShellVarContext current
FunctionEnd
;--------------------------------
Function un.GE_RemoveGame
SetOutPath $PLUGINSDIR
File "GameuxInstallHelper.dll"
System::Call 'GameuxInstallHelper::RemoveFromGameExplorerStrGUID(t "${GAME_GUID}")'
System::Call 'GameuxInstallHelper::RemoveTasksStrGUID(t "${GAME_GUID}")'
FunctionEnd
Possibly the GUID passed to the functions needs to be the same as in the GDF resource, but if that's the case, what's the point of having a GenerateGUID function in GameuxInstallHelper instead of an ExtractGUID function?
oborstad
28th March 2008 19:09 UTC
Originally posted by mauvecloud
Possibly the GUID passed to the functions needs to be the same as in the GDF resource, but if that's the case, what's the point of having a GenerateGUID function in GameuxInstallHelper instead of an ExtractGUID function?
It doesn't, the GUID that you use for passing into the game explorer
should be unique so that you could potentially add multiple versions/installs of the game to the explorer if you really wanted to. The GenerateGUID was failing for me because I had the 64 bit version of the dll instead of the 32 bit version on a 32 bit system.
we use:
System::Call "GameuxInstallHelper::GenerateGUID(g .r0)"
StrCmp $0 '{00000000-0000-0000-0000-000000000000}' finished
System::Call "GameuxInstallHelper::AddToGameExplorer(t 'path_to_gdf_file', t 'path_to_exe', i ${GIS_ALL_USERS}, g r0) i .r4"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, g r0, i 1, i 0, t 'Play', t 'path_to_exe', t 'arguments') i .r4"
System::Call "GameuxInstallHelper::CreateTask(i ${GIS_ALL_USERS}, g r0, i 0, i 0, t 'Support', t 'path_to_exe', t 'arguments') i .r4"
System::Call "GameuxInstallHelper::SetupRihcSavedGames(t '.save_game_extension', t 'path_to_exe', t 'Save_game_descriptor') i .r4"
System::Call "GameuxInstallHelper::RegisterWithMediaCenter(t 'path_to_gdf_file', t 'path_to_mcl_location', i ${GIS_ALL_USERS}, t 'path_to_exe', t 'args', i 0) i .r4"
finished:
${GIS_ALL_USERS} = 3, can be 1 for current user instead (HKCU vs LM and for limited user can be 1)
Hope that helps anyone else that is trying to get this up and running.
Owen.
kichik
29th March 2008 16:42 UTC
There's no need to use GameuxInstallHelper. There are better solutions available.
http://nsis.sourceforge.net/Game_explorer
http://nsis.sourceforge.net/Games_plug-in
mauvecloud
29th March 2008 17:32 UTC
I fail to see how either of those is better than GameuxInstallHelper. The "Games" plugin looks like it will only work if the GDF is embedded in the EXE, not if it's in a separate DLL, and requires MSVCR80.dll. The "GameExplorer" header doesn't handle Media Center (and also looks a little buggy - I mean, why swap the GDF path and INSTDIR depending on current or all users?), and neither currently supports rich saved games.
kichik
29th March 2008 17:47 UTC
GameExplorer header is smaller, simpler, easier to get and just works. Just look at the length of this GameuxInstallHelper related thread to see what I mean. I've created the GameExplorer headers to help users avoid this DLL.
mauvecloud
29th March 2008 19:01 UTC
I'm doubtful of the "just works" part. I still don't understand the reversal of R0 and R1 depending on ${CONTEXT} in the following snippet:
!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
Anyway, I think the clarifications in this thread can be summarized as follows, and maybe added to a wiki page about GameuxInstallHelper:
1. The correct parameter type to use for the GUID (it's "g", not "i" or "*g" - the System plugin takes care of creating a GUID from the string and passing a pointer to it)
2. Use the 32-bit version of GameuxInstallHelper.dll, not the 64-bit version (unless maybe you want to only allow the game to be installed on a 64-bit system)
3. The GUID can be generated during the install, and shouldn't be the same as the gameID in the GDF resource.
Once those three things are understood, using GameuxInstallHelper is almost as easy as the GameExplorer header or Games plugin.
kichik
29th March 2008 20:38 UTC
If you're going to create a Wiki page for GameuxInstallHelper, I suggest you put a direct link to the correct version or step by step instructions for its location.
mauvecloud
30th March 2008 02:20 UTC
Here you go:
http://nsis.sourceforge.net/Game_Explorer_with_Helper
(I haven't figured out yet how this forum decides which links to block, so I'm leaving it as text for now)
For comparison:
Weaknesses of old Game Explorer header:
1. No save game support
2. No media center support
3. Additional tasks have to be created manually (with long paths to remember)
4. No support for pre-Vista systems that might get upgraded
Weaknesses of Games plug-in:
1. Requires msvcr80.dll (612 KB)
2. Can't handle GDF in separate dll
3. No save game support
4. All tasks have to be created manually
5. No support for pre-Vista systems that might get upgraded
Weaknesses of Game Explorer with Helper header:
1. Requires GameuxInstallHelper.dll (95 KB)
2. Doesn't support more than one game per installer
oborstad
30th March 2008 04:29 UTC
2. Doesn't support more than one game per installer
If you change the macro for the adding the game to do a check to see if the dll is already written out, then it should work fine to add multiple games, as long as you make sure to always add them in sequence.
!ifndef GAME_EXPLORER_DLL_EXISTS
!ifdef GAME_EXPLORER_HELPER_PATH
File "/oname=GameuxInstallHelper.dll" "${GAME_EXPLORER_HELPER_PATH}"
!else
File "GameuxInstallHelper.dll"
!endif
!define GAME_EXPLORER_DLL_EXISTS
!endif
Also, another suggestion, for localization reasons, I'd pull the "Play" task out of the first macro, otherwise the French will see "Play". Or put them in as extra label options. (Same for support), or make them come from language strings $(GameExplorerPlayTask) or something.
Owen.
mauvecloud
30th March 2008 06:29 UTC
Supporting more than one game per installer took a little more than just checking for the dll, due to the way it had been using defines for the play task number and support task number, which wouldn't work if the task adding was done in a function declared before the one that added the game, so I switched to variables, and it should be more robust now.
As far as localization, I see your point, but I don't want to force the use of LangStrings, so I pulled the task adding out of the GameExplorer_AddGame, and GameExplorer_AddPlayTask and GameExplorer_AddSupportTask already allow the task names to be specified separately.