Marshalling

 









  1. Option Strict On
  2. Imports System.Runtime.InteropServices

  3. Module Program
  4.     Declare Unicode Sub BeginTest Lib ".\..\..\..\..\..\x64\Debug\Dll_ForMarshalling.dll" (
  5.                    str As String, FunSelector As Int32)
  6.     Declare Unicode Sub Get_TestData Lib ".\..\..\..\..\..\x64\Debug\Dll_ForMarshalling.dll" (
  7.        <InAttribute(), OutAttribute(), MarshalAs(UnmanagedType.LPWStr)> ByRef str As Text.StringBuilder, nMAxCount As Int32)
  8.     Sub Main(args As String())
  9.         For ii As Int32 = 1 To 1

  10.             Known_Folder_Desktop()
  11.             If (ii <= 1) Then Console.ReadKey()

  12.             Dim stringbuilder As New Text.StringBuilder(4 << 20)
  13.             BeginTest(" Desktop ", 1)
  14.             Get_TestData(stringbuilder, stringbuilder.Capacity)
  15.             OUTPUT2(stringbuilder.ToString)
  16.             If (ii <= 1) Then Console.ReadKey()

  17.             Console.WriteLine("=== KnownFolderManager ===")
  18.             KnownFolderManager()
  19.             Console.WriteLine("=== KnownFolderManager ====")
  20.             If (ii <= 1) Then Console.ReadKey()

  21.             Dim stringbuilder2 As New Text.StringBuilder(4 << 20)
  22.             BeginTest(" KnownFolder_Manager ", 2)
  23.             Get_TestData(stringbuilder2, stringbuilder2.Capacity)
  24.             OUTPUT2(stringbuilder2.ToString)
  25.             If (ii <= 1) Then Console.ReadKey()
  26.         Next ii

  27.         Console.Write("Press any key to exit") : Console.ReadKey()
  28.     End Sub
  29.     Public ReadOnly FolderId_Desktop_guid As New Guid(FolderId_Desktop)
  30.     Sub Known_Folder_Desktop()
  31.         Try
  32.             Dim Hresult As Int32
  33.             Hresult = SHGetKnownFolderPath(FolderId_Desktop_guid,
  34.                       0, Null,
  35.                       KnownFolderPath)
  36.             If Hresult <> S_OK Then
  37.                 OUTPUT2($"error: SHGetKnownFolderPath == {FolderId_Desktop_guid} {Hresult:X} ")
  38.             Else
  39.                 OUTPUT2("SHGetKnownFolderPath ==> " & KnownFolderPath)
  40.             End If
  41.             Dim ptr_IDList As IntPtr
  42.             Hresult = SHGetKnownFolderIDList(FolderId_Desktop_guid,
  43.                       0, Null,
  44.                       ptr_IDList)
  45.             If Hresult <> S_OK Then
  46.                 OUTPUT2($"error1: SHGetKnownFolderIDList  {Hresult:x}")
  47.             Else
  48.                 Hresult = SHGetNameFromIDList(ptr_IDList, SIGDN.SIGDN_URL, URL_Path)
  49.                 If Hresult <> S_OK Then
  50.                     OUTPUT2($"error2: SHGetNameFromIDList {Hresult:x}")
  51.                 Else
  52.                     ILFree(ptr_IDList)
  53.                     OUTPUT2("URL_Path ======> " & URL_Path)
  54.                 End If
  55.             End If
  56.             Hresult = SHGetKnownFolderItem(FolderId_Desktop_guid, 0, Null,
  57.                        New Guid(IID_IShellItem), pIShellItem_Obj)
  58.             Dim pIShellItem As IShellItem = CType(pIShellItem_Obj, IShellItem)

  59.             pIShellItem.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, pName_NormalDisplay)
  60.             pIShellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, pName_FileSysPATH)
  61.             OUTPUT2($"Name  : {pName_NormalDisplay}")
  62.             OUTPUT2($"Name  : {pName_FileSysPATH}")

  63.             Dim pIShellItem2 As IShellItem2 = CType(pIShellItem, IShellItem2)
  64.             pIShellItem2.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, pName2_NormalDisplay)
  65.             pIShellItem2.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, pName2_FileSysPATH)
  66.             OUTPUT2($"Name2 : {pName2_NormalDisplay}")
  67.             OUTPUT2($"Name2 : {pName2_FileSysPATH}")
  68.         Catch ex As Exception
  69.             Console.WriteLine($"Exception:{ex.Message}(hr={ex.HResult:x})")
  70.             Console.Beep() : Console.ReadKey()
  71.         End Try
  72.     End Sub
  73.     Sub KnownFolderManager()
  74.         Dim CLSCTX_INPROC_SERVER As UInt32 = &H1
  75.         Dim pIUnknown As IUnKnown = Nothing
  76.         Dim pManager As IKnownFolderManager = Nothing
  77.         Dim hr As Int32 = CoCreateInstance(New Guid(CLSID_KnownFolderManager), Null,
  78.             CLSCTX_INPROC_SERVER, New Guid(IID_IKnownFolderManager),
  79.             pIUnknown)
  80.         If hr = S_OK Then
  81.             pManager = CType(pIUnknown, IKnownFolderManager)
  82.             Dim CountOfFolderIds As UInteger = 0
  83.             Dim ptr_kfids As IntPtr
  84.             pManager.GetFolderIds(ptr_kfids, CountOfFolderIds)
  85.             For ii As Int32 = 0 To CInt(CountOfFolderIds - 1)
  86.                 Dim pIKnownFolder_obj As Object = Nothing
  87.                 Dim pIKnownFolder As IKnownFolder
  88.                 Dim pIShellItem_Obj As Object = Nothing
  89.                 Dim pIShellItem As IShellItem
  90.                 Try
  91.                     Dim KnownFolderId As Guid = Marshal.PtrToStructure(Of Guid)(
  92.                         ptr_kfids + (ii * Marshal.SizeOf(Of Guid)()))
  93.                     pManager.GetFolder(KnownFolderId, pIKnownFolder_obj)
  94.                     pIKnownFolder = CType(pIKnownFolder_obj, IKnownFolder)
  95.                     Console.Write("{0,3:d}:", ii + 1)

  96.                     pIKnownFolder.GetShellItem(0, New Guid(IID_IShellItem), pIShellItem_Obj)
  97.                     pIShellItem = CType(pIShellItem_Obj, IShellItem)
  98.                     Dim pwstr As String = Nothing
  99.                     pIShellItem.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, pwstr)
  100.                     If pwstr IsNot Nothing Then
  101.                         Console.Write("{0} ===>", pwstr)
  102.                     End If
  103.                     Dim pwstr2 As String = Nothing
  104.                     pIShellItem.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, pwstr2)
  105.                     Console.Write("  {0:123,S}", pwstr2)
  106.                 Catch ex As Exception
  107.                     'Console.Write(ex.HResult.ToString("x") & "  " & ex.Message)
  108.                 End Try
  109.                 Console.WriteLine()
  110.             Next ii
  111.             CoTaskMemFree(ptr_kfids)
  112.         End If
  113.     End Sub
  114.     Sub OUTPUT2(str As String)
  115.         Console.WriteLine("{0}", str)
  116.     End Sub
  117.     Dim pIShellItem_Obj As Object
  118.     Dim pIShellItem2_Obj As Object
  119.     Dim URL_Path As String
  120.     Dim KnownFolderPath As String
  121.     Dim pName_NormalDisplay As String
  122.     Dim pName_FileSysPATH As String
  123.     Dim pName2_NormalDisplay As String
  124.     Dim pName2_FileSysPATH As String

  125.     Declare Unicode Function SHGetKnownFolderItem Lib "Shell32" (
  126.        <InAttribute(), MarshalAs(UnmanagedType.LPStruct)> REF_KNOWN_FOLDER_ID As Guid,
  127.         _In_KNOWN_FOLDER_FLAG_flags As UInt32,
  128.         _In_opt_HANDLE_hToken As IntPtr,
  129.        <MarshalAs(UnmanagedType.LPStruct)> REF_IID_riid As Guid,
  130.        <Out(), MarshalAs(UnmanagedType.Interface)> ByRef _Outptr_void_ppv As Object) As Int32

  131.     Declare Unicode Function SHGetKnownFolderIDList Lib "Shell32.dll" (
  132.      <MarshalAs(UnmanagedType.LPStruct)> REF_KNOWN_FOLDER_ID_As_Guid As Guid,
  133.       KNOWN_FOLDER_FLAG As UInt32,
  134.       In_opt_hToken As IntPtr,
  135.      <Out()> ByRef ABSOLUTE_ppidl As IntPtr) As Int32

  136.     Declare Unicode Function SHGetNameFromIDList Lib "Shell32.dll" (
  137.          In_PCIDLIST_ABSOLUTE_pidl As IntPtr,
  138.          _In_SIGDN As SIGDN,
  139.       <Out()> ByRef _Outptr_PWSTR_ppszName As String) As Int32

  140.     Declare Unicode Function SHGetKnownFolderPath Lib "Shell32.dll" (
  141.         <MarshalAs(UnmanagedType.LPStruct)> REF_KNOWN_FOLDER_ID_As_Guid As Guid,
  142.         KNOWN_FOLDER_FLAG As UInt32,
  143.         In_opt_hToken As IntPtr,
  144.       <Out> ByRef Outptr_ppszPath As String) As Int32

  145.     Declare Unicode Function GetConsoleCP Lib "Kernel32.dll" () As UInt32
  146.     Declare Sub CoTaskMemFree Lib "Ole32" (_Frees_ptr_opt_LPVOID_pv As IntPtr)
  147.     Declare Sub ILFree Lib "shell32" (_In_opt_PIDLIST_RELATIVE_pidl As IntPtr)
  148.     Declare Unicode Function CoInitializeEx Lib "Ole32" (
  149.                _In_opt_LPVOID_pvReserved As IntPtr,
  150.                _In_DWORD_dwCoInit As UInt32) As Int32
  151.     Declare Sub CoUninitialize Lib "Ole32" ()
  152.     Declare Function OleInitialize Lib "Ole32" (In_LPVOID_pvReserved As IntPtr) As Int32
  153.     Declare Sub OleUninitialize Lib "Ole32" ()
  154.     Declare Unicode Function CoCreateInstance Lib "Ole32" (
  155.       <MarshalAs(UnmanagedType.LPStruct)> _In_REFCLSID_rclsid As Guid,
  156.                                           _In_opt_LPUNKNOWN_pUnkOuter As IntPtr,
  157.                                           _In_DWORD_dwClsContext As UInt32,
  158.       <MarshalAs(UnmanagedType.LPStruct)> _In_REFIID_riid As Guid,
  159.       <Out, MarshalAs(UnmanagedType.Interface)> ByRef COM_Outptr As IUnKnown) As Int32
  160.     '_Check_return_ WINOLEAPI CoCreateInstance(
  161.     '_In_ REFCLSID rclsid,
  162.     '_In_opt_ LPUNKNOWN pUnkOuter,
  163.     '_In_ DWORD dwClsContext,
  164.     '_In_ REFIID riid,
  165.     '_COM_Outptr_ _At_(* ppv, _Post_readable_size_(_Inexpressible_(varies))) LPVOID  FAR * ppv);

  166.     Public Const IID_IUnknown As String = "00000000-0000-0000-C000-000000000046"
  167.     <ComImport,
  168.      InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
  169.      Guid(IID_IUnknown)>
  170.     Public Interface IUnKnown
  171.         Sub QueryInterface(
  172.             ByRef REFIID_riid As Guid,
  173.             <Out, MarshalAs(UnmanagedType.Interface)> ByRef COM_Outptr_ As Object)
  174.         Function AddRef() As UInt32
  175.         Function Release() As UInt32
  176.     End Interface

  177.     Public Const IID_IShellItem As String = "43826d1e-e718-42ee-bc55-a1e261c37bfe"
  178.     <ComImport,
  179.      Guid(IID_IShellItem),
  180.      InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
  181.      >
  182.     Public Interface IShellItem : Inherits IUnKnown
  183.         Sub BindToHandler()
  184.         ' virtual HRESULT STDMETHODCALLTYPE BindToHandler( 
  185.         '  /* [unique][in] */ __RPC__in_opt IBindCtx *pbc,
  186.         '  /* [in] */ __RPC__in REFGUID bhid,
  187.         '  /* [in] */ __RPC__in REFIID riid,
  188.         '  /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  189.         Sub GetParent()
  190.         ' virtual HRESULT STDMETHODCALLTYPE GetParent( 
  191.         ' /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
  192.         Sub GetDisplayName(sigdn As SIGDN,
  193.             <MarshalAs(UnmanagedType.LPWStr)> ByRef ppszName As String)
  194.         ' virtual HRESULT STDMETHODCALLTYPE GetDisplayName( 
  195.         '   /* [in] */ SIGDN sigdnName,
  196.         '   /* [annotation][string][out] */ 
  197.         '   _Outptr_result_nullonfailure_  LPWSTR *ppszName) = 0;
  198.         Sub GetAttributes()
  199.         '   virtual HRESULT STDMETHODCALLTYPE GetAttributes( 
  200.         '   /* [in] */ SFGAOF sfgaoMask,
  201.         '   /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0;
  202.         Sub Compare()
  203.         'virtual HRESULT STDMETHODCALLTYPE Compare( 
  204.         '    /* [in] */ __RPC__in_opt IShellItem *psi,
  205.         '    /* [in] */ SICHINTF hint,
  206.         '    /* [out] */ __RPC__out int *piOrder) = 0;
  207.     End Interface

  208.     Public Const IID_IShellItem2 As String = "7e9fb0d3-919f-4307-ab2e-9b1860310c93"
  209.     <ComImport,
  210.      InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
  211.      Guid(IID_IShellItem2)>
  212.     Interface IShellItem2 : Inherits IShellItem
  213.         Sub GetPropertyStore()
  214.         ' /* [in] */ GETPROPERTYSTOREFLAGS flags,
  215.         ' /* [in] */ __RPC__in REFIID riid,
  216.         ' /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  217.         Sub GetPropertyStoreWithCreateObject()
  218.         ' /* [in] */ GETPROPERTYSTOREFLAGS flags,
  219.         ' /* [in] */ __RPC__in_opt IUnknown *punkCreateObject,
  220.         ' /* [in] */ __RPC__in REFIID riid,
  221.         ' /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  222.         Sub GetPropertyStoreForKeys()
  223.         ' /* [size_is][in] */ __RPC__in_ecount_full(cKeys) const PROPERTYKEY *rgKeys,
  224.         ' /* [in] */ UINT cKeys,
  225.         ' /* [in] */ GETPROPERTYSTOREFLAGS flags,
  226.         ' /* [in] */ __RPC__in REFIID riid,
  227.         ' /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  228.         Sub GetPropertyDescriptionList()
  229.         '/* [in] */ __RPC__in REFPROPERTYKEY keyType,
  230.         '/* [in] */ __RPC__in REFIID riid,
  231.         '/* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  232.         Sub Update()
  233.         '/* [unique][in] */ __RPC__in_opt IBindCtx *pbc) = 0;
  234.         Sub GetProperty()
  235.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  236.         '/* [out] */ __RPC__out PROPVARIANT *ppropvar) = 0;
  237.         Sub GetCLSID()
  238.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  239.         '/* [out] */ __RPC__out CLSID *pclsid) = 0;
  240.         Sub GetFileTime()
  241.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  242.         '/* [out] */ __RPC__out FILETIME *pft) = 0;
  243.         Sub GetInt32()
  244.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  245.         '/* [out] */ __RPC__out int *pi) = 0;
  246.         Sub GetString()
  247.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  248.         '/* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppsz) = 0;

  249.         Sub GetUInt32()
  250.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  251.         '/* [out] */ __RPC__out ULONG *pui) = 0;

  252.         Sub GetUInt64()
  253.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  254.         '/* [out] */ __RPC__out ULONGLONG *pull) = 0;

  255.         Sub GetBool()
  256.         '/* [in] */ __RPC__in REFPROPERTYKEY key,
  257.         '/* [out] */ __RPC__out BOOL *pf) = 0;
  258.     End Interface

  259.     Enum SIGDN As Int32
  260.         SIGDN_NORMALDISPLAY = 0
  261.         SIGDN_PARENTRELATIVEPARSING = CType(&H80018001, Int32)
  262.         SIGDN_DESKTOPABSOLUTEPARSING = CType(&H80028000, Int32)
  263.         SIGDN_PARENTRELATIVEEDITING = CType(&H80031001, Int32)
  264.         SIGDN_DESKTOPABSOLUTEEDITING = CType(&H8004C000, Int32)
  265.         SIGDN_FILESYSPATH = CType(&H80058000, Int32)
  266.         SIGDN_URL = CType(&H80068000, Int32)
  267.         SIGDN_PARENTRELATIVEFORADDRESSBAR = CType(&H8007C001, Int32)
  268.         SIGDN_PARENTRELATIVE = CType(&H80080001, Int32)
  269.         SIGDN_PARENTRELATIVEFORUI = CType(&H80094001, Int32)
  270.     End Enum

  271.     Public Const FolderId_Desktop As String = "B4BFCC3A-DB2C-424C-B029-7FE99A87C641"
  272.     Public Const FolderId_RoamingAppData As String = "3EB685DB-65F9-4CF6-A03A-E3EF65729F3D"
  273.     Public Const FolderId_LocalAppData As String = "F1B32785-6FBA-4FCF-9D55-7B8E7F157091"
  274.     Public Const FolderId_LocalAppDataLow As String = "A520A1A4-1780-4FF6-BD18-167343C5AF16"
  275.     Public Const FolderId_NetworkFolder As String = "D20BEEC4-5CA8-4905-AE3B-BF251EA09B53"
  276.     Public Const FolderId_ComputerFolder As String = "0AC0837C-BBF8-452A-850D-79D08E667CA7"
  277.     Public Const FolderId_InternetFolder As String = "4D9F7874-4E0C-4904-967B-40B0D20C3E4B"
  278.     Public Const FolderId_System As String = "1AC14E77-02E7-4E5D-B744-2EB1AE5198B7"
  279.     Public Const FolderId_Documents As String = "FDD39AD0-238F-46AF-ADB4-6C85480369C7"
  280.     Public Const FolderId_Windows As String = "F38BF404-1D43-42F2-9305-67DE0B28FC23"
  281.     Public Const FolderId_Downloads As String = "374DE290-123F-4565-9164-39C4925E467B"

  282.     Public Const CLSID_ShellWindows As String = "9BA05972-F6A8-11CF-A442-00A0C90A8F39"
  283.     Public Const IID_IShellWindows As String = "85CB6900-4D95-11CF-960C-0080C7F4EE85"
  284.     Public Const CLSID_ShellItem As String = "9ac9fbe1-e0a2-4ad6-b4ee-e212013ea917"
  285.     Public Const IID_IExplorerBrowser As String = "dfd3b6b5-c10c-4be9-85f6-a66969f402f6"
  286.     Public ReadOnly Null As IntPtr = IntPtr.Zero
  287.     Public Const S_OK As Int32 = 0
  288.     Public Const S_FALSE As Int32 = 1
  289.     Public Const E_NOINTERFACE As Int32 = &H80004002I
  290.     Enum COINITBASE As UInt32
  291.         COINITBASE_MULTITHREADED = 0     ' // OLE calls objects On any thread.
  292.     End Enum
  293.     Enum COINIT As UInt32
  294.         COINIT_APARTMENTTHREADED = 2 '     // Apartment model
  295.         COINIT_MULTITHREADED = COINITBASE.COINITBASE_MULTITHREADED
  296.         COINIT_DISABLE_OLE1DDE = 4
  297.         COINIT_SPEED_OVER_MEMORY = 8
  298.     End Enum
  299.     Public Const CLSID_KnownFolderManager As String = "4df0c730-df9d-4ae3-9153-aa6b82e9795a"

  300.     Public Const IID_IKnownFolderManager As String = "8BE2D872-86AA-4d47-B776-32CCA40C7018"
  301.     <ComImport,
  302.     InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
  303.     Guid(IID_IKnownFolderManager)>
  304.     Interface IKnownFolderManager : Inherits IUnKnown
  305.         Sub FolderIdFromCsidl()
  306.         '       /* [in] */ int nCsidl,
  307.         '       /* [out] */ __RPC__out KNOWNFOLDERID *pfid) = 0;
  308.         Sub FolderIdToCsidl()
  309.         '   virtual HRESULT STDMETHODCALLTYPE FolderIdToCsidl( 
  310.         '       /* [in] */ __RPC__in REFKNOWNFOLDERID rfid,
  311.         '       /* [out] */ __RPC__out int *pnCsidl) = 0;
  312.         Sub GetFolderIds(
  313.           <Out> ByRef pKnownFolderId As IntPtr,
  314.           <InAttribute> <Out> ByRef count As UInt32)
  315.         '   virtual HRESULT STDMETHODCALLTYPE GetFolderIds( 
  316.         '  /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*pCount) KNOWNFOLDERID **ppKFId,
  317.         '  /* [out][in] */ __RPC__inout UINT *pCount) = 0;
  318.         Sub GetFolder(
  319.         <MarshalAs(UnmanagedType.LPStruct)> REFKNOWNFOLDERID As Guid,
  320.         <Out, MarshalAs(UnmanagedType.Interface)> ByRef pIKnownFolder As Object)
  321.         '   virtual HRESULT STDMETHODCALLTYPE GetFolder( 
  322.         '       /* [in] */ __RPC__in REFKNOWNFOLDERID rfid,
  323.         '       /* [out] */ __RPC__deref_out_opt IKnownFolder **ppkf) = 0;
  324.         Sub GetFolderByName()
  325.         '   /* [string][in] */ __RPC__in_string LPCWSTR pszCanonicalName,
  326.         '   /* [out] */ __RPC__deref_out_opt IKnownFolder **ppkf) = 0;
  327.         Sub RegisterFolder()
  328.         '   virtual HRESULT STDMETHODCALLTYPE RegisterFolder( 
  329.         '       /* [in] */ __RPC__in REFKNOWNFOLDERID rfid,
  330.         '       /* [in] */ __RPC__in const KNOWNFOLDER_DEFINITION *pKFD) = 0;
  331.         Sub UnregisterFolder()
  332.         '       /* [in] */ __RPC__in REFKNOWNFOLDERID rfid) = 0;
  333.         Sub FindFolderFromPath()
  334.         '       /* [string][in] */ __RPC__in_string LPCWSTR pszPath,
  335.         '       /* [in] */ FFFP_MODE mode,
  336.         '       /* [out] */ __RPC__deref_out_opt IKnownFolder **ppkf) = 0;
  337.         Sub FindFolderFromIDList()
  338.         '       /* [in] */ __RPC__in PCIDLIST_ABSOLUTE pidl,
  339.         '       /* [out] */ __RPC__deref_out_opt IKnownFolder **ppkf) = 0;
  340.         Sub Redirect()
  341.         '   virtual /* [local] */ HRESULT STDMETHODCALLTYPE Redirect( 
  342.         '       /* [annotation][in] */ 
  343.         '       _In_  REFKNOWNFOLDERID rfid,
  344.         '       /* [annotation][unique][in] */ 
  345.         '       _In_opt_  HWND hwnd,
  346.         '       /* [annotation][in] */ 
  347.         '       _In_  KF_REDIRECT_FLAGS flags,
  348.         '       /* [annotation][string][unique][in] */ 
  349.         '       _In_opt_  LPCWSTR pszTargetPath,
  350.         '       /* [annotation][in] */ 
  351.         '       _In_  UINT cFolders,
  352.         '       /* [annotation][unique][size_is][in] */ 
  353.         '       _In_reads_opt_(cFolders)  const KNOWNFOLDERID *pExclusion,
  354.         '       /* [annotation][string][out] */ 
  355.         '       _Outptr_opt_result_maybenull_  LPWSTR *ppszError) = 0;
  356.     End Interface

  357.     Public Const IID_IKnownFolder As String = "3AA7AF7E-9B36-420c-A8E3-F77D4674A488"
  358.     <ComImport,
  359.     InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
  360.     Guid(IID_IKnownFolder)>
  361.     Public Interface IKnownFolder : Inherits IUnKnown
  362.         Sub GetId()
  363.         'virtual HRESULT STDMETHODCALLTYPE GetId( 
  364.         '    /* [out] */ __RPC__out KNOWNFOLDERID *pkfid) = 0;
  365.         Sub GetCategory()
  366.         'virtual HRESULT STDMETHODCALLTYPE GetCategory( 
  367.         '    /* [out] */ __RPC__out KF_CATEGORY *pCategory) = 0;

  368.         Sub GetShellItem(
  369.           dwFlags As UInt32,
  370.          <MarshalAs(UnmanagedType.LPStruct)> REFIID_iid As Guid,
  371.          <Out, MarshalAs(UnmanagedType.Interface)> ByRef _Com_OutPtr As Object)
  372.         'virtual HRESULT STDMETHODCALLTYPE GetShellItem( 
  373.         '   /* [in] */ DWORD dwFlags,
  374.         '   /* [in] */ __RPC__in REFIID riid,
  375.         '   /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
  376.         Sub GetPath()
  377.         'virtual HRESULT STDMETHODCALLTYPE GetPath( 
  378.         '    /* [in] */ DWORD dwFlags,
  379.         '    /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *ppszPath) = 0;
  380.         Sub SetPath()
  381.         'virtual HRESULT STDMETHODCALLTYPE SetPath( 
  382.         '    /* [in] */ DWORD dwFlags,
  383.         '    /* [string][in] */ __RPC__in_string LPCWSTR pszPath) = 0;
  384.         Sub GetIDList()
  385.         'virtual HRESULT STDMETHODCALLTYPE GetIDList( 
  386.         '    /* [in] */ DWORD dwFlags,
  387.         '    /* [out] */ __RPC__deref_out_opt PIDLIST_ABSOLUTE *ppidl) = 0;
  388.         Sub GetFolderType()
  389.         'virtual HRESULT STDMETHODCALLTYPE GetFolderType( 
  390.         '    /* [out] */ __RPC__out FOLDERTYPEID *pftid) = 0;
  391.         Sub GetRedirectionCapabilities()
  392.         'virtual HRESULT STDMETHODCALLTYPE GetRedirectionCapabilities( 
  393.         '    /* [out] */ __RPC__out KF_REDIRECTION_CAPABILITIES *pCapabilities) = 0;
  394.         Sub GetFolderDefinition()
  395.         ' virtual HRESULT STDMETHODCALLTYPE GetFolderDefinition( 
  396.         '    /* [out] */ __RPC__out KNOWNFOLDER_DEFINITION *pKFD) = 0;
  397.     End Interface


  398. End Module









  1. #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
  2. #include <Windows.h>
  3. #include <strsafe.h>
  4. #include <math.h>
  5. #include <ShlObj_core.h>
  6. extern "C" {
  7.     __declspec(dllexport) void BeginTest(LPCWSTR p, INT32 FunSelector);
  8.     __declspec(dllexport) void Get_TestData(LPWSTR* p, INT32 MaxCount);
  9. }
  10. HRESULT hr;
  11. const size_t Str_Buffer_size = 4 << 20;
  12. wchar_t Str_Value[Str_Buffer_size];
  13. wchar_t* pStart;
  14. size_t RemainedLength;

  15. auto  WriteText = [&](const wchar_t* fmt, ...) {
  16.     va_list args;
  17.     va_start(args, fmt);
  18.     StringCchVPrintfExW(pStart, RemainedLength, &pStart, &RemainedLength, 0,
  19.         fmt, args);
  20.     va_end(args);
  21.     };

  22. void BeginTest(LPCWSTR p1, INT32 FunSelector) {
  23.     const wchar_t* Comment = L"= <-- Marshalling DLL -->";
  24.     RemainedLength = ARRAYSIZE(Str_Value);
  25.     pStart = Str_Value;
  26.     WriteText(L"%s %s 1\n", p1, Comment);
  27.     if (SUCCEEDED(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)) &&
  28.         SUCCEEDED(OleInitialize(NULL))) {
  29.         void KnownFolder_Desktop();
  30.         void KnownFolder_Manager();
  31.         if (FunSelector == 1)       KnownFolder_Desktop();
  32.         else  if (FunSelector == 2)  KnownFolder_Manager();
  33.         OleUninitialize();
  34.         CoUninitialize();
  35.     }
  36.     WriteText(L"%s %s 2\n", p1, Comment);
  37. }

  38. void Get_TestData(LPWSTR* p, INT32 nMaxCount) {
  39.     StringCchCopyNW(*p, nMaxCount, Str_Value, pStart - Str_Value + 1);
  40. }

  41. void KnownFolder_Desktop() {
  42.     LPWSTR pwszPath = NULL;
  43.     SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &pwszPath);
  44.     WriteText(L"SHGetKnownFolderPath ==> %s\n", pwszPath);
  45.     CoTaskMemFree(pwszPath);

  46.     PIDLIST_ABSOLUTE ppidl;
  47.     SHGetKnownFolderIDList(FOLDERID_Desktop, 0, NULL, &ppidl);
  48.     SHGetNameFromIDList(ppidl, SIGDN::SIGDN_URL, &pwszPath);
  49.     WriteText(L"URL_Path ======> %s\n", pwszPath);
  50.     ILFree(ppidl); CoTaskMemFree(pwszPath);

  51.     IShellItem* pIShellItem;
  52.     IShellItem2* pIShellItem2;
  53.     hr = SHGetKnownFolderItem(FOLDERID_Desktop, KF_FLAG_DEFAULT, NULL,
  54.         IID_IShellItem, IID_PPV_ARGS_Helper(&pIShellItem));
  55.     if (SUCCEEDED(hr)) {
  56.         pIShellItem->GetDisplayName(SIGDN_NORMALDISPLAY, &pwszPath);
  57.         WriteText(L"name  : %s\n", pwszPath);
  58.         CoTaskMemFree(pwszPath);
  59.         pIShellItem->GetDisplayName(SIGDN_FILESYSPATH, &pwszPath);
  60.         WriteText(L"name  : %s\n", pwszPath);
  61.         CoTaskMemFree(pwszPath);

  62.         pIShellItem->QueryInterface(IID_IShellItem2, IID_PPV_ARGS_Helper(&pIShellItem2));

  63.         pIShellItem2->GetDisplayName(SIGDN_NORMALDISPLAY, &pwszPath);
  64.         WriteText(L"name2 : %s\n", pwszPath);
  65.         CoTaskMemFree(pwszPath);
  66.         pIShellItem2->GetDisplayName(SIGDN_FILESYSPATH, &pwszPath);
  67.         WriteText(L"name2 : %s\n", pwszPath);
  68.         CoTaskMemFree(pwszPath);

  69.         WriteText(L"pIShellItem->Release  = (%i)\n", pIShellItem->Release());
  70.         WriteText(L"pIShellItem2->Release = (%i)\n", pIShellItem2->Release());
  71.     }
  72. }
  73. void KnownFolder_Manager() {
  74.     IKnownFolderManager* pManager;
  75.     hr = CoCreateInstance(CLSID_KnownFolderManager, NULL,
  76.         CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pManager));
  77.     if (SUCCEEDED(hr)) {
  78.         KNOWNFOLDERID* pKnownFolderIDs = NULL;
  79.         UINT cCount = 0;
  80.         hr = pManager->GetFolderIds(&pKnownFolderIDs, &cCount);
  81.         if (SUCCEEDED(hr) && pKnownFolderIDs) {
  82.             for (UINT ii = 0; ii < cCount; ii++) {
  83.                 IKnownFolder* pKnownFolder;
  84.                 hr = pManager->GetFolder(*(pKnownFolderIDs + ii), &pKnownFolder);
  85.                 if (SUCCEEDED(hr)) {
  86.                     WriteText(L"%3i:", ii + 1);
  87.                     IShellItem* psi;
  88.                     hr = pKnownFolder->GetShellItem(0, IID_PPV_ARGS(&psi));
  89.                     if (SUCCEEDED(hr)) {
  90.                         LPWSTR pwstr1, pwstr2;
  91.                         psi->GetDisplayName(SIGDN_NORMALDISPLAY, &pwstr1);
  92.                         WriteText(L"%s ===> ", pwstr1);
  93.                         CoTaskMemFree(pwstr1);
  94.                         psi->GetDisplayName(SIGDN_FILESYSPATH, &pwstr2);
  95.                         WriteText(L"%s", pwstr2);
  96.                         CoTaskMemFree(pwstr2);
  97.                         psi->Release();
  98.                     }
  99.                     pKnownFolder->Release();
  100.                     WriteText(L"\n");
  101.                 }
  102.             }
  103.             CoTaskMemFree(pKnownFolderIDs);
  104.         }
  105.         pManager->Release();
  106.     }
  107. }






留言

這個網誌中的熱門文章

Calling a C# WPF library from C++

Marshalling II