EDIT: Scotty2012 and David Morton’s answers don’t work for me so I have put a bounty on this question. I think I need to change the type of the string to something else before passing it in.
I’m not much cop at P/Invoke and I’m struggling with declaring and calling SHSetKnownFolderPath. I’m using VB9 but if anyone puts answers in C# I should be able to translate.
I have got SHGetKnowFolderPath working. Here is my code.
In VB
Imports System.Runtime.InteropServices Public Class Form1 <DllImport('shell32.dll')> _ Private Shared Function SHGetKnownFolderPath(<MarshalAs(UnmanagedType.LPStruct)> ByVal rfid As Guid, ByVal dwFlags As UInteger, ByVal hToken As IntPtr, ByRef pszPath As IntPtr) As Integer End Function <DllImport('shell32.dll')> _ Private Shared Function SHSetKnownFolderPath(<MarshalAs(UnmanagedType.LPStruct)> ByVal rfid As Guid, ByVal dwFlags As UInteger, ByVal hToken As IntPtr, ByRef pszPath As IntPtr) As Integer End Function Public Shared ReadOnly Documents As New Guid('FDD39AD0-238F-46AF-ADB4-6C85480369C7') Private Sub ButtonSetDocumentsPath_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSetDocumentsPath.Click Dim pPath As IntPtr = Marshal.StringToCoTaskMemUni(TextBoxPath.Text) If SHSetKnownFolderPath(Documents, 0, IntPtr.Zero, pPath) = 0 Then MsgBox('Set Sucessfully') End If End Sub Private Sub ButtonGetDocumentsPath_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonGetDocumentsPath.Click Dim pPath As IntPtr If SHGetKnownFolderPath(Documents, 0, IntPtr.Zero, pPath) = 0 Then Dim s As String = Marshal.PtrToStringUni(pPath) Marshal.FreeCoTaskMem(pPath) TextBoxPath.Text = s End If End Sub End Class
Thanks!
Try this code out. Sorry for the length, but it’s all needed to properly PInvoke this particular function. It’s a simple console application that includes a definition for both functions and an example usage of SHGetKnownFolderPath.
I went ahead and included the definitions for KNOWN_FOLDER_FLAG as well as a few definitions for the folder ID’s. All of the folder Id’s are actually just GUIDs. All of the possible ID’s can be found at %ProgramFiles%\Windows SDK\v6.0A\Include\KnownFolders.h and added in the same manner that I added in the sample.
I included several wrapper functions that hide all of the evil marashal’ing details for calling the particular functions.
If there is any particular folder id you’d like or explanation please add a comment and I’ll update the sample.
EDIT Corrected a mistake in the Marshalling of SHSetKnownFolderPath. I did not add a MarshalAs tag to the String value and it was defaulting to an ANSI string. The API required unicode. The SHSetFolderFunction now works (confirmed with RecentFolder)