Получить приложение Excel из идентификатора процесса

Я запускаю приложение Excel, используя класс Process. Я могу получить идентификатор процесса и дескриптор главного окна с помощью приведенного ниже кода.

  Process xlP = Process.Start("excel.exe");
  int id = xlP.Id;
  int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;

Итак, это запускает приложение Excel. Как мне сослаться на этот конкретный экземпляр Excel с идентификатором процесса и дескриптором главного окна?

Я видел здесь похожие вопросы, но ответом была ссылка на веб-страницу, которой больше не существует.

Я в основном хочу что-то вроде ниже.

oExcelApp =  (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");

Пожалуйста, не запускайте приложение Excel с помощью метода Process.Start, нет никаких «но» или «может быть».


person mHelpMe    schedule 12.02.2016    source источник
comment
Что не так с GetActiveObject после Process.Start? По умолчанию будет запущен только один экземпляр Excel. Если существует несколько экземпляров, вам нужно пройти по таблице ROT, получить каждый экземпляр и найти идентификатор процесса из App.HWND   -  person Alex K.    schedule 12.02.2016
comment
@AlexK. Спасибо за ответ. Мы используем Windows 7, и в любой момент может быть открыто несколько экземпляров Excel. Вот почему я подумал, что идентификатор процесса будет полезен, но думаю, что я ошибаюсь. Извините, что такое ROT-таблица? могу сказать, что это ново для меня   -  person mHelpMe    schedule 12.02.2016
comment
Просто любопытно, что вы пытаетесь сделать с открытым документом Excel?   -  person Nick    schedule 12.02.2016
comment
в основном, когда я открываю приложение Excel, мне нужна надстройка (Bloomberg) - единственный способ получить надстройку bloomberg - это использовать метод Process.Start. Затем мне нужно вызвать некоторые функции bloomberg, чтобы проверить некоторые данные. Обычно я использую api bloomberg, однако данные недоступны через api   -  person mHelpMe    schedule 12.02.2016


Ответы (2)


Вы можете использовать следующий код, чтобы получить доступ ко всем запущенным экземплярам Excel и отобразить дескриптор окна, который они используют:

[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

private void button1_Click(object sender, EventArgs e)
{
    IRunningObjectTable lRunningObjectTable = null;
    IEnumMoniker lMonikerList = null;

    try
    {
        // Query Running Object Table 
        if (GetRunningObjectTable(0, out lRunningObjectTable) != 0 || lRunningObjectTable == null)
        {
            return;
        }

        // List Monikers
        lRunningObjectTable.EnumRunning(out lMonikerList);

        // Start Enumeration
        lMonikerList.Reset();

        // Array used for enumerating Monikers
        IMoniker[] lMonikerContainer = new IMoniker[1];

        IntPtr lPointerFetchedMonikers = IntPtr.Zero;

        // foreach Moniker
        while (lMonikerList.Next(1, lMonikerContainer, lPointerFetchedMonikers) == 0)
        {
            object lComObject;
            lRunningObjectTable.GetObject(lMonikerContainer[0], out lComObject);

            // Check the object is an Excel workbook
            if (lComObject is Microsoft.Office.Interop.Excel.Workbook)
            {
                Microsoft.Office.Interop.Excel.Workbook lExcelWorkbook = (Microsoft.Office.Interop.Excel.Workbook)lComObject;
                // Show the Window Handle 
                MessageBox.Show("Found Excel Application with Window Handle " + lExcelWorkbook.Application.Hwnd);
            }
        }
    }
    finally
    {
        // Release ressources
        if (lRunningObjectTable != null) Marshal.ReleaseComObject(lRunningObjectTable);
        if (lMonikerList != null) Marshal.ReleaseComObject(lMonikerList);
    }
}
person NineBerry    schedule 12.02.2016

Добавьте ссылку на Microsoft.Office.Interop.Excel и используйте следующий код:

        Process xlP = Process.Start("excel.exe");
        int id = xlP.Id;
        int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;

        Excel.Application oExcelApp = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");

        if(xlP.MainWindowTitle.Contains( oExcelApp.ActiveWorkbook.Name)   )
        {
            //Proceed further
        }
person stamhaney    schedule 12.02.2016