.NET2.0 C#互操作:如何从C#调用COM代码?

2024-03-07

在我的上一个开发环境中,我能够轻松地与 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 翻译 http://pinvoke.net/default.aspx/Interfaces/IWebBrowser2.html,其中相关部​​分是:

[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这个帖子 https://stackoverflow.com/questions/403218/does-c-net-support-idispatch-late-binding在.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:根据问题更新,我删除了答案中与问题不再相关的部分。然而,如果其他读者正在寻找一种在 winforms 应用程序中生成 HTML 的快速而肮脏的方法,并且不需要进程内 IE,我将留下以下内容:

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

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

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

在我的测试应用程序上,这正确地显示了我们都学会恐惧和厌恶的令人难以忘怀的信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.NET2.0 C#互操作:如何从C#调用COM代码? 的相关文章

随机推荐