How to iterate through instance of Excel c#

后端 未结 1 680
情话喂你
情话喂你 2020-12-04 00:08

I can access an instance of Excel in memory using Marshal.GetActiveObject. But this always returns the oldest existing instance.

I would like to iterate though all i

相关标签:
1条回答
  • 2020-12-04 00:46

    Try this.

            List<Process> procs = new List<Process>();
            procs.AddRange(Process.GetProcessesByName("excel"));
    

    Edit: There is an article that fully implements this at http://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx. GetActiveObject will always return the first object from the table. This is because Office doesn't register new objects. You have to get the application from the child windows.

    Edit: This is the code that worked for me.

    using Excel = Microsoft.Office.Interop.Excel;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication1
    {        
    
    class Program
    {
        [DllImport("Oleacc.dll")]
        public static extern int AccessibleObjectFromWindow(
              int hwnd, uint dwObjectID, byte[] riid,
              ref Microsoft.Office.Interop.Excel.Window 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() == "EXCEL7")
            {
                lParam = hwndChild;
                return false;
            }
            return true;
        }
    
        static void Main(string[] args)
        {
            Excel.Application app = new Excel.Application();
            EnumChildCallback cb;
            List<Process> procs = new List<Process>();
            procs.AddRange(Process.GetProcessesByName("excel"));
    
            foreach (Process p in procs)
            {
                if ((int)p.MainWindowHandle > 0)
                {
                    int childWindow = 0;
                    cb = new EnumChildCallback(EnumChildProc);
                    EnumChildWindows((int)p.MainWindowHandle, cb, ref childWindow);
    
                    if (childWindow > 0)
                    {
                        const uint OBJID_NATIVEOM = 0xFFFFFFF0;
                        Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}");
                        Excel.Window window = null;
                        int res = AccessibleObjectFromWindow(childWindow, OBJID_NATIVEOM, IID_IDispatch.ToByteArray(), ref window);
                        if (res >= 0)
                        {
                            app = window.Application;
                            Console.WriteLine(app.Name);
                        }
                    }
                }
            }
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题