标签: idispatch

C#.NET是否支持IDispatch后期绑定?


问题

我的问题是:C#nativly支持后期绑定IDispatch吗?


假装我正在尝试自动化Office,同时兼容客户安装的任何版本.

在.NET世界中,如果您安装了Office 2000,那么从现在到结束,每个开发人员和每个客户都需要拥有Office 2000.

在.NET之前的世界中,我们使用COM与Office应用程序进行通信.

例如:

1)使用版本独立的ProgID

"Excel.Application"
Run Code Online (Sandbox Code Playgroud)

解析为:

clsid = {00024500-0000-0000-C000-000000000046}
Run Code Online (Sandbox Code Playgroud)

然后使用COM,我们要求将其中一个类实例化为一个对象:

IUnknown unk;
CoCreateInstance(
    clsid, 
    null,
    CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
    IUnknown, 
    out unk);
Run Code Online (Sandbox Code Playgroud)

现在我们即将参加比赛 - 能够在我的应用程序中使用Excel.当然,如果你真的想要使用该对象,你必须调用一些方法来调用方法.

我们可以得到阿霍德不同的接口声明,翻译成我们的语言.这项技术很好,因为我们得到了

  • 早期绑定
  • 代码洞察
  • 编译类型语法检查

一些示例代码可能是:

Application xl = (IExcelApplication)unk;
ExcelWorkbook workbook = xl.Workbooks.Add(template, lcid);
Worksheet worksheet = workbook.ActiveSheet;
Run Code Online (Sandbox Code Playgroud)

但是使用接口有一个缺点:我们必须得到各种接口声明,转换成我们的语言.我们坚持使用基于方法的调用,必须指定所有参数,例如:

ExcelWorkbook workbook = xl.Workbooks.Add(template, lcid);
xl.Worksheets.Add(before, after, count, type, lcid);
Run Code Online (Sandbox Code Playgroud)

在现实世界中,这证明了我们愿意放弃的这些缺点:

  • 早期绑定
  • 代码洞察
  • 编译时语法检查

而是使用IDispatch后期绑定:

Variant xl = (IDispatch)unk;
Variant …
Run Code Online (Sandbox Code Playgroud)

c# late-binding idispatch

27
推荐指数
3
解决办法
2万
查看次数

如何在普通C中使用IDispatch来调用COM对象

我需要使用R工具中包含的gcc编译器(R用于windows的统计程序)编译我的一些代码,问题是我需要在我的代码中使用IDispatch来创建访问COM对象的方法,以及gcc编译器不支持我用来执行的大部分代码,这基本上是C++代码.

所以我的问题是如何在C中使用IDispatch来创建COM对象,而不必依赖于MFC,.NET,C#,WTL或ATL.我相信如果我这样做,我将能够毫无问题地编译我的代码.

c com gcc activex idispatch

14
推荐指数
2
解决办法
6539
查看次数

C#4,COM互操作和UPnP:一个尝试三巨头

我正在尝试编写一些使用UPnP进行NAT遍历的代码(仅供家庭使用),使用C#4和Microsoft的基于COM的NAT遍历API(Hnetcfg.dll).

不幸的是(或者幸运的是)我最后一次在.NET中使用COM互操作是在最后一个冰河时代的某个时候,我似乎对C#使用动态类型进行互操作以及如何编写回调感到困惑(所以COM服务器调用我的托管代码).

这是令人兴奋的几行代码:

// Referencing COM NATUPNPLib ("NATUPnP 1.0 Type Library")

using System;
using NATUPNPLib;

class NATUPnPExample
{
    public delegate void NewNumberOfEntriesDelegate(int lNewNumberOfEntries);

    public static void NewNumberOfEntries(int lNewNumberOfEntries)
    {
        Console.WriteLine("New number of entries: {0}", lNewNumberOfEntries);
    }

    public static void Main(string[] args)
    {
        UPnPNAT nat = new UPnPNAT();
        NewNumberOfEntriesDelegate numberOfEntriesCallback = NewNumberOfEntries;

        nat.NATEventManager.NumberOfEntriesCallback = numberOfEntriesCallback;

        nat.StaticPortMappingCollection.Add(4555, "TCP", 4555, "192.168.0.1", true, "UPnPNAT Test");

        // Presumably my NewNumberOfEntries() method should be called by the COM component about now

        nat.StaticPortMappingCollection.Remove(4555, "TCP");
    } …
Run Code Online (Sandbox Code Playgroud)

com upnp idispatch c#-4.0

11
推荐指数
1
解决办法
519
查看次数

COM/OLE/ActiveX/IDispatch混淆

我无法理解这些术语之间的差异.

COM和ActiveX是同义词吗?

ActiveX对象只是一个公开IDispatch的COM对象吗?

很多旧的MSDN页面都提到没有任何COM上下文的IDispatch.它是否有单独的历史记录,并且刚刚在其生命周期的后期在COM"保护伞"下引入?

OLE适合哪里?它(可观)是否存在于MFC命名和MSDN中 - 所有这些都只是遗产?

维基百科提供了一些见解,但并不多.我找不到更深入的参考资料.

com activex ole idispatch

7
推荐指数
2
解决办法
2486
查看次数

COM双接口

COM中的双接口是能够通过DispInterface或VTable方法访问的接口.

现在可以有人告诉我这两种方法的区别究竟是什么?

我认为VTable是一个虚拟表,它在实现类层次结构时保存指向不同函数的指针,该类层次结构具有可在子类中重写的虚函数.但是我不知道这与COM中的双接口有什么关系?

com interface idispatch

6
推荐指数
1
解决办法
5529
查看次数

在c#中实现IDispatch

我正在编写一些测试代码来模拟非托管代码,调用后期绑定COM对象的c#实现.我有一个声明为IDispatch类型的接口,如下所示.

 [Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")]
 [InterfaceType(ComInterfaceType.InterfaceIsDual)]
 public interface TestInterface
 {
     int Test();
 }

 [ClassInterface(ClassInterfaceType.AutoDual)]
 public class TestImpl : TestInterface 
 {
 ...
 }
Run Code Online (Sandbox Code Playgroud)

当我使用下面的代码调用IDispatch的GetIDsOfNames函数时

  ..
  //code provided by Hans Passant
  Object so = Activator.CreateInstance(Type.GetTypeFromProgID("ProgID.Test"));
  string[] rgsNames = new string[1];
  int[] rgDispId = new int[1];
  rgsNames[0] = "Test";

  //the next line throws an exception
  IDispatch disp = (IDispatch)so;
Run Code Online (Sandbox Code Playgroud)

IDispatch定义为:

 //code provided by Hans Passant
 [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
 private interface IDispatch {
     int GetTypeInfoCount();
     [return: MarshalAs(UnmanagedType.Interface)]
     ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int …
Run Code Online (Sandbox Code Playgroud)

c# com idispatch

6
推荐指数
1
解决办法
7220
查看次数

关于C#项目中神秘界面的警告

每次我构建我的C#解决方案时,我都会收到一些关于我从未见过或写过的接口的警告.我试过谷歌搜索其中一些,但没有得到点击.这些可能被埋在我正在引用的组件中吗?如果是这样,有没有办法让这些警告消失?

接口'IAlertable'标记为[dual],但不是从IDispatch派生的.它将被转换为IUnknown派生的接口.

接口'ICustomizationPermissionsReports'标记为[dual],但不是从IDispatch派生的.它将被转换为IUnknown派生的接口.

接口'IAlertable2'标记为[dual],但不是从IDispatch派生的.它将被转换为IUnknown派生的接口.

c# warnings interface idispatch iunknown

5
推荐指数
1
解决办法
1718
查看次数

CreateStdDispatch 如何知道调用什么方法?

我面临着实现一个IDispatch接口。有四种方法,幸运的是其中 3 种方法很简单:

function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetTypeInfo(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetIDsOfNames(...): HResult;
{
   Result := E_NOTIMPL;
}
Run Code Online (Sandbox Code Playgroud)

这是最后一种方法,Invoke这很困难。在这里,我不得不实际处理DispID并调用我的适当方法;从变体数组解组参数。

function Invoke(  
  dispIdMember: DISPID;
  riid: REFIID;
  lcid: LCID;
  wFlags: WORD;
  var pDispParams: DISPPARAMS;
  var pVarResult: VARIANT;
  var pExcepInfo: EXCEPINFO;
  var puArgErr: DWORD
): HRESULT;
Run Code Online (Sandbox Code Playgroud)

不想编写所有乏味的样板代码,我肯定会有错误,我去谷歌搜索 - 而不是做任何工作。

我在以下的 MSDN 文档中IDispatch.Invoke找到了这个片段:

通常,您不应直接实现Invoke

优秀!我无论如何都不想实施它!继续阅读:

相反,使用调度接口来创建函数CreateStdDispatchDispInvoke。有关详细信息,请参阅CreateStdDispatchDispInvoke、 …

com winapi idispatch native-code

5
推荐指数
2
解决办法
1738
查看次数

将接口传递给其他进程

我使用WM_COPYDATA来启用我的两个进程A和B之间的通信.与基本数据类型交换数据没有问题.

现在我有一个问题,在某些情况下我想从我的进程A传递一个接口(IDispatch)到我的进程B.是否可能?

delphi com ipc interface idispatch

5
推荐指数
2
解决办法
797
查看次数

信息不可用,没有为 .dll 加载符号

我在 C++ 中应用 Invoke 来使用应用程序的对象,但发生错误。错误:信息不可用,没有为 GPNSAutomation.dll 加载符号我的代码是:

 ::CLSIDFromProgID(OLESTR("SGNSAutomation.SGNSApplication"), &clsid);
IID iid;
  HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, 
  IID_IDispatch, (LPVOID*)&pWMPDispatch);
  IDispatch * pdisp = (IDispatch *)NULL;
  DISPID dispid;
  DISPPARAMS  params= {NULL,NULL,0,0};
 params.cArgs =1;
  OLECHAR * Name = OLESTR("importCase");
 HRESULT hresult =pWMPDispatch->GetIDsOfNames(IID_NULL, 
     &Name,1,LOCALE_SYSTEM_DEFAULT,&dispid);
  hresult =pWMPDispatch->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, 
            DISPATCH_METHOD, &params, NULL, NULL,
                          NULL);  

_ASSERT(hr==S_OK);
Run Code Online (Sandbox Code Playgroud)

com automation invoke idispatch

5
推荐指数
0
解决办法
4197
查看次数

标签 统计

idispatch ×10

com ×8

c# ×3

interface ×3

activex ×2

automation ×1

c ×1

c#-4.0 ×1

delphi ×1

gcc ×1

invoke ×1

ipc ×1

iunknown ×1

late-binding ×1

native-code ×1

ole ×1

upnp ×1

warnings ×1

winapi ×1