欧美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接口定義了一組方法和屬性,這些方法和屬性可以通過(guò)任何支持該模型的語(yǔ)言調(diào)用來(lái)訪問(wèn),本文給大家介紹了如何在C#中使用COM接口,需要的朋友可以參考下

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

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

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

1、確定要使用的COM接口

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

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

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

2、查找COM接口的GUID

這里提供了幾種方案

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

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

例如:CLSID_DesktopWallpaper,按F12如下所示

IDesktopWallpaper

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

3、接口聲明

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

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

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

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

二、訪問(wèn)pinvoke.net搜索

我們打開(kāi)pinvoke.net: the interop wiki!,搜索IDesktopWallpaper

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

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

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

Platform Invoke Data Types | Microsoft Learn

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

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

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

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

對(duì)于POINT或RECT之類(lèi)的,建議也是自己定義,不要使用C#內(nèi)置類(lè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類(lèi)型,暫時(shí)不導(dǎo)入
     //void SetSlideshow(IShellItemArray items);
 
     //未引用IShellItemArray類(lèi)型,暫時(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、定義類(lèi)

這個(gè)步驟和步驟3類(lèi)似,但是不需要定義類(lèi)的成員函數(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)目來(lái)實(shí)現(xiàn)這個(gè)功能,CsWin32是一個(gè)源代碼生成器,用于在 C# 項(xiàng)目中添加一組用戶定義的 Win32 P/Invoke 方法和支持類(lèi)型。

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

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

使用CsWin32生成COM接口的聲明,在官方的文檔中并未直接說(shuō)明,我也是在一個(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è)類(lèi)型都需要寫(xiě),如果只寫(xiě)了IDesktopWallpaper,就無(wú)法實(shí)例化接口。我一開(kāi)始就是卡在這里。

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

4、通過(guò)代碼生成器生成的類(lèi)型在哪

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

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

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

也可以通過(guò)Ctrl+T,輸入類(lèi)型名稱進(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());
             }

說(shuō)明:CsWin32項(xiàng)目在生成LPWSTR/PWSTR類(lèi)型時(shí)沒(méi)有使用C#的類(lèi)型進(jìn)行映射,例如只讀字符串的使用string,需要寫(xiě)入字符串的使用分配空間后的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)用易語(yǔ)言寫(xiě)的Dll文件方法

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

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

    C#中類(lèi)的使用教程詳解

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

    C#之多余控件事件及代碼刪除問(wèn)題

    這篇文章主要介紹了C#之多余控件事件及代碼刪除問(wèn)題,具有很好的參考價(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ì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • 一文詳解C#中方法重載的底層玩法

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

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

最新評(píng)論