Delphi, Asm, C, WinAPI, PHP, ..., FAQ |
Добро пожаловать, гость ( Вход | Регистрация )
Delphi, Asm, C, WinAPI, PHP, ..., FAQ |
-=CHE@TER=- |
Jan 5 2007, 00:35
Сообщение
#1
|
Walter Sullivan Группа: Root Admin Сообщений: 1,361 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 314 раз(а) |
Delphi programs in API.
На английском. Очень подробно всё описано, плюс есть исходные коды готовых юнитов. Например SmallUtil, в котором есть все частоиспользуемые подпрограммы, и который в размере меньше, чем SysUtils (автор так утверждает - я не проверял). |
-=CHE@TER=- |
Jul 7 2007, 16:37
Сообщение
#2
|
Walter Sullivan Группа: Root Admin Сообщений: 1,361 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 314 раз(а) |
Вопрос - кто знает, как по MUTEX'у процесса получить его путь и имя файла? Что-то типа ParamStr(0), только у другого процесса...
Суть в чём: при перезапуске моей программы, нужно чтобы она завершила свою старую копию (если есть) перед загрузкой, чтобы не убивать процесс вручную в TaskManager'е и затем снова запускать. Для убиения процесса используется такая, вот, нелёгкая процедура (потому что TerminateProcess() оставляет иконку в трее - т.е. она просто хлопает процесс, а мне нужно, чтобы он корректно завершился): CODE Function EnumThreadWndProc(Handle: Cardinal; lParam: Integer): LongBool; stdcall; Begin SendMessage(Handle, $0010{WM_CLOSE}, 0, 0); Result:=(lParam<>0); End; Function ProcessClose(FileName: String; bCloseAll: Boolean): Boolean; Var ThreadSearch, ModuleSearch: Cardinal; ThreadEntry: TThreadEntry32; ModuleEntry: TModuleEntry32; Begin result:=False; FileName:=ExtractFileName(FileName); ThreadSearch:=CreateToolHelp32Snapshot(TH32CS_SNAPTHREAD, 0); If ThreadSearch > 0 Then Begin ThreadEntry.dwSize:=SizeOf(TThreadEntry32); If Thread32First(ThreadSearch, ThreadEntry) Then Repeat ModuleSearch:=CreateToolHelp32Snapshot(TH32CS_SNAPMODULE, ThreadEntry.th32OwnerProcessID); If ModuleSearch > 0 Then Begin ModuleEntry.dwSize:=SizeOf(TModuleEntry32); If Module32First(ModuleSearch, ModuleEntry) Then Repeat If lstrcmpi(PChar(ExtractFileName(ModuleEntry.szExePath)), PChar(FileName)) = 0 Then Begin EnumThreadWindows(ThreadEntry.th32ThreadID, @EnumThreadWndProc, Integer(bCloseAll)); result:=True; End; Until (Not Module32Next(ModuleSearch, ModuleEntry)) Or (result); CloseHandle(ModuleSearch); End; Until (Not Thread32Next(ThreadSearch, ThreadEntry)) Or (result); CloseHandle(ThreadSearch); End; End; Имя файла нужно для сравнения с ModuleEntry.szExePath - вдруг, мою программу, переименовали, так что я не могу спускать в функцию ParamStr(0) от текущего процесса. Т.е. была, скажем, программа "A1.EXE", сделали копию "A2.EXE". Теперь пускают "A1.EXE", затем "A2.EXE" - т.к. MUTEX у них один, то вторая должна как-то (т.к. имя уже не совпадает) зная только MUTEX завершить предыдущую. Вообще, пытаюсь сделать такой алгоритм: 1) Производится попытка создать MUTEX с определённым именем 2) Если пришла ошибка GetLastError = ERROR_ALREADY_EXISTS, то убить этот процесс (корректно, как в коде выше, через посылание WM_CLOSE, иначе иконка в трее останется) Кто-нибудь знает как или, возможно, более простой путь решения?.. |
jTommy |
Jul 8 2007, 16:01
Сообщение
#3
|
Наблюдающий Группа: CTPAX-X Сообщений: 197 Регистрация: 4-February 08 Из: деревня Москва Пользователь №: 6 Спасибо сказали: 19 раз(а) |
Вопрос - кто знает, как по MUTEX'у процесса получить его путь и имя файла? Что-то типа ParamStr(0), только у другого процесса... Если я правильно понял ситуация такая: загружена твоя программа, пользователь изменил, например, настройки и надо перезагрузить программу, так?Суть в чём: при перезапуске моей программы, нужно чтобы она завершила свою старую копию (если есть) перед загрузкой, чтобы не убивать процесс вручную в TaskManager'е и затем снова запускать. В таком случае, может-быть так: пользователь жмет "применить", программа создает mutex, запускает второй экземпляр и заканчивает работу (при завершении, в самом конце удаляет mutex). Второй экземпляр находит mutex и ждет, пока он не пропадет. P.S.: А закрыть (корректно) процесс наверное можно, если послать ему сообщение WM_CLOSE или WM_DESTROY. В этом я не уверен - надо проверять. P.P.S.: Кажется я вернулся |
-=CHE@TER=- |
Jul 9 2007, 12:10
Сообщение
#4
|
Walter Sullivan Группа: Root Admin Сообщений: 1,361 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 314 раз(а) |
Если я правильно понял ситуация такая: загружена твоя программа, пользователь изменил, например, настройки и надо перезагрузить программу, так? Нет, всё гораздо хуже - программа при загрузке компьютера загружается и "садится" в SystemTray. А из-за чего я делаю такую хрень с её перезагрузкой - так это из-за того, что при загрузке компа, иногда, проявляется такой баг: программа загрузилась, в процессах есть, а в трее иконки нет. Х.з. из-за чего это. Приходится её перезапускать. В принципе, если бы всё было нормально и иконка всегда появлялась, то с перезагрузкой проги бы проблем не было - я бы просто не давал запускать ещё одну копию и сразу выходил. У меня есть подозрение, что это из-за того, что я держу автозапуск "Run" в HKCU, а не в HKLM, однако, ставить программу на автозапуск для всех пользователей - тупо. Каждый сам должен выбирать нужна она ему или нет.P.S.: А закрыть (корректно) процесс наверное можно, если послать ему сообщение WM_CLOSE или WM_DESTROY. В этом я не уверен - надо проверять. Handle'у процесса посылал WM_CLOSE - без толку. Это только формам посылать надо - как я сейчас и делаю. WM_DESTROY не пробовал.P.P.S.: Кажется я вернулся Welcome back! Хорошо отдохнул? (*улыбается*) |
-=CHE@TER=- |
Aug 22 2014, 11:14
Сообщение
#5
|
Walter Sullivan Группа: Root Admin Сообщений: 1,361 Регистрация: 4-February 08 Пользователь №: 3 Спасибо сказали: 314 раз(а) |
Нет, всё гораздо хуже - программа при загрузке компьютера загружается и "садится" в SystemTray. А из-за чего я делаю такую хрень с её перезагрузкой - так это из-за того, что при загрузке компа, иногда, проявляется такой баг: программа загрузилась, в процессах есть, а в трее иконки нет. Х.з. из-за чего это. Приходится её перезапускать. Бардак на корабле! © Попугай из Пиратов Карибского моря. Надо разбираться, так не должно быть. Как оказалось, это не я дурак, а кривая реализация в Windows (выделение моё):QUOTE First is a timeout of 4 seconds, raised to 7 in Windows Vista. Second is that delivery is aborted if the target process seems hung. According to Microsoft's documentation, this means that the target hasn't been seen to pick up any messages for at least 5 seconds. © Missing Icons in Notification Area <...> Experiments with Windows XP confirm that the taskbar window can be busy for more than a minute during startup, most notably because of network discovery. |
Упрощённая версия | Сейчас: 5th November 2024 - 17:25 |