当前位置 : 主页 > 编程语言 > c++ >

.NET2.0 C#Interop:如何从C#调用COM代码?

来源:互联网 收集:自由互联 发布时间:2021-06-23
在我的上一个开发环境中,我能够轻松地与COM交互,在COM对象上调用方法.这是原始代码,翻译成C#样式代码(掩盖原始语言): public static void SpawnIEWithSource(String szSourceHTML){ OleVariant ie; //IWebB
在我的上一个开发环境中,我能够轻松地与COM交互,在COM对象上调用方法.这是原始代码,翻译成C#样式代码(掩盖原始语言):

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互操作的繁琐,痛苦的过程.

PInvoke.net已经包含IWebBrower2 translation,其相关部分是:

[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类:

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

所以现在是我实际的C#事务的时候了:

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.

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

快速搜索Stack Overflow以使用来自C#的IDispatch会在this post中显示我想要的东西在.NET中是不可能的.

那么可以使用C#.NET 2.0中的COM吗?

问题是我想在C#/ .NET中使用一种公认的设计模式.它涉及启动Internet Explorer进程,并为其提供HTML内容,而不使用临时文件.

被拒绝的设计理念是在WinForm上托管Internet Explorer.

可接受的替代方案是启动系统注册的Web浏览器,使其显示HTML,而不使用临时文件.

绊脚石继续在.NET世界中使用COM对象.具体问题涉及在不需要C#4.0的情况下对IDispatch执行后期绑定调用. (即使用.NET 2.0时)

Update: Based on question updates, I have removed the portions of my answer that are no longer relevant to the question. However, in case other readers are looking for a quick and dirty way to generate HTML in a winforms app and do not require an in-process IE, I will leave the following:

可能的场景1:最终目标是简单地向最终用户显示HTML并使用Windows窗体

System.Windows.Forms.WebBrowser是您尝试手动实现的接口的简单易用的.NET包装器.要获取它,将该对象的实例从工具栏(在“所有Windows窗体”部分下列为“Web浏览器”)拖放到窗体上.然后,在一些合适的事件处理程序:

webBrowser1.Navigate("about:blank");
webBrowser1.Document.Write("<html><body>Hello World</body></html>");

在我的测试应用程序中,这正确地显示了我们都学会害怕和厌恶的难以忘怀的消息.

网友评论