c#WinForm程序调用vsto动态库,已解决

最近做一个vsto的项目,涉及到Form程序调用vsto动态库,弄了半天,搜了很多资料终于搞定了,把积累写下来备以后用。
相关网址:

https://stackoverflow.com/questions/10875278/vsto-add-ins-comaddins-and-requestcomaddinautomationservice

https://blogs.msdn.microsoft.com/andreww/2008/08/11/why-your-comaddin-object-should-derive-from-standardolemarshalobject/

https://blogs.msdn.microsoft.com/andreww/2007/01/15/vsto-add-ins-comaddins-and-requestcomaddinautomationservice/

Demo:

1. 建立一个word外接程序(addin)
我的demo建的是WordVSTOTest工程,建好以后在addin.cs文件中添加一个类变量和一个函数。这个函数是必须的。

namespace WordVSTOTest
{
    public partial class ThisAddIn
    {
        private AddinUtilities addinUtilities;
        protected override object RequestComAddInAutomationService()
        {
            if (addinUtilities == null)
            {
                addinUtilities = new AddinUtilities();
            }
            return addinUtilities;
        }

    }
}

 注意到AddinUtilities 没有定义,是的,这是个自定义类,名字随便,但要保持一致,里面要封装你要导出的供外部调用的函数。

2. 添加一个类
demo的类名叫AddinUtilities,添加如下代码:

using System.Runtime.InteropServices;

namespace WordVSTOTest
{
    [ComVisible(true)]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IAddinUtilities
    {
        void test();
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    public class AddinUtilities : StandardOleMarshalObject, IAddinUtilities
    {
        void test()
        {
            MessageBox.Show("Hello World");
        }
    }
}

 这里定义一个接口类型,接口类型里面的函数就是要导出供外部调用的函数,需要什么函数就些什么函数,和普通函数无区别,然后我们的AddinUtilities类要继承这个接口,最后依次实现定义的函数就可以了。我这里是导出了test函数,简单弹个框。

3. 编译
这个编译需要设置一下,不然会有很多莫名其妙的错误,首先vs要用管理员启动,然后转到工程属性-->build,在“输出”栏有个 “为COM互操作注册”的复选框,要勾选这个,最后编译。编译过程中如果要提示还有类似没有注册的错误,要用regasm.exe  注册一下就行了。电脑里搜索到regasm.exe所在的目录,cmd下转到该目录,使用命令:regasm.exe dll绝对路径 /参数。  编译好的dll要在winForm工程里面使用。

好了vsto这边的工作就做完了,下面转到我们的Form测试工程。

4. 建立一个WinForm工程
Demo为WinFormTest工程,建好以后,在form上拖一个button控件,双击button直接转到click函数处:写入一下代码:

public Word.Application app;
        public IAddinUtilities utils;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            app = new Word.Application();
            string str = app.Name;
            
            app.Visible = false;
            object addinName = "WordVSTOTest";
            COMAddIn addin = app.COMAddIns.Item(ref addinName);
            
            utils = (IAddinUtilities)addin.Object;
            utils.test();

            //如果没有这个Quit的话,任务管理器的WINWORD.exe不会退出,越来越多。
            ((Word._Application)app).Quit(); 
            System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app);
        }

 注意工程需要using以下几项:
using WordVSTOTest;
using Word = Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;

引入这些后才可以编译通过。

简单看一下工程截图:

查看运行结果:

5. 结束。
理解这个调用过程还需要对COM有所了解,不明白原理,抄来抄去到时候出现bug也难排查,就到这里吧。

原文地址:https://www.cnblogs.com/priarieNew/p/9761486.html