首页 > 编程语言 >如何在C#中使用COM接口

如何在C#中使用COM接口

时间:2025-01-07 17:46:20浏览次数:7  
标签:Runtime MethodImpl C# MethodImplOptions 接口 InternalCall COM MethodCodeType

在C++中,可以使用CoCreateInstance函数来创建COM接口的实例。

以下教程可以帮助你方便的在C#中实现同样的功能。

 

方法一、手动生成(适用于所有.NET版本)

1、确定要使用的COM接口

Windows中很多功能都是通过COM实现的,有时候我们想实现一些系统功能,但是又没有直接的Win32 API代调用,就可以寻找COM接口替代。

至于使用哪个COM接口,这个可以通过搜索引擎。

 

例如,我想设置桌面壁纸,就可以通过IDesktopWallpaper接口来实现。

 

2、查找COM接口的GUID

这里提供了几种方案

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

二、对于不常用的COM接口,可能搜索引擎不能搜索到对应的GUID,我们可以创建一个Win32工程(需要Visual Studio安装C++桌面开发),然后输入CLSID_接口名称,再按F12就可以看到GUID。

例如:CLSID_DesktopWallpaper,按F12如下所示

三、如果电脑上没有安装C++桌面开发负载,可以访问stevemk14ebr的gist来进行搜索

 

3、接口声明

有了COM接口的GUID后,我们需要对COM接口进行声明

这里有几个方法可供参考:

一、通过C# + COM接口为关键进行进行搜索

 例如搜索[C# IDesktopWallpaper],然后在结果中查找,一般会有C#的接口声明,如果没找到相关结果,可以查看方法2

 

二、访问pinvoke.net搜索

我们打开https://www.pinvoke.net/,搜索IDesktopWallpaper

目前该网站已经停止维护,所以基本上搜索不出来。

 

三、访问MSDN文档,通过数据类型映射,自行声明COM接口

可以参考下面的文章:

https://learn.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/ac7ay120(v=vs.100)?redirectedfrom=MSDN

这种方法虽然比较麻烦,但也算是最终解决方案了。

 

需要注意的是,接口中涉及的类型也需要进行声明。

 

例如IDesktopWallpaper在C#中声明如下:

  1 using System;
  2 using System.Runtime.CompilerServices;
  3 using System.Runtime.InteropServices;
  4 using System.Text;
  5 
  6 namespace IDesktopWallpaperWrapper.Win32
  7 {
  8     /// <summary>
  9     /// The direction that the slideshow should advance.
 10     /// </summary>
 11     [ComVisible(true)]
 12     public enum DESKTOP_SLIDESHOW_DIRECTION
 13     {
 14         /// <summary>
 15         /// Advance the slideshow forward.
 16         /// </summary>
 17         DSD_FORWARD = 0,
 18         /// <summary>
 19         /// Advance the slideshow backward.
 20         /// </summary>
 21         DSD_BACKWARD = 1
 22     }
 23 
 24 
 25 
 26     /// <summary>
 27     /// Specifies how the desktop wallpaper should be displayed.
 28     /// </summary>
 29     [ComVisible(true)]
 30     public enum DESKTOP_WALLPAPER_POSITION
 31     {
 32         /// <summary>
 33         /// Center the image; do not stretch.
 34         /// </summary>
 35         DWPOS_CENTER = 0,
 36         /// <summary>
 37         /// Tile the image across all monitors.
 38         /// </summary>
 39         DWPOS_TILE = 1,
 40         /// <summary>
 41         /// Stretch the image to exactly fit on the monitor.
 42         /// </summary>
 43         DWPOS_STRETCH = 2,
 44         /// <summary>
 45         /// Stretch the image to exactly the height or width of the monitor without changing its aspect ratio or cropping the image.
 46         /// This can result in colored letterbox bars on either side or on above and below of the image.
 47         /// </summary>
 48         DWPOS_FIT = 3,
 49         /// <summary>
 50         /// Stretch the image to fill the screen, cropping the image as necessary to avoid letterbox bars.
 51         /// </summary>
 52         DWPOS_FILL = 4,
 53         /// <summary>
 54         /// Spans a single image across all monitors attached to the system.
 55         /// </summary>
 56         DWPOS_SPAN = 5
 57     }
 58 
 59 
 60 
 61     [ComVisible(true)]
 62     [Flags]
 63     public enum DESKTOP_SLIDESHOW_STATE
 64     {
 65         /// <summary>
 66         /// Slideshows are enabled.
 67         /// </summary>
 68         DSS_ENABLED = 1,
 69         /// <summary>
 70         /// A slideshow is currently configured.
 71         /// </summary>
 72         DSS_SLIDESHOW = 2,
 73         /// <summary>
 74         /// A remote session has temporarily disabled the slideshow.
 75         /// </summary>
 76         DSS_DISABLED_BY_REMOTE_SESSION = 4
 77     }
 78 
 79 
 80 
 81     /// <summary>
 82     /// COM interface providing methods for managing the desktop wallpaper.
 83     /// Instantiate this COM interface with DesktopWallpaper wrapper class instead.
 84     /// </summary>
 85     /// <remarks>
 86     /// Windows 8 or later is required in order to access this interface.
 87     /// </remarks>
 88     [ComImport]
 89     [Guid("b92b56a9-8b55-4e14-9a89-0199bbb6f93b")]
 90     [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
 91     public interface IDesktopWallpaper
 92     {
 93         //  As with any COM import, method ordering is crucial to the functioning of the interface.
 94         // The code ordering below must be maintained, else an AccessViolationException can be thrown.
 95 
 96         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
 97         void SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.LPWStr)] string wallpaper);
 98 
 99         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
100         [return: MarshalAs(UnmanagedType.LPWStr)]
101         StringBuilder GetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
102 
103         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
104         [return: MarshalAs(UnmanagedType.LPWStr)]
105         StringBuilder GetMonitorDevicePathAt(uint monitorIndex);
106 
107         [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
108         uint GetMonitorDevicePathCount();
109 
110         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
111         RECT GetMonitorRECT([MarshalAs(UnmanagedType.LPWStr)] string monitorID);
112 
113         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
114         void SetBackgroundColor(uint color);
115 
116         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
117         uint GetBackgroundColor();
118 
119         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
120         void SetPosition([MarshalAs(UnmanagedType.I4)] DESKTOP_WALLPAPER_POSITION position);
121 
122         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
123         [return: MarshalAs(UnmanagedType.I4)]
124         DESKTOP_WALLPAPER_POSITION GetPosition();
125 
126         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
127         void SetSlideshow(IShellItemArray items);
128         //void SetSlideshow(IntPtr items);
129 
130         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
131         IShellItemArray GetSlideshow();
132         //IntPtr GetSlideshow();
133 
134         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
135         void SetSlideshowOptions(uint options, uint slideshowTick);
136 
137         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
138         void GetSlideshowOptions(out uint options, out uint slideshowTick);
139 
140         // NOT IMPLEMENTED BY COCLASS
141         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
142         void AdvanceSlideshow([MarshalAs(UnmanagedType.LPWStr)] string monitorID, [MarshalAs(UnmanagedType.I4)] DESKTOP_SLIDESHOW_DIRECTION direction);
143 
144         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
145         DESKTOP_SLIDESHOW_STATE GetStatus();
146 
147         //[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
148         void Enable([MarshalAs(UnmanagedType.Bool)] bool enable);
149     }
150 }

 

 

4、定义类

这个步骤和步骤3类似,但是不需要定义类的成员函数。

1 [ComImport]
2 [Guid("b92b56a9-8b55-4e14-9a89-0199bbb6f93b")]
3 
4 public class DesktopWallpaper
5 {
6 
7 }

 

5、使用

1 IDesktopWallpaper desktopWallpaper = (IDesktopWallpaper)new DesktopWallpaper();
2 
3 //调用成员函数
4 desktopWallpaper.xxxx();

 

方法二、自动生成(适用于.NET6+版本)

标签:Runtime,MethodImpl,C#,MethodImplOptions,接口,InternalCall,COM,MethodCodeType
From: https://www.cnblogs.com/zhaotianff/p/18657903

相关文章

  • echarts示例-legend
    二、legend-图例1、type-图例的类型。可选值:'plain':普通图例。缺省就是普通图例。'scroll':可滚动翻页的图例。当图例数量较多时可以使用。当使用'scroll'时,使用这些设置进行细节配置:legend.scrollDataIndexlegend.pageButtonItemGaplegend.pageButtonGaplegend.pageButton......
  • 【core analyzer】core analyzer的介绍和安装详情
    1.core和coreanalyzer的基本概念......
  • 在 .NET Framework 中,C#代码防止按钮重复点击的后端处理
    ai生成:在.NETFramework中,防止按钮重复点击的后端处理通常涉及到Web应用程序(如ASP.NETWebForms或ASP.NETMVC)。以下是一些常见的后端处理方法和示例代码:ASP.NETWebForms在WebForms中,你可以使用ViewState或Session来防止按钮重复点击。以下是一个使用ViewSta......
  • 【mac】mac多用户创建与用户添加删除
    mac多用户创建与用户添加删除 在 linux 系统中我们习惯了使用useradd,userdel,usermod 等指令进行用户管理,使用groupadd,groupdel,groupmod等指令进行用户组管理。但是在 macOS 下这些指令是没有的。所以今天分享的主题是在macOS下如何在命令行里进行用户组、用户......
  • Cursor 收费太贵?3分钟教你接入超低价 DeepSeek-V3,代码质量逼近 Claude 3.5
    DeepSeek-V3实在是太便宜了,就跟不要钱似的:每百万输入tokens0.1元(缓存命中)/1元(缓存未命中),每百万输出tokens2元跟其他模型相比,DeepSeek-V3的性价比非常高,只能用“真香”来形容。Sealos推出的AI聚合代理服务SealosAIProxy为用户提供了便捷的AI模型访......
  • docker配置mysql一主多从。宿主机Navicat Premium 15通过不同ip连接
    1.环境准备1.1拉取MySQL镜像dockerpullmysql:8.0解释:从Docker官方镜像仓库中拉取MySQL8.0镜像,确保我们使用最新版本。如果已经拉取,可以跳过这步。1.2创建自定义网络(二选一)1.2.1创建自定义网络(端口不同)dockernetworkcreatemysql-cluster解释:创建......
  • 在 C++ 中优雅地处理 JSON:nlohmann/json 库实践指南
    JSON(JavaScriptObjectNotation)作为一种轻量级的数据交换格式,在现代软件开发中扮演着重要角色。在C++开发中,nlohmann/json库因其易用性和灵活性而广受欢迎。本文将通过实例介绍如何使用这个强大的库进行JSON数据的序列化和反序列化操作。环境准备首先,我们需要配置项目......
  • [题目记录]CF335F Buy One , Get One Free
    CF335FBuyOne,GetOneFree题意\(n\)个物品,价格为\(a_i\),每买一个物品\(i\)可以免费得到一个\(a_j<a_i\)的物品\(j\),问获取所有物品的最小花费.\(n\le5\times10^5\),\(1\lea_i\le10^9\).题解有一个最直接显然的贪心是买最大,送次大,以此类......
  • MATLAB的cat函数
    在图像处理中,我们将图像导入MATLAB中,通常以矩阵的形式进行处理;在各种的处理过程中,我们不可避免的要完成对矩阵的拼接,主要分为纵向和横向两种方式。1、横向拼接横向拼接可以考虑使用:“,”或者“空格”;A=[111;222;333];B=[444;555;666];C=[777;888;99......
  • LeetCode 747. 至少是其他数字两倍的最大数
    问题描述给定一个整数数组nums,其中总是存在唯一的一个最大整数。任务是找出数组中的最大元素,并检查它是否至少是数组中每个其他数字的两倍。如果是,则返回最大元素的下标;否则,返回-1。解题思路这个问题可以通过两个主要步骤解决:寻找最大元素及其下标:首先,我们需要遍历数组......