给出一个特定的类:
public class Klass
{
public int value;
public void doSomething(){
return;
}
}
据我所知,要使所说的COM类可见,需要做一些事情:
System.Runtime.InteropServices
产生类似的东西
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface IKlass
{
[DispId(0)]
public int value;
[DispId(1)]
public void doSomething();
}
[Guid("0D53A3E8-E51A-49C7-944E-E72A2064F938"),
ClassInterface(ClassInterfaceType.None)]
public class Klass : IKlass
{
public int value;
public void doSomething(){
return;
}
}
在我看来,生成的代码看起来简直太荒谬了……问题是,是否有一种简单的更干净的方法来创建这些COM接口?我可以想象自己修改构建过程以提供一个interop
功能。例如
public interop class Klass
{
public interop int value;
//...
}
但是,这是非标准的,也存在问题。我可以使用Visual Studio / C#内置的任何东西来使构建COM接口更容易/更清洁吗?
答案 0 :(得分:1)
Zohar Peled建议,最好的方法是使用RegAsm.exe
:
using System.Windows.Forms;
namespace TestProject
{
// Note. Only public classes are exported to COM!
public class Test
{
// Note. Only public methods are exported to COM!
public void testIt() {
MessageBox.Show("Yellow world");
}
}
}
重要提示: 仅公共类导出到COM。通过COM对象实例,只能使用这些类的公共方法。
签署项目。
在AssemblyInfo.cs中,将[assembly: ComVisible(false)]
设置为[assembly: ComVisible(true)]
。 注意:您还可以在要向COM公开的每个类之前使用属性[ComVisible(true)]。这只是将默认设置设置为true
,因此在构建API时更易于使用
构建项目。
运行高潮。记住要使用正确的Regasm版本(32位/ 64位)和.NET Framework的版本:
# .NET v4.5 64-bit
"C:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" -tlb -codebase "C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.dll" -verbose
# .NET v4.5 32-bit
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" -tlb -codebase "C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.dll" -verbose
...
Regasm应该输出如下内容:
Microsoft .NET Framework Assembly Registration Utility version 4.7.3056.0
for Microsoft .NET Framework version 4.7.3056.0
Copyright (C) Microsoft Corporation. All rights reserved.
Types registered successfully
Type 'TestProject.Test' exported.
Assembly exported to 'C:\Users\sancarn\Desktop\tbd\TestProject\TestProject\bin\Debug\TestProject.tlb', and the type library was registered successfully
现在您可以在VBScript中测试文件,例如:
Dim o As Object
Set o = CreateObject("TestProject.Test")
Call o.testIt
答案 1 :(得分:1)
Sancarn回答了您的问题,但是请注意,这也会使您的项目中所有与COM兼容的类也可见,而您可能不希望看到这些类(请参见here和here)。如果未明确设置UUID,则在使用早期绑定的客户端(例如VB或VBA)(而不是后期绑定的VBScript)访问类时,部署时会遇到麻烦。
是的,它不是“干净的”,但COM也不是,特别是当您想将其公开给后期绑定的客户端实时VBScript时。
我还将您的公共场所更改为财产,这对于公共成员来说是更标准的:
[Guid("EAA4976A-45C3-4BC5-BC0B-E474F4C3C83F")]
public interface IKlass
{
[DispId(0)]
public int value {get; set;}
[DispId(1)]
public void doSomething();
}