Pregunta

Estoy desarrollando un cierto código en C # donde estén en contacto con Microsoft Word. Quiero ser capaz de tener la opción de reutilizar una instancia existente o como alternativa la creación de una nueva instancia.

Teniendo en cuenta lo que quiero hacer todo esto utilizando el enlace en tiempo ... que es seguro decir que he descubierto la manera de hacer las cosas de trabajo cuando se crea una nueva instancia .. acabo de llamar Activator.CreateInstance etc ..

El problema que estoy teniendo es ¿cómo puedo volver a utilizar una instancia existente, por ejemplo, la palabra ya están abiertas y quiero usar esa instancia.

¿Hay un Activator.UseExistingInstance? o algo similar ??

Gracias!

¿Fue útil?

Solución

Es posible que desee echar un vistazo a la función AccessibleObjectFromWindow API definido en Oleacc.dll. Andrew Whitechapel tiene algunos artículos sobre cómo usarlo. Sobre la base de sus artículos que escribí una respuesta a una pregunta muy similar (alrededor de Excel, no Word), que se puede encontrar aquí:

  

Cómo utilizar utilizar el enlace para obtener instancia de Excel?

Allí encontrará un ejemplo de cómo conectar a una instancia de Excel ya se está ejecutando y luego automatizar este caso utilizando el enlace en tiempo.

Actualización:

A continuación se muestra un resumen adaptado a la Palabra:

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));
                    }
                }
            }
        }
    }
}

Otros consejos

Usted está buscando 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);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top