Короче говоря, ответ, безусловно, да.
Но чтобы вы знали, ваш подход к использованию GetObject для получения существующего приложения Excel пользователя может быть подвержен ошибкам. Если запущено только одно приложение Excel, то GetObject будет работать нормально. Однако если в настоящий момент открыто несколько приложений Excel, вы не можете контролировать, какое приложение Excel возвращается из функции «GetObject» - возвращаемый экземпляр Excel может быть не тем, который вам нужен.
Возможно, вы захотите подумать о создании управляемой надстройки COM, которая запускает в самом приложении Excel и, следовательно, никогда не имеет проблем с тем, «каким» экземпляром приложения Excel он управляет. Чтобы сделать это, вы могли бы начать с просмотра статьи Как создать надстройку Office COM с помощью Visual C # .NET .
Если вам известен идентификатор процесса или дескриптор главного окна (a.k.a. "Hwnd") экземпляра приложения Excel, которым вы хотите управлять, тогда вы сможете получить доступ к этому точному экземпляру. Чтобы узнать, как это сделать, вы можете прочитать обсуждение Эндрю Уайтчепелом темы здесь . Раздел, который вас заинтересует, начинается со строки: «Чтобы заполучить объект приложения Excel, это то, что мы сделаем». Обсуждение немного сложное, но если следовать его коду к букве, оно работает точно так, как описано.
Если вы хотите продолжить работу с подходом «GetObject», то в следующем примере кода используется раннее связывание для получения активного листа запущенного в данный момент приложения Excel. Предполагается, что у вас есть оператор использования using Excel = Microsoft.Office.Interop.Excel
, а также using System.Runtime.InteropServices
в верхней части вашего модуля кода:
// Note:
// using System.Runtime.InteropServices;
// using Excel = Microsoft.Office.Interop.Excel;
Excel.Application excelApp =
Marshal.GetActiveObject("Excel.Application");
object activeSheet = excelApp.ActiveSheet;
Если бы вы использовали позднюю привязку, то это могло бы выглядеть так:
// Note:
// using System.Runtime.InteropServices;
object excelApp =
Marshal.GetActiveObject("Excel.Application");
object activeSheet =
excelApp
.GetType()
.InvokeMember(
"ActiveSheet",
BindingFlags.GetProperty,
null,
excelApp,
null);
Надеюсь, это поможет ...
Последующий ответ:
Привет, даже если запущено несколько приложений Excel. Моя логика - использовать приложение, которое подсвечивается в данный момент, то есть активно в данный момент (с фокусом).
Ах, вы должны были сказать ... В вашем первоначальном вопросе говорится, что вы хотели бы продублировать поведение GetObject
метода, вызванного из VB 6.0. Для этого все ответы, которые вы получили здесь, отвечают правильно.
Итак, во-первых, имейте в виду, что то, о чем вы сейчас спрашиваете, хорошо за возможностями метода GetObject
VB 6.0. Для этого вам необходимо:
- Получить дескриптор окна активного приложения, вызвав функцию GetForegroundWindow Windows API.
- Выполните итерацию всех запущенных в данный момент процессов Excel с помощью Process.GetProcessesByName ("Excel") и сравните Process.MainWindowHandle для каждого запущенного процесса Excel с дескриптором окна, который вы получили ранее, используя API GetForegroundWindow . Предполагая, что у вас есть совпадение, вы подтвердили, что приложение Excel является активным в данный момент. Если совпадений не найдено, то в настоящий момент ни одно приложение Excel не имеет фокуса, и вы можете сообщить об этом пользователю.
- После того как вы подтвердите, что активное окно является запущенным приложением Excel, вы можете использовать дескриптор окна, полученный с помощью API GetForegroundWindow , чтобы получить объект приложения Excel, которым вы можете управлять. Чтобы сделать это, см. Статью Получение объекта приложения в надстройке Shimmed Automation от Эндрю Уайтчепела, начиная с раздела «Как получить объект приложения Excel, это то, что мы сделаем» «. Это сложная тема, но описание в статье отлично, и пример кода работает отлично. Однако в вашем случае вы захотите заменить первую строку кода
int hwnd = (int)Process.GetCurrentProcess().MainWindowHandle;
дескриптором окна активного окна, которое вы нашли ранее. Другими словами, что-то вроде этого: int hwnd = theHwndOfTheActiveWindowYouFoundEarlier
.
Я понимаю, что это много, чтобы переварить, но если вы выполните эти шаги, он будет работать нормально. Самая сложная часть - это код Эндрю Уайтчепела, но он будет работать как есть, за исключением необходимости изменять первую строку. Удачи!
- Майк