C#生成COM接口及注意事项(含注册脚本)

  1. 编写实现,注意实现类上必须有 [ClassInterface(ClassInterfaceType.None)] 特性
    using System.Runtime.InteropServices;
    
    namespace EcgTool
    {
        public interface IEcgBaseUtility
        {
            bool DecompressData(byte[] compressbuffer,ref short[] _decompressData);
        }
    
        [ClassInterface(ClassInterfaceType.None)]
        public class EcgTools : IEcgBaseUtility
        {
            public bool DecompressData(byte[] compressbuffer,ref short[] _decompressData)
            {
                EcgBaseUtilityWrap.EcgBaseUtilityWrap ecgBaseUtilityWrap = new EcgBaseUtilityWrap.EcgBaseUtilityWrap();
    
                var ret = ecgBaseUtilityWrap.DecompressData(compressbuffer,_decompressData, 1);
                return ret;
            }
        }
    }

     

  2. 修改Properties下面的AssemblyInfo.cs
    [assembly: ComVisible(true)]
    [assembly: ClassInterface(ClassInterfaceType.AutoDual)]

     

  3. 点开 项目-项目属性-生成  找到"为COM互操作注册" 勾选保存

 

  以上就是基于VS2019生成COM的操作。

  需要注意的是如果需要带出参数,需要在参数前加上 ref (和是否是引用类型无关)。如上面的 _decompressData

  实际实现ecgBaseUtilityWrap.DecompressData中是没有ref的,为什么我们自己声明的COM函数需要加?

  可以参考: C#程序员请不要混淆引用类型和ref引用传参

  

  如果觉得上面绕,可以参考我的理解:

  

  COM是win系统给的接口,你写的dll和调用者exe中间的数据是通过系统传递的,上面的数组在系统中实际是一个PSafeArray

而不是C#中的byte[]和short[]。即我们的参数a被一个b的参数接收了,里面实际操作的是b(是不是回想起形参和实参的区别?)

所以这样数据是带不出来的,而我们解决形参值带不出来的办法就是加个ref。

 

  本机调试因为步骤3所以是不需要注册的,但当我们把dll给用户时,用户需要注册才能调用COM的dll。

@echo off 
if not "%OS%"=="Windows_NT" exit

if exist "%SystemRoot%\SysWOW64" path %path%;%windir%\SysNative;%SystemRoot%\SysWOW64;%~dp0
bcdedit >nul
if '%errorlevel%' NEQ '0' (goto UACPrompt) else (goto UACAdmin)
:UACPrompt
%1 start "" mshta vbscript:createobject("shell.application").shellexecute("""%~0""","::",,"runas",1)(window.close)&exit
exit /B
:UACAdmin
echo 已获取管理员权限

::获取当前路径 注册需要编写dll对应的.net版本 防止使用默认的RegAsm.exe
cd /d "%~dp0"
set path=%cd%
echo 当前路径:%path%

::先取消注册 再注册
%path%\RegAsm.exe /u %path%\EcgTool.dll
%path%\RegAsm.exe %path%\EcgTool.dll

echo 按任意键退出
pause >nul
exit

把.net对应的RegAsm.exe版本和动态库放在同一目录,

将上面的脚本保存成.bat文件运行即可。ps:记得把 EcgTool.dll 改为自己的dll

posted @ 2021-03-15 16:24  htzmi  阅读(863)  评论(0)    收藏  举报