将整数传递给VSTO 2010 Word插件

9
我正在开发一个VSTO 2010 Word插件。它有一个自定义任务窗格,其中包含一个倒计时器(用户控件)。想法是当打开一个Word文档时,总时间(以小时和分钟为单位)被传递给插件,插件将其传递给倒计时器控件。当我在VS2010中运行插件并在Addin_Startup中传递两个整数值即小时和分钟给用户控件时,它可以正常工作。
现在,我正在尝试在asp.net页面上的按钮单击时打开一个Word文档。当我单击按钮时,应该打开一个Word文档,并将时间(以小时和分钟为单位)传递给插件,然后插件将其传递给用户控件,计时器应该按照给定的时间运行。
问题是我无法弄清如何向插件传递两个整数,也不知道要把它们传递到哪里。以下是我的代码,有时会出现“灾难性失败错误”,其他时候会出现“无法将类型为'System.__ComObject'的COM对象转换为接口类型'MyWordAddin.IAddInUtilities'”。
ThisAddin类
namespace MyWordAddin
{
    public partial class ThisAddIn
    {
        private ctlClock myUserControl;
        private Microsoft.Office.Tools.CustomTaskPane myCustomTaskPane;
        private int hour, min;
        private AddInUtilities utilities;

        protected override object RequestComAddInAutomationService()
        {
            if (utilities == null)
            {
                utilities = new AddInUtilities();
            }
            return utilities;
        }

        public int Min
        {
            get { return min; }
            set { min = value; }
        }

        public int Hour
        {
            get { return hour; }
            set { hour = value; }
        }


        public Microsoft.Office.Tools.CustomTaskPane MyCustomTaskPane
        {
            get { return myCustomTaskPane; }
            set { myCustomTaskPane = value; }
        }

        public void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            //MessageBox.Show("Start Up Called");
            myCustomTaskPane.VisibleChanged += new EventHandler(myCustomTaskPane_VisibleChanged);

        }
        public void setTime(int h, int m)
        {
            Hour = h;
            Min = m;
            myUserControl = new ctlClock(Hour, Min);
            //myUserControl = new ctlClock(0, 1);
            myCustomTaskPane = this.CustomTaskPanes.Add(myUserControl, "Remaining Time");
            myCustomTaskPane.Visible = true;
        }

        private void yCustomTaskPane_VisibleChanged(object sender, System.EventArgs e)
        {
            Globals.Ribbons.ManageTaskPaneRibbon.toggleButton1.Checked = myCustomTaskPane.Visible;
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

AddinUtilities class

namespace MyWordAddin
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IAddInUtilities
    {
        void setAddinTime(int h, int min);
    }

    [ComVisible(true)]
    //[Serializable()]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddInUtilities : StandardOleMarshalObject,IAddInUtilities
    {
        public void setAddinTime(int hour, int min)
        {
            Globals.ThisAddIn.setTime(hour, min);          

        }

   }


}

控制器应用程序试图打开 Word 文档并向插件发送两个整数。

namespace ControllerApplication
{
    public class CCWordApp
    {
        private Word._Application oWordApp; // a reference to Word application

        public Word._Application OWordApp
        {
            get { return oWordApp; }
            set { oWordApp = value; }
        }
        private Word.Document oWordDoc;     // a reference to the document

        public Word.Document OWordDoc
        {
            get { return oWordDoc; }
            set { oWordDoc = value; }
        }

        public CCWordApp()
        {
            // activate the interface with the COM object of Microsoft Word
            oWordApp = new Word.Application();
            oWordDoc = new Word.Document();


        }

        // Open a new document
        public void Open()
        {
                object addinName = "MyWordAddIn";
                Microsoft.Office.Core.COMAddIn addin = oWordApp.COMAddIns.Item(addinName);
                IAddInUtilities utils = null;
                    utils = (IAddInUtilities)addin.Object;
                    utils.setAddinTime(0, 8);


            Object oMissing = System.Reflection.Missing.Value;
            oWordApp.Visible = true;
            oWordDoc = oWordApp.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
            oWordDoc.Activate();
        }

当我运行控制器应用程序时,点击开始按钮时,有时会出现“灾难性故障”,其他时候会出现“无法将类型为'System.__ComObject'的COM对象转换为接口类型'MyWordAddin.IAddInUtilities'”,有时它会卡在代码的最后一行上,显示“未传递对象实例到对象”。我已经用粗体选中了代码中出错的位置。我无法确定问题出在哪里,也不知道为什么我不能将两个简单的整数传递给我的插件。肯定有些地方我做得非常错误。请指导我。

...加粗了出现错误的代码部分 出错在哪里?我没有看到加粗选中的部分。 - SliverNinja - MSFT
2
控制器应用程序的打开功能在以下代码行中发生错误:utils = (IAddInUtilities)addin.Object; utils.setAddinTime(0, 8); - user1770669
addin.Object是什么类型的对象?尝试使用GetCOMObjectType使用IDispatch接口反射COM实例。您可以设置断点以查看是否曾经触发了RequestComAddInAutomationService吗? - SliverNinja - MSFT
你尝试过使用ComInterfaceType.InterfaceIsIUnknown声明IAddInUtilities吗? - Richard Cook
1个回答

0

我认为你需要覆盖RequestCOMAddInAutomationService,因为你在使用VSTO。

请参考这篇文章: 如何从外部应用程序调用Add-In函数?

共享Add-In使用COMAddIn.Object方式将其函数暴露给外部应用程序,因此我们对OnConnection的实现将大致如下:

((COMAddIn)AddInInst).Object = new MyAutomationObject();

但是,在VSTO中不能使用此方法,因为设置COMAddIn.Object仅允许在OnConnection函数期间进行,并且在VSTO项目中无法看到OnConnection。

它提供了一个覆盖RequestCOMAddInAutomationService()的示例

希望能有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接