Help to find AppData for W8 (vista, Win7...)

BlitzMax Forums/BlitzMax Programming/Help to find AppData for W8 (vista, Win7...)

Pingus(Posted 2015) [#1]
Since several years, I use this to retrieve the AppData folder for saving customer's datas:

Const	CSIDL_APPDATA		= $1a
Const CSIDL_COMMON_APPDATA = $23
Global	appdata_path_ptr:Byte Ptr, files_path$

Extern "win32"
	Function SHGetFolderPathA(hWnd:Int, folder:Int, token:Int, FLAGS:Int, str:Byte Ptr)
End Extern
GetAppDataFolder()
Function GetAppDataFolder()
	Local res, dir, cnt

		appdata_path_ptr = New Byte[260]
	
		res = SHGetFolderPathA(Null, CSIDL_APPDATA, Null, 1, appdata_path_ptr)
		cnt = 0
		While (appdata_path_ptr[cnt] <> 0)
			cnt :+ 1
		Wend
		files_path$ = String.FromBytes(appdata_path_ptr, cnt)
	
		files_path$ :+ "/" + AppName$	
		Print files_path$				
EndFunction


So far, it worked quite fine and none of our working PCs showed any issue about this, whatever the OS (XP, Vista, W7,W8...)

However, some users reported issues that I can not explain,but that *could* be explained if for any reason SHGetFolderPathA would return a wrong or random (?!) pathes.

I had read here that SHGetFolderPathA is deprecated since Vista, so it would probably be better to use SHGetKnownFolderPath (for Vista and so on).

Grey Alien generously posted a while ago some C++ code for this.

http://www.blitzbasic.com/Community/posts.php?topic=98999#1162256

But I am a total noob about C++ and can not understand nor use that post.

There should be a way to 'convert' this

HRESULT SHGetKnownFolderPath(
_In_ REFKNOWNFOLDERID rfid,
_In_ DWORD dwFlags,
_In_opt_ HANDLE hToken,
_Out_ PWSTR *ppszPath
);

Into bmax code like above for SHGetFolderPathA:

(from there : https://msdn.microsoft.com/en-us/library/windows/desktop/bb762188%28v=vs.85%29.aspx)

Unfortunatly I have not even the beginning of a clue about how to write something like a "rfid" variable or "*ppszPath" or all that mysterious things that Windows Apis requires.

Any help is welcome.


Brucey(Posted 2015) [#2]
Until it's been removed from the APIs, SHGetFolderPath should work as expected.

Maybe you should be using the W variant of it instead - use of the A version is not Unicode friendly.


*(Posted 2015) [#3]
Why not use System drive \users\ {username} \ AppData ?

As long as you can get the username from windows of the currently active user its normally in for example C:\Users\{username}\AppData


Brucey(Posted 2015) [#4]
Why not use System drive \users\ {username} \ AppData ?

Which isn't compatible with all the OS's he listed.

That's why they invented APIs.


*(Posted 2015) [#5]
Weird its the same place on vista/7/8 here


Derron(Posted 2015) [#6]
Weird its the same place on vista/7/8 here


You perfectly described for what APIs are existing...

bye
Ron


*(Posted 2015) [#7]
Didn't max have a AppData function?


Derron(Posted 2015) [#8]
I don't think so. Max only has an AppPath-function (returning the path to the currently executed binary dir).


bye
Ron


Brucey(Posted 2015) [#9]
One could always use the cross-platform BaH.Volumes module to do it properly (via APIs)...


grable(Posted 2015) [#10]
You could use the APPDATA environment variable which is in XP and up.


Pingus(Posted 2015) [#11]
APPDATA environment variable does not look reliable and may be changed at runtime by other programs.

As far as I see, BaH.Volumes is using SHGetFolderPath so I do not see in what it would be different from my simple code for that use.

According to that page, a develloper is experimenting random path from SHGetFolderPath :

https://social.msdn.microsoft.com/Forums/vstudio/en-US/c63c0246-22eb-4bc2-9062-ec03627c6bc8/issue-with-shgetfolderpath-and-csidlappdata-under-windows-7?forum=vcgeneral

Microsoft guru answer:

There is another file access virtualization in effect if you are running a 32bit app on 64bit windows.

(which I guess is exactly what's happening with many users nowadays)

Dev answer:

After investigating this issue, it looks like this issue is due to something Internet Explorer is doing. The correct way is to use the newer API, HGetKnownFolderPath(), instead of the legacy SHGetFolderPath().


Brucey(Posted 2015) [#12]
BaH.Volumes uses either SHGetKnownFolderPath or SHGetFolderPath depending on which is available, preferring SHGetKnownFolderPath.


Pingus(Posted 2015) [#13]
Ah ?
Great news !
Thanks Brucey, you are my saver :-) (one more time).


Pingus(Posted 2015) [#14]
Hmm, sorry to be a pain... but is that link include the right module ?

https://maxmods.googlecode.com/files/volumes_1_07_src.zip

I can not see any SHGetKnownFolderPath in theses files.


Brucey(Posted 2015) [#15]
Unfortunately, google are winding down googlecode, so uploading new downloads hasn't worked for a while, and soon the whole of googlecode will be disappearing too.

However, the latest source can be seen here :

https://github.com/maxmods/bah.mod/tree/master/volumes.mod


GfK(Posted 2015) [#16]
Here's what I use, works for Windows and OSX:

Bit of a Frankenstein's monster - I wrote some bits, other people wrote other bits. Dunno. Credit to whoever.


BlitzSupport(Posted 2015) [#17]
There's this too:

Get Windows 'special folder' paths

... oh, and this:

Save settings to correct location on Windows


Pingus(Posted 2015) [#18]
Load of things to check.
The github volume module from Brucey contain the hoped SHGetKnownFolderPath, I will try to work with that in a first step althought GFK version seems short and more simple.

Thanks guys!


GfK(Posted 2015) [#19]
For what it's worth, I've used that code in over 50 products and never encountered a single problem.