C# 如何使用后期绑定访问Microsoft Word现有实例

C# 如何使用后期绑定访问Microsoft Word现有实例,c#,automation,ms-word,late-binding,activator,C#,Automation,Ms Word,Late Binding,Activator,我正在用c语言开发一些代码,在那里我将与Microsoft Word进行交互。我希望能够选择重新使用现有实例,或者创建新实例 记住,我想用后期绑定来完成所有这些。。。可以肯定地说,我已经找到了在创建新实例时如何使事情正常工作的方法。。我只是调用Activator.CreateInstance等 我遇到的问题是如何重用现有实例,例如,Word已经打开,我想使用该实例 是否有Activator.UseExistingInstance?或者类似的东西 谢谢 您可能需要查看Oleacc.dll中定义的A

我正在用c语言开发一些代码,在那里我将与Microsoft Word进行交互。我希望能够选择重新使用现有实例,或者创建新实例

记住,我想用后期绑定来完成所有这些。。。可以肯定地说,我已经找到了在创建新实例时如何使事情正常工作的方法。。我只是调用Activator.CreateInstance等

我遇到的问题是如何重用现有实例,例如,Word已经打开,我想使用该实例

是否有Activator.UseExistingInstance?或者类似的东西


谢谢

您可能需要查看Oleacc.dll中定义的
AccessibleObjectFromWindow
api函数。有一些关于如何使用它的文章。根据他的文章,我回答了一个非常类似的问题(关于Excel,而不是Word),你可以在这里找到:

在这里,您将看到一个示例,如何连接到已经运行的Excel实例,然后使用后期绑定自动化该实例

更新:

以下是一个适用于Word的简短示例:

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

namespace WordLateBindingSample
{
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
    public interface IDispatch
    {
    }

    class Program
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("Oleacc.dll")]
        static extern int AccessibleObjectFromWindow(int hwnd, uint dwObjectID, byte[] riid, out IDispatch ptr);

        public delegate bool EnumChildCallback(int hwnd, ref int lParam);

        [DllImport("User32.dll")]
        public static extern bool EnumChildWindows(int hWndParent, EnumChildCallback lpEnumFunc, ref int lParam);

        [DllImport("User32.dll")]
        public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount);

        public static bool EnumChildProc(int hwndChild, ref int lParam)
        {
            StringBuilder buf = new StringBuilder(128);
            GetClassName(hwndChild, buf, 128);
            if (buf.ToString() == "_WwG")
            {
                lParam = hwndChild;
                return false;
            }
            return true;
        }

        static void Main(string[] args)
        {
            // Use the window class name ("OpusApp") to retrieve a handle to Word's main window.
            // Alternatively you can get the window handle via the process id:
            // int hwnd = (int)Process.GetProcessById(wordPid).MainWindowHandle;
            //
            int hwnd = (int)FindWindow("OpusApp", null);

            if (hwnd != 0)
            {
                int hwndChild = 0;

                // Search the accessible child window (it has class name "_WwG") 
                // as described in http://msdn.microsoft.com/en-us/library/dd317978%28VS.85%29.aspx
                //
                EnumChildCallback cb = new EnumChildCallback(EnumChildProc);
                EnumChildWindows(hwnd, cb, ref hwndChild);

                if (hwndChild != 0)
                {
                    // We call AccessibleObjectFromWindow, passing the constant OBJID_NATIVEOM (defined in winuser.h) 
                    // and IID_IDispatch - we want an IDispatch pointer into the native object model.
                    //
                    const uint OBJID_NATIVEOM = 0xFFFFFFF0;
                    Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
                    IDispatch ptr;

                    int hr = AccessibleObjectFromWindow(hwndChild, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), out ptr);

                    if (hr >= 0)
                    {
                        object wordApp = ptr.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, ptr, null);

                        object version = wordApp.GetType().InvokeMember("Version", BindingFlags.GetField | BindingFlags.InvokeMethod | BindingFlags.GetProperty, null, wordApp, null);
                        Console.WriteLine(string.Format("Word version is: {0}", version));
                    }
                }
            }
        }
    }
}

您正在查找Marshal.GetActiveObject

object word;
try
{
    word = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
}
catch (COMException)
{
    Type type = Type.GetTypeFromProgID("Word.Application");
    word = System.Activator.CreateInstance(type);
}

您好,您是说您正在创建一个WinForms项目,而不是在设计时设置对Microsoft.Office.Interop.Word或PIA的引用,或其他任何内容的引用?在这种情况下,您调用的是:Type.GetTypeFromProgID(“Word.Application”);在该类型上使用Activator.CreateInstance?假设您将Activator.CreateInstance的结果分配给“var”或“object”类型变量:重复使用该变量有什么问题?非常感谢。这是我一直在寻找的解决方案。致以最良好的问候。我有进程句柄,我能从该句柄中获得word实例吗?我一直得到
hr=-2147467259
,你能帮助@Dirk吗。@AniketBhansali:这是HRESULT的意思。你在哪一行得到的?我在变量
hr
中调用了
AccessibleObjectFromWindow
得到的结果,我解决了它,这是因为多个office安装,即office 2013和2016,通过卸载其中一个来解决。无论如何,谢谢@Dirk Vollmar