Tech Articles


Calling SHGetKnownFolderPath from PowerBuilder


Up through Windows XP, if you wanted to get the physical location of certain defined folders (e.g. the users Documents folder), you would use the SHGetFolderPath function in the Windows API.  Roland Smith has examples of using that on his Topwiz Software site.  That function continues to work in later versions of Windows, although it's basically a wrapper for the SHGetKnownFolderPath function.

SHGetFolderPath uses CSIDL values, whereas SHGetKnownFolderPath uses KnownFolderID GUIDs.  One difference is that there are a lot more KnownFolderIDs than there are CSIDLs.  That means some of the defined folder locations you may want to get the physical location for can't be accessed through the older SHGetFolderPath method.  And that's exactly the situation I ran into.


I needed to find the user's Downloads folder, and there isn't a CSIDL value for that.  So, I needed to see how to call the SHGetKnownFolderPath function from PowerBuilder.  As with many OLE and Windows API calls, it can save you a lot of time if you can find some Visual Basic code that does what you need to do, and you can convert the syntax.  And fortunately, I found some that did this.



So, with a little tweaking, I ended up with this:

//Local External Functions:

 Function Long CLSIDFromString (ref string lpszGuid, ref blob pGuid ) Library "ole32"   
 Function Long SHGetKnownFolderPath( ref blob nFolder,int dwFlags,uLong hToken , ref long pszPath) LIBRARY "Shell32.dll"   
 Subroutine CopyMemory ( ref String pDest, long pSrc, long ByteLen) Library "kernel32" Alias For "RtlMoveMemory"   
 Subroutine CoTaskMemFree ( long hMem) Library "ole32"   
 Function Long lstrlenW ( long ptr) Library "kernel32"   

//PowerScript

 blob     guid  
 long     ll_rc, ll_folderpointer, ll_folderlen  
 string ls_folder, ls_folder_id  
 ls_folder_id = '{374DE290-123F-4565-9164-39C4925E467B}'  
 IF CLSIDFromString (ls_folder_id, guid ) = 0 THEN  
      IF SHGetKnownFolderPath ( guid, 0, 0, ll_folderpointer ) = 0 THEN  
           IF ll_folderpointer <>0 THEN  
                ll_folderlen = lstrlenW ( ll_folderpointer )  
                If ll_folderlen <> 0 THEN  
                     ls_folder = Space ( ll_folderlen )                      
                     CopyMemory ( ls_folder, ll_folderpointer, ll_folderlen * 2 )  
                END IF  
           END IF  
           CoTaskMemFree ( ll_folderpointer )  
      END IF  
 END IF  
 MessageBox ( "Downloads Folder", ls_folder )  


Hope you find that useful as well.

 

 

 

 

 

 

Comments (1)
Tuesday, Sep 23 2025

I tried this with PB 2022 Build 1892 and it works the first time. The second call causes it to hang for a few seconds and then it aborts.

0

Find Articles by Tag

Web API PowerScript (PS) SOAP WinAPI PowerBuilder (Appeon) RibbonBar Builder Syntax Event Handler Debugging License JSONParser IDE ODBC RibbonBar Stored Procedure PostgreSQL Bug Excel Encryption Source Code BLOB OrcaScript PowerServer Web PBDOM CI/CD JSON JSONGenerator Azure Sort Database .NET Assembly Design Database Painter Linux OS Testing Repository DevOps Outlook Database Object iOS Performance SVN Migration PDFlib PFC Oracle Text Class TortoiseGit UI Themes Database Table InfoMaker Expression Database Connection Event Handling PBVM Interface TLS/SSL SnapDevelop PowerBuilder Compiler Debug Model Array SqlExecutor TFS Jenkins DLL Automated Testing Database Profile UI Modernization CoderObject SDK Trial Icon Import JSON Source Control Export JSON Resize Windows OS 64-bit Windows 10 Icons SQL Server .NET Std Framework GhostScript COM DragDrop Application WebBrowser SqlModelMapper Encoding Database Table Schema RESTClient DataWindow SQL PowerServer Mobile 32-bit File REST Elevate Conference Installation DataWindow JSON Git XML MessageBox Deployment PDF PostgreSQL ODBC driver Variable OAuth 2.0 Android ActiveX NativePDF Validation .NET DataStore Service External Functions Data Web Service Proxy OAuth CrypterObject Database Table Data Transaction Authentication Menu Configuration Graph UI Platform Messagging SnapObjects Window TreeView RichTextEdit Control C# DataType Error HTTPClient Authorization API Debugger Script Open Source PBNI Filter Import Event Export PowerBuilder Mobile OLE Visual Studio Branch & Merge Charts