Alaska Software Inc. - Get User Download Folder Path
Username: Password:
AuthorTopic: Get User Download Folder Path
Jonathan LeemingGet User Download Folder Path
on Mon, 30 Mar 2020 16:23:53 -0600
Hi,

Hope all are well as we work through the current crisis and we pull 
though to a brighter tomorrow.

In my application I refer to the users Document folder with Claytons 
function tdGetPCPath(nCSIDL) which does a couple of DLL calls to 
"SHGetSpecialFolderLocation" & "SHGetPathFromIDListA" and if nCISDL is 
0x0005 returns the "My Documents" path.

I was looking to get the user's Downloads folder by the same method but 
have found that there is no nCSIDL value for Downloads and that 
"SHGetSpecialFolderLocation" is deprecated and should be replaced with 
"SHGetFolderLocation" however this replacement still seems to be based 
upon a CSIDL value.  I have found reference to other functions that are 
based upon REFKNOWNFOLDERID where I believe that if I use a GUID of 
{FDD39AD0-238F-46AF-ADB4-6C85480369C7} it would give me the My Documents 
folder path and if I use {374DE290-123F-4565-9164-39C4925E467B} I would 
get the downloads folder path.

I have spent a fair bit of time trying to construct the DLL calls to get 
the desired results but I'm getting nowhere very slowly!

Does anyone have a function that would return the folder path based upon 
a passed GUID that they would consider sharing?

Thanks & Stay Well... Jonathan

jonathan.leeming@familycentre.org
Edmonton, Alberta, Canada
Jonathan LeemingRe: Get User Download Folder Path
on Tue, 31 Mar 2020 15:44:43 -0600
On 3/30/2020 4:23 PM, Jonathan Leeming wrote:
> Hi,
> 
> Hope all are well as we work through the current crisis and we pull 
> though to a brighter tomorrow.
> 
> In my application I refer to the users Document folder with Claytons 
> function tdGetPCPath(nCSIDL) which does a couple of DLL calls to 
> "SHGetSpecialFolderLocation" & "SHGetPathFromIDListA" and if nCISDL is 
> 0x0005 returns the "My Documents" path.
> 
> I was looking to get the user's Downloads folder by the same method but 
> have found that there is no nCSIDL value for Downloads and that 
> "SHGetSpecialFolderLocation" is deprecated and should be replaced with 
> "SHGetFolderLocation" however this replacement still seems to be based 
> upon a CSIDL value.  I have found reference to other functions that are 
> based upon REFKNOWNFOLDERID where I believe that if I use a GUID of 
> {FDD39AD0-238F-46AF-ADB4-6C85480369C7} it would give me the My Documents 
> folder path and if I use {374DE290-123F-4565-9164-39C4925E467B} I would 
> get the downloads folder path.
> 
> I have spent a fair bit of time trying to construct the DLL calls to get 
> the desired results but I'm getting nowhere very slowly!
> 
> Does anyone have a function that would return the folder path based upon 
> a passed GUID that they would consider sharing?
> 
> Thanks & Stay Well... Jonathan
> 
Hi Again,

In looking for a solution I decided to inspect Clayton's tdGetPCPath() 
and upon reviewing the Xbase++ docs for DllCall() found that it is being 
replaced with EXTERN so, with the objective of improving my 
understanding of dll calls decided to modify Clayton's function to use 
EXTERN instead of DllCall().  The replacement of the first DllCall() 
with EXTERN worked fine and the updated @pIDlist when passed to the 
original second DllCall() caused the @cPath to be updated so all is good 
(so far).  When I replaced the second DllCall() with EXTERN the @cPath 
does not get updated.

I have attached the modified version of Clayton's function with my 
changes if anyone would care to have a look and hopefully offer some 
guidance / suggestions.

I have been compiling/linking it in GUI mode.

Thanks... Jonathan


jonathan.leeming@familycentre.org
Edmonton, Alberta, Canada

getpath.prg
Andreas Gehrs-Pahl
Re: Get User Download Folder Path
on Wed, 01 Apr 2020 03:46:58 -0400
Jonathan,

>In looking for a solution I decided to inspect Clayton's tdGetPCPath() 
>and upon reviewing the Xbase++ docs for DllCall() found that it is being 
>replaced with EXTERN so, with the objective of improving my 
>understanding of dll calls decided to modify Clayton's function to use 
>EXTERN instead of DllCall().

Actually, the EXTERN pre-processor command replaces the DLLFUNCTION 
pre-processor command, not really the DllCall() function (despite what the 
documentation says).

>When I replaced the second DllCall() with EXTERN the @cPath does not get 
>updated.

The reason for this is that you forgot to pass the pszPATH parameter by 
reference -- you forgot the "@" in front of pszPATH -- in the EXTERN command 
in line 21.

Clayton's code doesn't use DLLFUNCTION and there is no need to specify call 
backs or special parameter types, so using the (much more straight forward 
and simpler) DllLoad() and DllCall() functions directly makes more sense.

Attached is a demo program that uses the SHGetKnownFolderPath -- implemented 
with both, DllCall() functions and the EXTERN command -- and should be 
pretty much what you want.

Hope this helps,

Andreas

Andreas Gehrs-Pahl
Absolute Software, LLC

phone: (989) 723-9927
email: Andreas@AbsoluteSoftwareLLC.com
web:   http://www.AbsoluteSoftwareLLC.com
[F]:   https://www.facebook.com/AbsoluteSoftwareLLC

GetKnownPath.zip
Jonathan LeemingRe: Get User Download Folder Path
on Wed, 01 Apr 2020 09:00:39 -0600
On 4/1/2020 1:46 AM, Andreas Gehrs-Pahl wrote:
> Jonathan,
> 
>> In looking for a solution I decided to inspect Clayton's tdGetPCPath()
>> and upon reviewing the Xbase++ docs for DllCall() found that it is being
>> replaced with EXTERN so, with the objective of improving my
>> understanding of dll calls decided to modify Clayton's function to use
>> EXTERN instead of DllCall().
> 
> Actually, the EXTERN pre-processor command replaces the DLLFUNCTION
> pre-processor command, not really the DllCall() function (despite what the
> documentation says).
> 
>> When I replaced the second DllCall() with EXTERN the @cPath does not get
>> updated.
> 
> The reason for this is that you forgot to pass the pszPATH parameter by
> reference -- you forgot the "@" in front of pszPATH -- in the EXTERN command
> in line 21.
> 
> Clayton's code doesn't use DLLFUNCTION and there is no need to specify call
> backs or special parameter types, so using the (much more straight forward
> and simpler) DllLoad() and DllCall() functions directly makes more sense.
> 
> Attached is a demo program that uses the SHGetKnownFolderPath -- implemented
> with both, DllCall() functions and the EXTERN command -- and should be
> pretty much what you want.
> 
> Hope this helps,
> 
> Andreas
> 
Hi Andreas,

Any Many Thanks!

At least I was not completely off the mark in my attempt... and yes, 
adding the "@" fixed the issue.  However I have since replaced that 
function with your code which now allows me to find any of the "newer" 
folders.  The 135 defines for the SHGetKnowFolderPath() are much 
appreciated.  As an interim measure I was using 
GetEnv("USERPROFILE")+"\Downloads" but obviously not the best approach!

Thanks yet again for your help!

Stay Well... Jonathan

jonathan.leeming@familycentre.org
Edmonton, Alberta, Canada