Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

How to call SHGetKnownFolderPath function properl


17 replies to this topic

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 29 December 2012 - 15:15

Hi.

I have a problem with my installscript project.
I need to call the "SHGetKnownFolderPath" function but when I build the project there's no error in build. So, I test the build but when this takes some part of the installation then an error appears: "error in call "SHGetKnownFolderPath".
CODE

// Define Microsoft CSIDL constants
#define FOLDERID_SavedGames
#define KF_FLAG_DONT_VERIFY 0x00004000

// Prototype SHGetFolderPathA in SHFolder.dll
prototype NUMBER shell32.SHGetKnownFolderPath(HWND, NUMBER, NUMBER, BYREF STRING);

szPath = "";
nResult=shell32.SHGetKnownFolderPath(FOLDERID_SavedGames, KF_FLAG_DONT_VERIFY, NULL, szPath);
if (nResult=0) then
MessageBox("FOLDERID_SavedGames= "+szPath,0);
else
SprintfBox(SEVERE, "FOLDERID_SavedGames", "Failed(%d): %s", nResult, FormatMessage(nResult));
endif;


Please, Anyone to help me?, thanks.

P.D. This is the error code:

Error Number: 0x80040707 Failure to call the function

Edited by thanatos83, 30 December 2012 - 16:50.


Taco Bell

Taco Bell

    IS6 Expert

  • Moderators
  • 1,281 posts

Posted 02 January 2013 - 16:07

I haven't yet had to make that particular shell function call, but based on other such ones, you need to at least change all of the SHGetKnownFolderPath references instead to SHGetFolderPathA to match the available ANSI function--like you also indicated in your comment.

Edited by Taco Bell, 02 January 2013 - 16:08.

user posted image

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 03 January 2013 - 11:48

thanks for reply and happy new year taco.


OK, I modified the script and when compiling only one error was reported:

comma expected in 0hff325c4c9dbbb043b5b42d72e54eaaa4

but this is the reference when define the constant so whats the problem?

CODE

// Define Microsoft CSIDL constants for Vista
#define FOLDERID_SavedGames 0hff325c4c9dbbb043b5b42d72e54eaaa4

// Prototype SHGetKnownFolderPath in Shell32
prototype NUMBER shell32.SHGetKnownFolderPath( NUMBER, NUMBER, HWND, BYREF STRING);

nResult=shell32.SHGetKnownFolderPath( FOLDERID_SavedGames, 0, NULL, szPath);

if (nResult=0) then  
       MessageBox("CSIDL_COMMON_FAVORITES= "+szPath,0);
else
SprintfBox(SEVERE, "CSIDL_COMMON_FAVORITES", "Failed(%d): %s", nResult, FormatMessage(nResult));
endif;


Taco Bell

Taco Bell

    IS6 Expert

  • Moderators
  • 1,281 posts

Posted 03 January 2013 - 14:06

Well that new compile error is because that FOLDERID_SavedGames value appears to be a hexadecimal value, so it needs to be preceeded by "0x". However, according to the KNOWNFOLDERID documentation, it should actually be a GUID value of "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}".

Also, I looked into it further and that newer SHGetKnownFolderPath function call surprisingly doesn't have ANSI & Unicode counterparts, so you can ignore my previous suggestion.

Edited by Taco Bell, 03 January 2013 - 14:28.

user posted image

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 03 January 2013 - 16:25

QUOTE
Also, I looked into it further and that newer SHGetKnownFolderPath function call surprisingly doesn't have ANSI & Unicode counterparts, so you can ignore my previous suggestion.


Understood.

I looked MSDN documentation too and yes I need to set that GUID value but when you define this GUID value you need to enclose with quotes?

CODE

// Define Microsoft CSIDL constants for Vista
#define FOLDERID_SavedGames "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}"

// Prototype SHGetKnownFolderPath in Shell32
prototype NUMBER shell32.SHGetKnownFolderPath( NUMBER, NUMBER, HWND, BYREF STRING);

Edited by thanatos83, 03 January 2013 - 16:29.


Taco Bell

Taco Bell

    IS6 Expert

  • Moderators
  • 1,281 posts

Posted 04 January 2013 - 14:47

No, you do NOT need to enclose the GUID value when defining it which should also satisfy the calling funtion.
user posted image

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 04 January 2013 - 15:22

But a GUID with curly braces and dashes is not a NUMBER, right? I don't have a solution, just want to point out that you may need to adjust the prototype.

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 04 January 2013 - 15:27

Oh, and SHGetKnownFolderPath requires Windows Vista or above. If you also want to support XP you'd better call SHGetFolderPath which takes an INT parameter (CSIDL) to specify which folder you want to retrieve http://msdn.microsof...1(v=vs.85).aspx

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 04 January 2013 - 15:31

Okay, after re-reading the original post I noticed that you are looking for the saved games folder, which was introduced in Vista, so my previous comment about XP is obsolete smile.gif

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 04 January 2013 - 16:05

QUOTE
Oh, and SHGetKnownFolderPath requires Windows Vista or above. If you also want to support XP you'd better call SHGetFolderPath which takes an INT parameter (CSIDL) to specify which folder you want to retrieve http://msdn.microsof...1(v=vs.85).aspx


Thanks for suggestion about to support XP Stefan, I'll take in mind.

The first parameter in the prototype is NOT a number (you're right) because string variables passed to DLL functions are passed by reference. In that case I need to use that type of value: "BYREF STRING"

But when compiling there are errors related to character "{", unreconized character, etc..

Edited by thanatos83, 04 January 2013 - 16:08.


Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 08 January 2013 - 12:42

For the GUID to be a string you must include the "" in your define.
Maybe try and assign the contant to a variable, like this:

#define FOLDERID_SavedGames "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}"
szSavedGames = FOLDERID_SavedGames;

and then use szSavedGames in the first parameter.

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 09 January 2013 - 20:57

Thanks for your help, now the compiler not reports any errors. But when I install the product then an error is report like this:

Failed --> the system can not find the file specified.

CODE


// Define Microsoft GUID constant for Vista
#define FOLDERID_SavedGames "{4C5C32FF-BB9D-43b0-B5B4-2D72E54EAAA4}"

// Prototype SHGetKnownFolderPath in Shell32
prototype NUMBER Shell32.SHGetKnownFolderPath( BYREF STRING, NUMBER, HWND, BYREF STRING);

szSavedGames = FOLDERID_SavedGames;                    
nResult = Shell32.SHGetKnownFolderPath( szSavedGames, 0, NULL, szPath  );
if (nResult=0) then  
  MessageBox("FOLDERID_SavedGames= "+szPath,0);
else
 SprintfBox(SEVERE, "FOLDERID_SavedGames=", "Failed(%d): %s" nResult, FormatMessage(nResult));
endif;


I think the problem resides in the final parameter...

Edited by thanatos83, 10 January 2013 - 16:11.


Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 10 January 2013 - 18:52

Based on the error message, I would think the problem is the first parameter, still something wrong with that GUID. Did you run ProcessMonitor from SysInternals to see which file it tries to access?

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 11 January 2013 - 16:02

Hi.

Yes, so this is the result from Process Monitor... and only is filtered with file system activity and only setup.exe process.

I attached the image from process monitor but it seems the error points to a diferent path

Attached Images

  • screen.jpg

Edited by thanatos83, 11 January 2013 - 16:05.


Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 11 January 2013 - 17:45

So it actually doesn't try to access the path. Not sure what to recommend next.

You could try writing your own DLL to call the function, and then pass the result back to InstallShield. This would also help to find out if the problem is in InstallShield or in the parameters for the function call.

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 18 January 2013 - 08:30

Yep, so this not try to access but for xp this work well. I think the only problem is in the parameter.

I'll try that, thanks.

Stefan Krueger

Stefan Krueger

    InstallSite.org

  • Administrators
  • 13,269 posts

Posted 23 January 2013 - 19:22

It works on XP??? XP doesn#t have a saved games folder, so it shouldn't work on XP at all.

thanatos83

thanatos83
  • Full Members
  • 40 posts

Posted 23 January 2013 - 20:51

Sorry for my bad explain... In XP, I use this Knowledge base to take a path from a subfolder of Public folder as a reference:

Q111348: CODE: Find the Directory Where Internet Favorite Items Are Stored

Edited by thanatos83, 23 January 2013 - 20:58.