如何验证C#/.NET COM 对象实际上是一个COM 对象?
How to verify that C#/.NET COM object is actually a COM object?
我有一个 C# 项目,它创建了一个用于 POS 终端的 COM 对象。在我将它提供给客户之前,我想确保它可以作为 COM dll 工作。 RegAsm 说它有效。
using System;
using System.Runtime.InteropServices;
namespace POS
{
[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1a" )]
[InterfaceType( ComInterfaceType.InterfaceIsDual )]
[ComVisible( true )]
public interface ITwoWay
{
// The Initialize method is called to establish the communications connection...
[DispId( 1 )]
void Initialize( String IPAddress, long Port, long MaxPacketSize );
// A convenience method that allows the POS to test the Third Party’s back-end...
[DispId( 2 )]
void TestConnect();
// The Terminate method is called to indicate that the POS system is about to terminate...
[DispId( 3 )]
void Terminate();
// All interface calls made during a transaction send the same record format with specific reply fields ...
[DispId( 4 )]
void TransactionCall( String viPOSMsg, ref String InterceptArray );
}
}
实际入口点在class TwoWay
中定义
using System.Runtime.InteropServices;
using System.EnterpriseServices;
namespace POS
{
[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1b" )]
[ComDefaultInterface(typeof(ITwoWay))]
[ClassInterface( ClassInterfaceType.None )]
[ComVisible( true )]
public class TwoWay : ITwoWay
...
[ComVisible( true )]
public void Initialize( string iPAddress, long port, long maxPacketSize )
...
我原以为我可以将 .tlb 导入另一个 .net 项目并以这种方式对其进行测试,但是当我将我的 COM 项目添加为 COM 引用时,VS 拒绝了它,因为它是作为 .NET dll 创建的。
我试图为 运行 CreateObject 创建一个 vb 脚本,但是权限错误。我试图设置 I_USER 帐户等,但无法进行。
注册表显示了一个名称正确的条目,并且 class id 设置为正确的 guid。但是,我仍然想通过 COM 接口加载它并运行它。
如何验证 COM .dll 实际上是 COM .dll?这么老了,一定有办法的。
一种快速的方法是使用 .NET 的 dynamic 功能,这对 COM 编程非常有用
所以如果你 class 是这样定义的(我个人不使用 .NET 的 COM 接口,但如果接口是双重的,那不会改变任何东西),请注意我添加了一个 progid,它是良好的 COM 实践:
[Guid("0135bc5c-b248-444c-94b9-b0b4577f5a1a")]
[ProgId("MyComponent.TwoWay")]
[ComVisible(true)]
public class TwoWay
{
public void Initialize(string IPAddress, long Port, long MaxPacketSize)
{
Console.WriteLine(IPAddress);
}
// other methods...
}
然后我可以像这样使用 .NET 对其进行测试(无需创建 TLB,只需使用 regasm 注册它):
var type = Type.GetTypeFromProgID("MyComponent.TwoWay");
dynamic twoway = Activator.CreateInstance(type);
twoway.Initialize("hello", 0, 0);
不方便的是你没有自动完成,你只需要注意传递适合的参数。 .NET 足够聪明,可以将 Int32
转换为 Int64
(请注意,您使用的 C# long
是 64 位宽)。
我有一个 C# 项目,它创建了一个用于 POS 终端的 COM 对象。在我将它提供给客户之前,我想确保它可以作为 COM dll 工作。 RegAsm 说它有效。
using System;
using System.Runtime.InteropServices;
namespace POS
{
[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1a" )]
[InterfaceType( ComInterfaceType.InterfaceIsDual )]
[ComVisible( true )]
public interface ITwoWay
{
// The Initialize method is called to establish the communications connection...
[DispId( 1 )]
void Initialize( String IPAddress, long Port, long MaxPacketSize );
// A convenience method that allows the POS to test the Third Party’s back-end...
[DispId( 2 )]
void TestConnect();
// The Terminate method is called to indicate that the POS system is about to terminate...
[DispId( 3 )]
void Terminate();
// All interface calls made during a transaction send the same record format with specific reply fields ...
[DispId( 4 )]
void TransactionCall( String viPOSMsg, ref String InterceptArray );
}
}
实际入口点在class TwoWay
中定义using System.Runtime.InteropServices;
using System.EnterpriseServices;
namespace POS
{
[Guid( "0135bc5c-b248-444c-94b9-b0b4577f5a1b" )]
[ComDefaultInterface(typeof(ITwoWay))]
[ClassInterface( ClassInterfaceType.None )]
[ComVisible( true )]
public class TwoWay : ITwoWay
...
[ComVisible( true )]
public void Initialize( string iPAddress, long port, long maxPacketSize )
...
我原以为我可以将 .tlb 导入另一个 .net 项目并以这种方式对其进行测试,但是当我将我的 COM 项目添加为 COM 引用时,VS 拒绝了它,因为它是作为 .NET dll 创建的。
我试图为 运行 CreateObject 创建一个 vb 脚本,但是权限错误。我试图设置 I_USER 帐户等,但无法进行。
注册表显示了一个名称正确的条目,并且 class id 设置为正确的 guid。但是,我仍然想通过 COM 接口加载它并运行它。
如何验证 COM .dll 实际上是 COM .dll?这么老了,一定有办法的。
一种快速的方法是使用 .NET 的 dynamic 功能,这对 COM 编程非常有用
所以如果你 class 是这样定义的(我个人不使用 .NET 的 COM 接口,但如果接口是双重的,那不会改变任何东西),请注意我添加了一个 progid,它是良好的 COM 实践:
[Guid("0135bc5c-b248-444c-94b9-b0b4577f5a1a")]
[ProgId("MyComponent.TwoWay")]
[ComVisible(true)]
public class TwoWay
{
public void Initialize(string IPAddress, long Port, long MaxPacketSize)
{
Console.WriteLine(IPAddress);
}
// other methods...
}
然后我可以像这样使用 .NET 对其进行测试(无需创建 TLB,只需使用 regasm 注册它):
var type = Type.GetTypeFromProgID("MyComponent.TwoWay");
dynamic twoway = Activator.CreateInstance(type);
twoway.Initialize("hello", 0, 0);
不方便的是你没有自动完成,你只需要注意传递适合的参数。 .NET 足够聪明,可以将 Int32
转换为 Int64
(请注意,您使用的 C# long
是 64 位宽)。