문제

C#에서 일부 코드를 개발중인 Microsoft Word와 상호 작용할 것입니다. 기존 인스턴스를 재사용하거나 새 인스턴스를 만드는 대안으로 옵션을 사용할 수 있기를 원합니다.

명심하면 늦은 바인딩을 사용 하여이 모든 작업을 수행하고 싶습니다 ... 새 인스턴스를 만들 때 작업을 수행하는 방법을 알아내는 것이 안전합니다.

내가 가진 문제는 기존 인스턴스를 재사용하는 방법입니다. 예를 들어 Word가 이미 열려 있고 해당 인스턴스를 사용하고 싶습니다.

Activator.useexistingInstance가 있습니까? 또는 비슷한 것 ??

감사!

도움이 되었습니까?

해결책

당신은 그것을보고 싶을 것입니다 AccessibleObjectFromWindow API 함수는 OleAcc.dll에 정의되었습니다. Andrew Whitechapel 사용 방법에 대한 기사가 있습니다. 그의 기사를 바탕으로 나는 여기에서 찾을 수있는 매우 유사한 질문 (단어가 아닌 Excel에 관한)에 대한 답을 썼습니다.

Late Binding을 사용하여 Excel 인스턴스를 얻는 방법은 무엇입니까?

거기에서 이미 실행중인 Excel 인스턴스에 연결 한 다음 늦은 바인딩을 사용 하여이 인스턴스를 자동화하는 방법을 찾을 수 있습니다.

업데이트:

다음은 단어에 적합한 짧은 샘플입니다.

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);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top