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!