.NET2.0 C#互操作:如何从C#调用COM代码? [英] .NET2.0 C# Interop: How to call COM code from C#?

查看:253
本文介绍了.NET2.0 C#互操作:如何从C#调用COM代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的最后一个开发环境中,我能够轻松地与COM交互,调用COM对象的方法。这里是原代码,翻译成C#代码风格(以掩盖原来的语言):

In my last development environment, I was able to easily interact with COM, calling methods on COM objects. Here is the original code, translated into C# style code (to mask the original language):

public static void SpawnIEWithSource(String szSourceHTML)
{
    OleVariant ie; //IWebBrowser2
    OleVariant ie = new InternetExplorer();
    ie.Navigate2("about:blank");

    OleVariant webDocument = ie.Document;
    webDocument.Write(szSourceHTML);
    webDocument.close;

    ie.Visible = True;
}

现在开始尝试与COM到互操作的繁琐,痛苦的过程,从管理代码。

Now begins the tedious, painful, process of trying to interop with COM from managed code.

PInvoke.net已经包含的 IWebBrower2翻译,其中relavent porition是:

PInvoke.net already contains the IWebBrower2 translation, the relavent porition of which is:

[ComImport, 
   DefaultMember("Name"), 
   Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E"), 
   InterfaceType(ComInterfaceType.InterfaceIsIDispatch), 
   SuppressUnmanagedCodeSecurity]
public interface IWebBrowser2
{
    [DispId(500)]
    void Navigate2([In] ref object URL, [In] ref object Flags, [In] ref object TargetFrameName, [In] ref object PostData, [In] ref object Headers);

    object Document { [return: MarshalAs(UnmanagedType.IDispatch)] [DispId(0xcb)] get; }
}



我创建的COM类:

I've created the COM class:

[ComImport]
[Guid("0002DF01-0000-0000-C000-000000000046")]
public class InternetExplorer
{
}

所以,现在是时候让我实际的C#交易:

So now it's time for my actual C# transaction:

public static void SpawnIEWithSource(String szHtml)
{
    PInvoke.ShellDocView.IWebBrowser2 ie;
    ie = (PInvoke.ShellDocView.IWebBrowser2)new PInvoke.ShellDocView.InternetExplorer();

    //Navigate to about:blank to initialize the browser
    object o = System.Reflection.Missing.Value;
    String url = @"about:blank";
    ie.Navigate2(ref url, ref o, ref o, ref o, ref o);

    //stuff contents into the document
    object webDocument = ie.Document;
    //webDocument.Write(szHtml);
    //webDocument.Close();

    ie.Visible = true;
}



细心的读者注意到IWebBrowser2.Document是后期绑定的IDispatch。
我们正在使用Visual Studio 2005,与我们的.NET 2.0,和我们的客户的,机器。

The careful readers notice that IWebBrowser2.Document is a late-bound IDispatch. We're using Visual Studio 2005, with .NET 2.0 on our, and our customer's, machines.

那么什么是.NET 2.0的方法来调用方法即,在一定程度上,只支持后期绑定的IDispatch对象上?

So what's the .NET 2.0 method to invoke methods on an object that, on some level, only supports late-bound IDispatch?

使用的IDispatch在C#中快速搜索堆栈溢出的轮番上涨的这个帖子说我想要的东西是不可能在.NET

A quick search of Stack Overflow for using IDispatch from C# turns up this post saying what I want is not possible in .NET.

那么,是否可以使用从C#.NET 2.0?

So is it possible to use COM from C# .NET 2.0?


现在的问题是,有,我想在C#/。NET使用一个公认的设计模式。它涉及启动Internet Explorer的进程外,并给予它的HTML内容,不使用临时文件中的所有时间。

The question is that there is an accepted design pattern that I want to use in C#/.NET. It involves launching Internet Explorer out of process, and giving it HTML content, all the while not using temporary files.

一个拒绝的设计理念是在WinForm的主机的Internet Explorer。

A rejected design idea is hosting Internet Explorer on a WinForm.

这是可接受的替代推出系统中注册的web浏览器,给它的HTML来显示,而无需使用一个临时文件。

An acceptable alternative is launching the system registered web browser, giving it HTML to display, without using a temporary file.

绊脚石继续在.NET世界中使用COM对象。具体问题涉及到无需C#4.0 IDispatch接口进行后期绑定调用。 (即在使用.NET 2.0)

The stumbling block is continuing to use COM objects in the .NET world. The specific problem involves performing late-binding calls to IDispatch without needing C# 4.0. (i.e. while using .NET 2.0)

推荐答案

称为后期绑定的IDispatch在.NET relativly容易,但小便穷人:

Late bound IDispatch called is relativly easy in .NET, although piss-poor:

public static void SpawnIEWithSource(String szHtml)
{
    // Get the class type and instantiate Internet Explorer.
    Type ieType = Type.GetTypeFromProgID("InternetExplorer.Application");
    object ie = Activator.CreateInstance(ieType);

    //Navigate to the blank page in order to make sure the Document exists
    //ie.Navigate2("about:blank");
    Object[] parameters = new Object[1];
    parameters[0] = @"about:blank";
    ie.GetType().InvokeMember("Navigate2", BindingFlags.InvokeMethod | BindingFlags.IgnoreCase, null, ie, parameters);

    //Get the Document object now that it exists
    //Object document = ie.Document;
    object document = ie.GetType().InvokeMember("Document", BindingFlags.GetProperty | BindingFlags.IgnoreCase, null, ie, null);

    //document.Write(szSourceHTML);
    parameters = new Object[1];
    parameters[0] = szHtml;
    document.GetType().InvokeMember("Write", BindingFlags.InvokeMethod | BindingFlags.IgnoreCase, null, document, parameters);

    //document.Close()
    document.GetType().InvokeMember("Close", BindingFlags.InvokeMethod | BindingFlags.IgnoreCase, null, document, null);

    //ie.Visible = true;
    parameters = new Object[1];
    parameters[0] = true;
    ie.GetType().InvokeMember("Visible", BindingFlags.SetProperty | BindingFlags.IgnoreCase, null, ie, parameters);
}

引用的SO问题,原本说,不可能,直到C#4.0进行了修订展示它是如何可能的.NET 2.0。

The referenced SO question that originally said "not possible until C# 4.0" was amended to show how it is possible in .NET 2.0.

请问C#.NET支持的IDispatch后期绑定?

这篇关于.NET2.0 C#互操作:如何从C#调用COM代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆