Попробуйте этот код. Извините за длину, но все это необходимо для правильной PInvoke этой конкретной функции. Это простое консольное приложение, которое включает определение для обеих функций и пример использования SHGetKnownFolderPath.
Я пошел дальше и включил определения для KNOWN_FOLDER_FLAG, а также несколько определений для идентификаторов папок. Все идентификаторы папок на самом деле просто GUID. Все возможные идентификаторы могут быть найдены в% ProgramFiles% \ Windows SDK \ v6.0A \ Include \ KnownFolders.h и добавлены так же, как я добавил в примере.
Я включил несколько функций-оболочек, которые скрывают все детали злого маршала для вызова определенных функций.
Если есть какой-либо конкретный идентификатор папки, который вы хотели бы или объяснение, пожалуйста, добавьте комментарий, и я обновлю образец.
EDIT Исправлена ошибка в Marshalling SHSetKnownFolderPath. Я не добавил тэг MarshalAs к значению String, и по умолчанию он представлял собой строку ANSI. Для API требуется Unicode. Функция SHSetFolder теперь работает (подтверждено с помощью RecentFolder)
Imports System.Runtime.InteropServices
Module NativeMethods
Public Enum KNOWN_FOLDER_FLAG
'''KF_FLAG_CREATE -> 0x00008000
KF_FLAG_CREATE = 32768
'''KF_FLAG_DONT_VERIFY -> 0x00004000
KF_FLAG_DONT_VERIFY = 16384
'''KF_FLAG_DONT_UNEXPAND -> 0x00002000
KF_FLAG_DONT_UNEXPAND = 8192
'''KF_FLAG_NO_ALIAS -> 0x00001000
KF_FLAG_NO_ALIAS = 4096
'''KF_FLAG_INIT -> 0x00000800
KF_FLAG_INIT = 2048
'''KF_FLAG_DEFAULT_PATH -> 0x00000400
KF_FLAG_DEFAULT_PATH = 1024
'''KF_FLAG_NOT_PARENT_RELATIVE -> 0x00000200
KF_FLAG_NOT_PARENT_RELATIVE = 512
'''KF_FLAG_SIMPLE_IDLIST -> 0x00000100
KF_FLAG_SIMPLE_IDLIST = 256
'''KF_FLAG_ALIAS_ONLY -> 0x80000000
KF_FLAG_ALIAS_ONLY = &H80000000
End Enum
Public ComputerFolder As Guid = New Guid("0AC0837C-BBF8-452A-850D-79D08E667CA7")
Public DesktopFolder As Guid = New Guid("B4BFCC3A-DB2C-424C-B029-7FE99A87C641")
Public DocumentsFolder As Guid = New Guid("FDD39AD0-238F-46AF-ADB4-6C85480369C7")
<DllImport("shell32.dll")> _
Public Function SHGetKnownFolderPath( _
ByRef folderId As Guid, _
ByVal flags As UInteger, _
ByVal token As IntPtr, _
<Out()> ByRef pathPtr As IntPtr) As Integer
End Function
<DllImport("shell32.dll")> _
Public Function SHSetKnownFolderPath( _
ByRef folderId As Guid, _
ByVal flags As UInteger, _
ByVal token As IntPtr, _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal path As String) As Integer
End Function
Public Function SHGetKnownFolderPathWrapper(ByVal folderId As Guid) As String
Return SHGetKnownFolderPathWrapper(folderId, 0)
End Function
Public Function SHGetKnownFolderPathWrapper( _
ByVal folderId As Guid, _
ByVal flags As KNOWN_FOLDER_FLAG) As String
Dim ptr = IntPtr.Zero
Dim path = String.Empty
Try
Dim ret = SHGetKnownFolderPath(folderId, CUInt(flags), IntPtr.Zero, ptr)
If ret <> 0 Then
Throw Marshal.GetExceptionForHR(ret)
End If
path = Marshal.PtrToStringUni(ptr)
Finally
Marshal.FreeCoTaskMem(ptr)
End Try
Return path
End Function
Public Sub SHSetKnownFolderPathWrapper( _
ByVal folderId As Guid, _
ByVal path As String)
SHSetKnownFolderPathWrapper(folderId, 0, path)
End Sub
Public Sub SHSetKnownFolderPathWrapper( _
ByVal folderId As Guid, _
ByVal flags As KNOWN_FOLDER_FLAG, _
ByVal path As String)
Dim ret = SHSetKnownFolderPath(folderId, CUInt(flags), IntPtr.Zero, path)
If ret <> 0 Then
Throw Marshal.GetExceptionForHR(ret)
End If
End Sub
End Module
Module Module1
Sub Main()
Dim path = SHGetKnownFolderPathWrapper(NativeMethods.DesktopFolder)
Console.WriteLine(path)
End Sub
End Module