wraithdu Posted March 6, 2008 Posted March 6, 2008 I'm trying to use DllCall for the SHGetKnownFolderPath (Vista only) function. I can't seem to get it to work. Here's the MSDN info - HRESULT SHGetKnownFolderPath( REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath ); I'm wondering if AutoIt doesn't have the right data type for 'rfid'. It's supposed to be the GUID reference for the folder location. I don't know how to pass this value. So here's what I got so far - Func _WinAPI_GetKnownFolderPath($nFolder, $dwFlags) $folder = DllCall("shell32.dll", "int", "SHGetKnownFolderPath", _ "str", $nFolder, _ "dword", $dwFlags, _ "ptr", "", _ "wstr", "" _ ) Return $folder[4] EndFunc Can anyone help? I've successfully got SHGetFolderPath working, but I want both versions.
PsaltyDS Posted March 7, 2008 Posted March 7, 2008 From MSDN: rfid [in] A reference to the KNOWNFOLDERID that identifies the folder. Since it's a reference, try "..."str*", $nFolder, ..." Can't test, because I am blissfully Vista free... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
wraithdu Posted March 7, 2008 Author Posted March 7, 2008 (edited) Sorry, but that didn't work Problem still is, I don't know what data type REFKNOWNFOLDERID is, or what the data is supposed to be exactly. Is it the GUID string, GUID binary data, with or without {}...where do I get that data or how do I convert it? Silly MSDN isn't much help... Edited March 7, 2008 by wraithdu
Moderators SmOke_N Posted March 7, 2008 Moderators Posted March 7, 2008 Sorry, but that didn't work Problem still is, I don't know what data type REFKNOWNFOLDERID is, or what the data is supposed to be exactly. Is it the GUID string, GUID binary data, with or without {}...where do I get that data or how do I convert it? Silly MSDN isn't much help...Try it as "int" and try 0 as the param first... Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.
PsaltyDS Posted March 7, 2008 Posted March 7, 2008 Sorry, but that didn't work Problem still is, I don't know what data type REFKNOWNFOLDERID is, or what the data is supposed to be exactly. Is it the GUID string, GUID binary data, with or without {}...where do I get that data or how do I convert it? Silly MSDN isn't much help...You can get a list of them and see. According to MSDN, you can use the IKnownFolderManager::GetFolderIds method to get a list. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
wraithdu Posted March 7, 2008 Author Posted March 7, 2008 (edited) Thanks, but I don't need a list of the FOLDERIDs, I have the list of GUIDs already. I don't know what data TYPE I'm supposed to pass to the function. I think it's supposed to be a GUID type, but AutoIt doesn't seem to support it. BTW, NSIS's System plugin does support the GUID data type, but I can't get this darn function to work in NSIS either. @SmOke_N The function crashes if the input data type is an int, ptr, or dword. str and wstr don't crash, but it doesn't work either. The return value is some crazy number. It should be 0 if it's successful. Edited March 7, 2008 by wraithdu
PsaltyDS Posted March 8, 2008 Posted March 8, 2008 Thanks, but I don't need a list of the FOLDERIDs, I have the list of GUIDs already. I don't know what data TYPE I'm supposed to pass to the function. I think it's supposed to be a GUID type, but AutoIt doesn't seem to support it. BTW, NSIS's System plugin does support the GUID data type, but I can't get this darn function to work in NSIS either. @SmOke_N The function crashes if the input data type is an int, ptr, or dword. str and wstr don't crash, but it doesn't work either. The return value is some crazy number. It should be 0 if it's successful. Hmm... well, this generates a GUID, and the GUID it generates is a string: $TypeLib = ObjCreate("Scriptlet.TypeLib") $GUID = $TypeLib.Guid ConsoleWrite("Debug: $GUID = " & $GUID & " Type = " & VarGetType($GUID) & @LF)oÝ÷ ØƲmëaz"׫Ûø¬¶Þ¥«,yÖ®¶sbb33cµ7G'V7DuTBÒFÆÅ7G'V7D7&VFRgV÷C¶6"uTE³3ÒgV÷C²¢b33cµGTÆ"Òö&¤7&VFRgV÷Cµ67&FÆWBåGTÆ"gV÷C²¢b33c´uTBÒb33cµGTÆ"äwV@¤6öç6öÆUw&FRgV÷C´FV'Vs¢b33c´uTBÒgV÷C²fײb33c´uTBfײgV÷C²GRÒgV÷C²fײf$vWEGRb33c´uTBfײgV÷C²ÆVâÒgV÷C²fײ7G&ætÆVâb33c´uTBfײÄb¤FÆÅ7G'V7E6WDFFb33cµ7G'V7DuTBÂgV÷C´uTBgV÷C²Âb33c´uTB¢b33c·G$uTBÒFÆÅ7G'V7DvWEG"b33cµ7G'V7DuTBÂgV÷C´uTBgV÷C² ¢b33c¶föÆFW"ÒFÆÄ6ÆÂgV÷C·6VÆÃ3"æFÆÂgV÷C²ÂgV÷C¶çBgV÷C²ÂgV÷Cµ4vWD¶æ÷väföÆFW%FgV÷C²Âð gV÷C·G"gV÷C²Âb33c·G$uTBÂð gV÷C¶Gv÷&BgV÷C²ÂÂð gV÷C·G"gV÷C²ÂgV÷C²gV÷C²Âð gV÷C·w7G"gV÷C²ÂgV÷C²gV÷C² I'm guessing a lot now though, so feel free to ignore it... Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
wraithdu Posted March 8, 2008 Author Posted March 8, 2008 Nice bit of code! I'll probably have to remember some of that in the future. But alas, no luck. As I said above, passing a ptr to the function in param 1 crashes it, return code -1073741819. It only accepts the str and wstr data types as far as I can tell.
wraithdu Posted March 8, 2008 Author Posted March 8, 2008 Ok, I'm 90% of the way there! I finally figured out how to pass the correct GUID structure (thanks to kichik and others at NSIS for the hints). Here's the working code I have so far - #include <WinAPI.au3> $tagstruct = DllStructCreate($tagGUID) $tagptr = DllStructGetPtr($tagstruct) _WinAPI_GUIDFromStringEx("{8983036C-27C0-404B-8F08-102D10DCFD74}", $tagptr) $folder = DllCall("shell32.dll", "int", "SHGetKnownFolderPath", _ "ptr", $tagptr, _ "dword", 0x1000, _ "int", "", _ "ptr*", "" _ ) ConsoleWrite("returncode = " & $folder[0] & @CRLF & "outaddr = " & $folder[4] & @CRLF) DllCall("ole32.dll", "none", "CoTaskMemFree", _ "ptr", $folder[4] _ ) So the output here is the address to the pointer that contains the unicode path. How can I read this data? I can't use DllStructGetData cause I don't have a struct to read. I tried creating one ahead of time, but the function won't write to it. It would just write the pointer address anyway. So how do I read memory where I just have the pointer address?
wraithdu Posted March 8, 2008 Author Posted March 8, 2008 Finally!!! #include <WinAPI.au3> $tagstruct = DllStructCreate($tagGUID) $tagptr = DllStructGetPtr($tagstruct) _WinAPI_GUIDFromStringEx("{8983036C-27C0-404B-8F08-102D10DCFD74}", $tagptr) $folder = DllCall("shell32.dll", "int", "SHGetKnownFolderPath", _ "ptr", $tagptr, _ "dword", 0x1000, _ "int", "", _ "ptr*", "" _ ) $len = DllCall("kernel32.dll", "int", "lstrlenW", _ "ptr", $folder[4] _ ) $pathstruct = DllStructCreate("wchar[" & $len[0] & "]") $pathptr = DllStructGetPtr($pathstruct) $path = DllCall("kernel32.dll", "int", "lstrcpyW", _ "ptr", $pathptr, _ "ptr", $folder[4] _ ) ConsoleWrite("returncode = " & $folder[0] & @CRLF & "outaddr = " & $folder[4] & @CRLF) ConsoleWrite("path len = " & $len[0] & @CRLF & "path = " & DllStructGetData($pathstruct, 1) & @CRLF) DllCall("ole32.dll", "none", "CoTaskMemFree", _ "ptr", $folder[4] _ ) Now, is there an easier way to do this? LOL
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now