Office Addin 在使用 WCF 时终止主机

发布于 2024-08-23 16:35:44 字数 3224 浏览 4 评论 0原文

解决这个问题花了一些时间,结论很有趣。

我们的 Office (Word/Excel/PowerPoint) 加载项向我们的自定义 WCF 服务发送请求,托管 Office 应用程序终止,并在应用程序日志中留下此条目:

Provider: .NET Runtime 
EventID: 1023
Level: 2
Task: 0 
Keywords: 0x80000000000000 
Channel: Application 
EventData: .NET Runtime version 2.0.50727.4200 - Fatal Execution Engine Error (6BC47B3E) (80131506)

要重现此情况,请创建一个新的“Word 2007 加载项”项目在 Visual Studio 2008 中。添加对 System.ServiceModel 和 System.Runtime.Serialization 的引用。修改您的 ThisAddin 类以包含此代码,我相信这是重现此行为所需的最少代码:

[Serializable]
public class CustomQuery { }
[Serializable]
public class CustomQueryCollection : ReadOnlyCollection<CustomQuery>
{
    public CustomQueryCollection(IEnumerable<CustomQuery> queries)
        : base(queries.ToArray())
    { }
}
[Serializable]
[KnownType(typeof(CustomQueryCollection))]
public class CustomRequest : ISerializable
{
    readonly CustomQueryCollection _collection;
    public CustomRequest(IEnumerable<CustomQuery> queries)
    {
        _collection = new CustomQueryCollection(queries);
    }
    protected CustomRequest(SerializationInfo info, StreamingContext context)
    {
        _collection = (CustomQueryCollection)info.GetValue("Queries", typeof(CustomQueryCollection));
    }
    public CustomQueryCollection Queries { get { return _collection; } }
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Queries", _collection);
    }
}
[ServiceContract]
public interface ICustomService
{
    [OperationContract]
    void SendRequest(CustomRequest request);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CustomService : ICustomService
{
    public void SendRequest(CustomRequest request)
    {
        // this line is never reached.
    }
}
public class CustomClient : ClientBase<ICustomService>, ICustomService
{
    public CustomClient(Binding binding, EndpointAddress address)
        : base(binding, address)
    { }
    public void SendRequest(CustomRequest request)
    {
        Channel.SendRequest(request);
    }
}
public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        var address = "net.pipe://localhost/kamikaze";
        var endpointAddress = new EndpointAddress(address);
        var binding = new NetNamedPipeBinding();
        using (var serviceHost = new ServiceHost(new CustomService()))
        using (var client = new CustomClient(binding, endpointAddress))
        {
            serviceHost.AddServiceEndpoint(typeof(ICustomService), binding, address);
            serviceHost.Open();
            client.SendRequest(new CustomRequest(new CustomQuery[0]));
            // this line is never reached.
            serivceHost.Close();
        }
    }
    private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { }
    #region VSTO generated code
    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }
    #endregion
}

按 [F5]:Word 2007 启动,然后消失,在系统的应用程序日志中留下上述日志消息。相同的代码在我们尝试过的所有其他上下文中都运行得很好。

It took some time to solve this and the conclusions are interesting.

Our Office (Word/Excel/PowerPoint) add-in sends a request to our custom WCF service, the hosting Office application terminates, leaving this entry in the application log:

Provider: .NET Runtime 
EventID: 1023
Level: 2
Task: 0 
Keywords: 0x80000000000000 
Channel: Application 
EventData: .NET Runtime version 2.0.50727.4200 - Fatal Execution Engine Error (6BC47B3E) (80131506)

To reproduce this, create a new "Word 2007 Add-in" project in Visual Studio 2008. Add references to System.ServiceModel and System.Runtime.Serialization. Modify your ThisAddin class to contain this code, which I believe is the minimum code necessary to reproduce this behaviour:

[Serializable]
public class CustomQuery { }
[Serializable]
public class CustomQueryCollection : ReadOnlyCollection<CustomQuery>
{
    public CustomQueryCollection(IEnumerable<CustomQuery> queries)
        : base(queries.ToArray())
    { }
}
[Serializable]
[KnownType(typeof(CustomQueryCollection))]
public class CustomRequest : ISerializable
{
    readonly CustomQueryCollection _collection;
    public CustomRequest(IEnumerable<CustomQuery> queries)
    {
        _collection = new CustomQueryCollection(queries);
    }
    protected CustomRequest(SerializationInfo info, StreamingContext context)
    {
        _collection = (CustomQueryCollection)info.GetValue("Queries", typeof(CustomQueryCollection));
    }
    public CustomQueryCollection Queries { get { return _collection; } }
    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Queries", _collection);
    }
}
[ServiceContract]
public interface ICustomService
{
    [OperationContract]
    void SendRequest(CustomRequest request);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CustomService : ICustomService
{
    public void SendRequest(CustomRequest request)
    {
        // this line is never reached.
    }
}
public class CustomClient : ClientBase<ICustomService>, ICustomService
{
    public CustomClient(Binding binding, EndpointAddress address)
        : base(binding, address)
    { }
    public void SendRequest(CustomRequest request)
    {
        Channel.SendRequest(request);
    }
}
public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        var address = "net.pipe://localhost/kamikaze";
        var endpointAddress = new EndpointAddress(address);
        var binding = new NetNamedPipeBinding();
        using (var serviceHost = new ServiceHost(new CustomService()))
        using (var client = new CustomClient(binding, endpointAddress))
        {
            serviceHost.AddServiceEndpoint(typeof(ICustomService), binding, address);
            serviceHost.Open();
            client.SendRequest(new CustomRequest(new CustomQuery[0]));
            // this line is never reached.
            serivceHost.Close();
        }
    }
    private void ThisAddIn_Shutdown(object sender, System.EventArgs e) { }
    #region VSTO generated code
    private void InternalStartup()
    {
        this.Startup += new System.EventHandler(ThisAddIn_Startup);
        this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
    }
    #endregion
}

Hit [F5]: Word 2007 starts, and then disappears, leaving the log message described above in your system's application log. The same code works perfectly fine in all other contexts that we've tried.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

木有鱼丸 2024-08-30 16:35:44

更改这些代码行:

[KnownType(typeof(CustomQueryCollection))]
[KnownType(typeof(CustomQuery[]))]

_collection = (CustomQueryCollection)info.GetValue("Queries", typeof(CustomQueryCollection));
_collection = new CustomQueryCollection((CustomQuery[]) info.GetValue("Queries", typeof(CustomQuery[])));

info.AddValue("Queries", _collection);
info.AddValue("Queries", _collection.ToArray());

...那里。不再出现致命的引擎执行错误。我怀疑这与 Office 作为 .Net 2.0 主机有关,而我们所有其他用例和测试都涉及 .Net 3.5 主机,但我只是猜测。

Change these lines of code:

[KnownType(typeof(CustomQueryCollection))]
[KnownType(typeof(CustomQuery[]))]

_collection = (CustomQueryCollection)info.GetValue("Queries", typeof(CustomQueryCollection));
_collection = new CustomQueryCollection((CustomQuery[]) info.GetValue("Queries", typeof(CustomQuery[])));

info.AddValue("Queries", _collection);
info.AddValue("Queries", _collection.ToArray());

...there. No more fatal engine execution errors. I suspect this is related to Office being a .Net 2.0 host, while all our other use cases and tests involved .Net 3.5 hosts, but I'm only guessing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文