欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何在C#中使用COM接口

 更新時(shí)間:2025年03月05日 10:21:15   作者:△曉風(fēng)殘?jiān)漏e  
COM是一種二進(jìn)制接口標(biāo)準(zhǔn),允許軟件組件在同一進(jìn)程中、跨進(jìn)程甚至跨網(wǎng)絡(luò)透明地交互,COM接口定義了一組方法和屬性,這些方法和屬性可以通過任何支持該模型的語言調(diào)用來訪問,本文給大家介紹了如何在C#中使用COM接口,需要的朋友可以參考下

在C++中,可以使用CoCreateInstance函數(shù)來創(chuàng)建COM接口的實(shí)例。

以下教程可以幫助你方便的在C#中實(shí)現(xiàn)同樣的功能。

方法一、手動(dòng)生成(適用于所有.NET版本)

1、確定要使用的COM接口

Windows中很多功能都是通過COM實(shí)現(xiàn)的,有時(shí)候我們想實(shí)現(xiàn)一些系統(tǒng)功能,但是又沒有直接的Win32 API代調(diào)用,就可以尋找COM接口替代。

至于使用哪個(gè)COM接口,這個(gè)可以通過搜索引擎。

例如,我想設(shè)置桌面壁紙,可以通過IDesktopWallpaper接口來實(shí)現(xiàn)。

2、查找COM接口的GUID

這里提供了幾種方案

一、通過搜索引擎,常用的COM接口,可以通過搜索引擎直接搜索到GUID

二、對(duì)于不常用的COM接口,可能搜索引擎不能搜索到對(duì)應(yīng)的GUID,我們可以創(chuàng)建一個(gè)Win32工程(需要Visual Studio安裝C++桌面開發(fā)),然后輸入CLSID_接口名稱,再按F12就可以看到GUID。

例如:CLSID_DesktopWallpaper,按F12如下所示

IDesktopWallpaper

三、如果電腦上沒有安裝C++桌面開發(fā)負(fù)載,可以訪問stevemk14ebr的gist來進(jìn)行搜索

3、接口聲明

有了COM接口的GUID后,我們需要對(duì)COM接口進(jìn)行聲明

這里有幾個(gè)方法可供參考:

一、通過C# + COM接口為關(guān)鍵進(jìn)行進(jìn)行搜索

 例如搜索[C# IDesktopWallpaper],然后在結(jié)果中查找,一般會(huì)有C#的接口聲明,如果沒找到相關(guān)結(jié)果,可以查看方法2

二、訪問pinvoke.net搜索

我們打開pinvoke.net: the interop wiki!,搜索IDesktopWallpaper

目前該網(wǎng)站已經(jīng)停止維護(hù),很大機(jī)率會(huì)搜索不出來。

三、訪問MSDN文檔,通過數(shù)據(jù)類型映射,自行聲明COM接口

數(shù)據(jù)類型的映射可以參考下面的文章:

Platform Invoke Data Types | Microsoft Learn

這種方法雖然比較麻煩,但也算是最終解決方案了。

像我平常跟硬件交互比較多,這種映射也是家常便飯了。

需要注意的是,接口中涉及的類型也要進(jìn)行聲明。

例如void SetPosition(DESKTOP_WALLPAPER_POSITION position)參數(shù)里涉及了DESKTOP_WALLPAPER_POSITION,我們需要對(duì)這個(gè)DESKTOP_WALLPAPER_POSITION類型進(jìn)行定義。

對(duì)于POINT或RECT之類的,建議也是自己定義,不要使用C#內(nèi)置類型,否則有可能會(huì)封送失敗。

IDesktopWallpaper在C#中聲明如下:

 [ComVisible(true)]
 public enum DESKTOP_SLIDESHOW_DIRECTION
 {
      DSD_FORWARD = 0,
      DSD_BACKWARD = 1
  }
  
 
 public struct RECT
 {
     public int left;
     public int top;
     public int right;
     public int bottom;
 }
 
 [ComVisible(true)]
 public enum DESKTOP_WALLPAPER_POSITION
 {
     DWPOS_CENTER = 0,
     DWPOS_TILE = 1,
     DWPOS_STRETCH = 2,
     DWPOS_FIT = 3,
     DWPOS_FILL = 4,
     DWPOS_SPAN = 5
 }
 
 [ComVisible(true)]
 [Flags]
 public enum DESKTOP_SLIDESHOW_STATE
 {
     DSS_ENABLED = 1,
     DSS_SLIDESHOW = 2,
     DSS_DISABLED_BY_REMOTE_SESSION = 4
 }
 
 [ComImport]
 [Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")]
 [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 public interface IDesktopWallpaper
 {
     void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);
     
     [return: MarshalAs(UnmanagedType.LPWStr)]
     StringBuilder GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
     
     [return: MarshalAs(UnmanagedType.LPWStr)]
     StringBuilder GetMonitorDevicePathAt(uint monitorIndex);
 
     [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
     uint GetMonitorDevicePathCount();
        
     RECT GetMonitorRECT([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
   
     void SetBackgroundColor(uint color);
  
     uint GetBackgroundColor();
 
     void SetPosition([MarshalAs(UnmanagedType.I4)] DESKTOP_WALLPAPER_POSITION position);
 
     [return: MarshalAs(UnmanagedType.I4)]
     DESKTOP_WALLPAPER_POSITION GetPosition();
 
     //未引入IShellItemArray類型,暫時(shí)不導(dǎo)入
     //void SetSlideshow(IShellItemArray items);
 
     //未引用IShellItemArray類型,暫時(shí)不導(dǎo)入
     //IShellItemArray GetSlideshow();
     //IntPtr GetSlideshow();
 
     void SetSlideshowOptions(uint options, uint slideshowTick);
 
     void GetSlideshowOptions(out uint options, out uint slideshowTick);
 
     void AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.I4)] DESKTOP_SLIDESHOW_DIRECTION direction);
 
     DESKTOP_SLIDESHOW_STATE GetStatus();
 
     void Enable([MarshalAs(UnmanagedType.Bool)] bool enable);
 }

4、定義類

這個(gè)步驟和步驟3類似,但是不需要定義類的成員函數(shù)。這里的GUID使用的是CLSID_DesktopWallpaper的GUID

[ComImport]
[Guid("C2CF3110-460E-4FC1-B9D0-8A1C0C9CC4BD")]
 public class DesktopWallpaper
 {
 
 }

5、使用

 IDesktopWallpaper desktopWallpaper = (IDesktopWallpaper)new DesktopWallpaper();
 
 //調(diào)用成員函數(shù)
desktopWallpaper.xxxx();

方法二、自動(dòng)生成(適用于.NET6+版本)

自動(dòng)生成主要是借助Cswin32項(xiàng)目來實(shí)現(xiàn)這個(gè)功能,CsWin32是一個(gè)源代碼生成器,用于在 C# 項(xiàng)目中添加一組用戶定義的 Win32 P/Invoke 方法和支持類型。

這種方法會(huì)比較簡單方便,但是僅適用于.NET Core。.Net Framework無法使用。

另外還要求Visual Studio的版本至少是Visual Studio 2019 Update 11 (16.11)

使用CsWin32生成COM接口的聲明,在官方的文檔中并未直接說明,我也是在一個(gè)issue中找到了實(shí)現(xiàn)方法。

實(shí)現(xiàn)步驟如下:

1、nuget導(dǎo)入Microsoft.Windows.CsWin32包

2、在項(xiàng)目下,新建一個(gè)NativeMethods.txt文件

3、在NativeMethods.txt下輸入需要導(dǎo)入的COM接口

例如我們想使用IDesktopWallpaper接口,就在NativeMethods.txt下輸入

 IDesktopWallpaper
 DesktopWallpaper

注意:

1、兩個(gè)類型都需要寫,如果只寫了IDesktopWallpaper,就無法實(shí)例化接口。我一開始就是卡在這里。

2、需要生成接口的類型都可以寫在NativeMethods.txt里,每個(gè)類型單獨(dú)一行。

4、通過代碼生成器生成的類型在哪

對(duì)于自動(dòng)生成的類型,命名空間都不一樣,但是都是在Windows.Win32命名空間下。

在Visual Studio中,輸入Windows.Win32,自己定位所需要類型所在的命名空間即可。

例如IDesktopWallpaper所在的命名空間是:Windows.Win32.UI.Shell

也可以通過Ctrl+T,輸入類型名稱進(jìn)行查找 

5、使用

             Windows.Win32.UI.Shell.IDesktopWallpaper desktopWallpaper = (Windows.Win32.UI.Shell.IDesktopWallpaper)new Windows.Win32.UI.Shell.DesktopWallpaper();
             Windows.Win32.Foundation.PWSTR pWSTR = new Windows.Win32.Foundation.PWSTR();
            
            
             unsafe
             {
                 char* p = stackalloc char[1];
                 p[0] = '0';
                 Windows.Win32.Foundation.PWSTR szMonitorId = new Windows.Win32.Foundation.PWSTR(p);
 #pragma warning disable CA1416 // 驗(yàn)證平臺(tái)兼容性
                 desktopWallpaper.GetWallpaper(szMonitorId, &pWSTR);
 #pragma warning restore CA1416 // 驗(yàn)證平臺(tái)兼容性
 
                 MessageBox.Show(pWSTR.ToString());
             }

說明:CsWin32項(xiàng)目在生成LPWSTR/PWSTR類型時(shí)沒有使用C#的類型進(jìn)行映射,例如只讀字符串的使用string,需要寫入字符串的使用分配空間后的StringBuilder。

所以不得不使用unsafe關(guān)鍵字,并使用指針。這種方法并不太友好 。

以上就是詳解如何在C#中使用COM接口的詳細(xì)內(nèi)容,更多關(guān)于C#使用COM接口的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 字符串和十六進(jìn)制之間的轉(zhuǎn)換方法實(shí)例

    字符串和十六進(jìn)制之間的轉(zhuǎn)換方法實(shí)例

    這篇文章介紹了字符串和十六進(jìn)制之間的轉(zhuǎn)換方法實(shí)例,有需要的朋友可以參考一下
    2013-11-11
  • C#+EmguCV使用攝像頭讀取、保存視頻

    C#+EmguCV使用攝像頭讀取、保存視頻

    這篇文章主要為大家詳細(xì)介紹了C#+EmguCV使用攝像頭讀取、保存視頻,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • c#使用csredis操作redis的示例

    c#使用csredis操作redis的示例

    這篇文章主要介紹了c#使用csredis操作redis的示例,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2020-12-12
  • Unity實(shí)現(xiàn)游戲卡牌滾動(dòng)效果

    Unity實(shí)現(xiàn)游戲卡牌滾動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)游戲卡牌滾動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • C#調(diào)用易語言寫的Dll文件方法

    C#調(diào)用易語言寫的Dll文件方法

    在本篇內(nèi)容里小編給大家分享的是關(guān)于C#調(diào)用易語言寫的Dll文件的方法內(nèi)容,需要的參考下。
    2018-12-12
  • C#中類的使用教程詳解

    C#中類的使用教程詳解

    在對(duì)類訪問使用時(shí),常用到的有訪問類的成員、方法。本文就將通過示例為大家詳細(xì)講講C#中類的使用教程,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)
    2022-07-07
  • C#之多余控件事件及代碼刪除問題

    C#之多余控件事件及代碼刪除問題

    這篇文章主要介紹了C#之多余控件事件及代碼刪除問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • ItemsControl 數(shù)據(jù)綁定的兩種方式

    ItemsControl 數(shù)據(jù)綁定的兩種方式

    這篇文章主要介紹了ItemsControl 數(shù)據(jù)綁定的兩種方式,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下
    2021-03-03
  • ToLua框架下C#與Lua代碼的互調(diào)操作

    ToLua框架下C#與Lua代碼的互調(diào)操作

    這篇文章主要介紹了ToLua框架下C#與Lua代碼的互調(diào)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • 一文詳解C#中方法重載的底層玩法

    一文詳解C#中方法重載的底層玩法

    最近在看C++的方法重載,就在想C#中的重載底層是怎么玩的。畢竟很多朋友應(yīng)該知道C是不支持重載的。本文將來詳細(xì)講講C#中方法重載的底層玩法,感興趣的可以了解一下<BR>
    2022-06-06

最新評(píng)論