如何验证C#/。NET COM对象实际上是COM对象?

时间:2019-06-28 02:16:09

标签: c# com

我有一个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 );
    }
}

实际的入口点是在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创建的。

我试图创建一个vb脚本来运行CreateObject,但是权限错误。我试图设置I_USER帐户,等等,但是我做不到。

注册表显示具有正确名称的条目,并且将类ID设置为正确的GUID。但仍然,我想加载它并通过COM接口运行它。

如何验证COM .dll实际上是COM .dll?就像这样古老,必须有一种方法。

1 个答案:

答案 0 :(得分:0)

一种快速的实现方法是使用.NET的dynamic功能,这对于COM编程非常有用

因此,如果您的类定义是这样的(我个人没有将COM接口与.NET一起使用,但是如果接口是双重的,则不会有任何改变),请注意,我添加了一个很好的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位宽)。