Прикрепить к существующему экземпляру Excel

Я пытаюсь определить, работает ли экземпляр Excel с определенным открытым файлом, и если да, то прикрепляюсь к нему, чтобы я мог контролировать этот экземпляр.

Я искал вокруг, и большая часть того, что у меня есть, пришло из этот вопрос. В нем есть ссылка на другой сайт, но, к сожалению, это мертво для меня, поэтому я не могу прочитать об этом.

Мой код до сих пор;

//Is Excel open?
if (Process.GetProcessesByName("EXCEL").Length != 0)
{
    Process[] processes = Process.GetProcesses();
    foreach (Process process in processes)
    {
        //Find the exact Excel instance
        if (process.ProcessName.ToString() == "EXCEL" && process.MainWindowTitle == ("Microsoft Excel - " + fileName))
        {
             //Get the process ID of that instance
             int processID = (int)Process.GetProcessById(process.Id).MainWindowHandle;

             //Attach to the instance...
             Excel.Application existingExcel = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject(process.Id);                 
        }
    }
}

До сих пор мне удавалось получить идентификатор процесса экземпляра, к которому я хочу подключиться, но я теряюсь, когда дело доходит до использования этого идентификатора.

Любые идеи о том, как действовать?


person Sean    schedule 14.05.2014    source источник
comment
Что не работает с кодом, который вы опубликовали до сих пор? А как насчет ответа на вопрос, на который вы ссылаетесь, недостаточно? (Связанный блог можно найти по адресу https://web.archive.org/web/20100420164139/http://blogs.officezealot.com/whitechapel/archive/2005/04/10/4514.aspx., но не содержит намного больше, чем в этом ответе)   -  person Ben Aaronson    schedule 14.05.2014
comment
Также важно: какая это версия Excel? Excel 2013, к сожалению, ломает вещи, которые отлично работают с более ранними версиями.   -  person Ben Aaronson    schedule 14.05.2014
comment
Я использую Office 2010, и это фрагмент кода Excel.Application существующийExcel = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject(process.Id); Выдает ошибку; Недопустимая строка класса (Исключение из HRESULT: 0x800401F3 (CO_E_CLASSSTRING)) По сути, я хочу иметь возможность сделать что-то вроде; exisitingExcel.Worksheets.add(); Использование ответа, на который я ссылался, просто выдает ошибку, когда переменная res имеет значение null.   -  person Sean    schedule 14.05.2014


Ответы (1)


Marshal.GetActiveObject() не принимает идентификатор процесса в качестве параметра. Что вы хотите:

Marshal.GetActiveObject("Excel.Application");

Обратите внимание, что для этого вообще не требуется отслеживать процесс, он просто должен быть.

Это становится намного сложнее, если у вас может быть несколько процессов и вы хотите подключиться к определенному. Отсюда и ответ на другой вопрос.

Также есть хорошая статья по адресу http://blogs.msdn.com/b/andreww/archive/2008/11/30/starting-or-connecting-to-office-apps.aspx с более полным описанием различных способы запуска excel. Обратите внимание, что не все они обязательно обновлены до Excel 2013, где наличие единого процесса для всех окон Excel усложняет ситуацию. Однако для ваших целей решение GetActiveObject должно подойти.

person Ben Aaronson    schedule 14.05.2014
comment
Вы не отвечаете на вопрос. Дважды запустите Excel. Перейдите в диспетчер задач, и вы найдете два запущенных Excel. В этом случае GetActiveObject возвращает только один (самый старый) запущенный экземпляр. Возвращенный экземпляр может быть не тем, который хочет OP. - person user3454439; 25.08.2015