31.08.2016, 20:42 | #1 |
Участник
|
hwnd --> pid
Привет всем.
Есть метод X++: static container GetWindowThreadProcessId(HWND _hwnd) { container ret = [0.0]; DLL _DLL = new DLL('USER32'); DLLFunction dllFunction = new DLLFunction(_DLL, 'GetWindowThreadProcessId'); Binary lpdwProcessId = new Binary(#SizeOfInt); int pid; ; dllFunction.returns(ExtTypes::DWord); // DWORD WINAPI dllFunction.arg(ExtTypes::DWord); // _In_ HWND hWnd, dllFunction.arg(ExtTypes::Pointer); // _Out_opt_ LPDWORD lpdwProcessId pid = dllFunction.call(_hwnd, lpdwProcessId); if (pid) { ret = [pid, lpdwProcessId.dWord(0)]; } return ret; } /* [url]https://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396[/url] DWORD WINAPI GetWindowThreadProcessId( _In_ HWND hWnd, _Out_opt_ LPDWORD lpdwProcessId ); Parameters hWnd [in] Type: HWND A handle to the window. lpdwProcessId [out, optional] Type: LPDWORD A pointer to a variable that receives the process identifier. If this parameter is not NULL, GetWindowThreadProcessId copies the identifier of the process to the variable; otherwise, it does not. Return value Type: Type: DWORD The return value is the identifier of the thread that created the window. */ Он позволяет по hwnd окна определить pid. Мы его используем для определения pid процесса excel c которым работаем через com или .net (com объект возвращает hwnd через который мы данным методом получаем pid). Соответственно если есть куча Excel то можно найти концы - понять какой com объект породил проблему и оставил зависший Excel после построения отчета. Хочется переписать его на .Net Может кто-нибудь подскажет как этот код переписать так, чтобы он работал на сервере? |
|
31.08.2016, 22:03 | #2 |
Британский учённый
|
Я бы попробовал через Process.GetProcessesByName. Excel не позволяет открывать два разных файла с одним именем, т.е. можно получить процесс по имени, а потом вызвать kill().
__________________
Людям физического труда для восстановления своих сил нужен 7-8 часовой ночной сон. Людям умственного труда нужно спать часов 9-10. Ну а программистов будить нельзя вообще. |
|
|
За это сообщение автора поблагодарили: Logger (5). |
31.08.2016, 23:49 | #3 |
Участник
|
Я решаю другую проблему.
Моя задача не поубивать Excel не глядя. А понять среди нескольких десятков зависших Excel-ей на сервере - каким кодом аксапты они порождены, чтобы этот кривой код вылечить (реально есть несколько сотен выгрузок в Excel - нужно понять какая гадит). Пока хочется при создании SysExcel или ComExcelDocument_RU просто писать в лог стек вызовов и pid процесса excel. Ну и может еще какую полезную инфу. Тогда можно быстро находить проблемные места в коде и лечить их. |
|
01.09.2016, 00:08 | #4 |
Участник
|
Позволяет если это разные экземпляры Excel
В моем случае это либо com объект Excel либо .Net обертка над Excel. Они приводят к созданию нового инстанса Excel. Но по достижению какого то числа Excel-ей (сколько то десятков) новые уже не создаются, а выскакивает ошибка. В общем идет "утечка" Excel-ей пока не затопит. Последний раз редактировалось Logger; 01.09.2016 в 00:11. |
|
01.09.2016, 07:36 | #5 |
Участник
|
Будет ли ваш HWND равен Process.MainWindowHandle ? Или если excel скажем скрыт (visible = false), то окна у процесса вообще не будет? Хотя если есть HWND, то должно быть и окно. Будет ли оно основным для процесса?
Если будет, то тогда можно перебрать все процессы и найти нужный. Или тот же самый отбор сделать через скрипт PowerShell (System.Management.Automation) http://stackoverflow.com/questions/4...rom-com-object Цитата:
(Get-Process -Name iexplore)| Where-Object {$_.MainWindowHandle -eq $ie.HWND}
|
|
|
За это сообщение автора поблагодарили: Logger (5). |
01.09.2016, 11:35 | #6 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Будет ли ваш HWND равен Process.MainWindowHandle ? Или если excel скажем скрыт (visible = false), то окна у процесса вообще не будет? Хотя если есть HWND, то должно быть и окно. Будет ли оно основным для процесса?
Если будет, то тогда можно перебрать все процессы и найти нужный. Или тот же самый отбор сделать через скрипт PowerShell (System.Management.Automation) http://stackoverflow.com/questions/4...rom-com-object Набросал джобик X++: static void _2(Args _args) { SysExcelApplication SysExcelApplication; hwnd hwnd; System.Diagnostics.Process[] pr; System.Diagnostics.Process proc; int pCount; int i; str toString; str procName; int id; System.IntPtr mainWindowHandle; int iMainWindowHandle; int64 i64MainWindowHandle; System.IntPtr handle; int iHandle; container getWindowThreadProcessId(HWND _hwnd) { #define.sizeOfInt(4) container ret = [0, 0]; DLL _DLL = new DLL('USER32'); DLLFunction dllFunction = new DLLFunction(_DLL, 'GetWindowThreadProcessId'); Binary lpdwProcessId = new Binary(#SizeOfInt); int pid; ; dllFunction.returns(ExtTypes::DWord); // DWORD WINAPI dllFunction.arg(ExtTypes::DWord); // _In_ HWND hWnd, dllFunction.arg(ExtTypes::Pointer); // _Out_opt_ LPDWORD lpdwProcessId pid = dllFunction.call(_hwnd, lpdwProcessId); if (pid) { ret = [pid, lpdwProcessId.dWord(0)]; } return ret; } ; //SysExcelApplication = SysExcelApplication_NET::construct(); SysExcelApplication = SysExcelApplication::construct(); hwnd = SysExcelApplication.HWND(); info(strFMT("%1", hwnd)); info(con2str(GetWindowThreadProcessId(hwnd))); pr = System.Diagnostics.Process::GetProcesses(); pCount = pr.get_Length(); for (i = 1; i < pCount; i++) { proc = pr.GetValue(i); toString = proc.ToString(); procName = proc.get_ProcessName(); id = proc.get_Id(); mainWindowHandle = proc.get_MainWindowHandle(); iMainWindowHandle = mainWindowHandle.ToInt32(); i64MainWindowHandle = mainWindowHandle.ToInt64(); handle = proc.get_Handle(); iHandle = handle.ToInt32(); info(con2str([ id, imainWindowHandle, i64MainWindowHandle, ihandle, procName, toString ])); } // [url]http://www.cyberforum.ru/csharp-beginners/thread4966.html[/url] } это X++: //pkoz 31.08.2016 HWND HWND() { return application.Hwnd(); } А цикл по System.Diagnostics.Process::GetProcesses() возвращает почти везде нулевой get_MainWindowHandle() что очень странно. Т.е. при использовании перебора всех System.Diagnostics.Process из под аксапты - не получается одновременно получить pid и hwnd и, соответственно, не получается связать их. Последний раз редактировалось Logger; 01.09.2016 в 11:38. |
|
Теги |
com-объект, excel, excel com формат, hwnd, pid |
|
|