Author | Topic: Get User Download Folder Path | |
---|---|---|
Jonathan Leeming | Get 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 Leeming | Re: 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 Leeming | Re: 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 |