Форум: "Прочее";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];
Вниз
Контроль приложения с помощью сервиса Найти похожие ветки
← →
defen © (2010-07-23 06:16) [0]Доброго времени суток! Подскажите пожалуйса. Как сделать так, чтобы сервис знал, что моё приложение закрылось?
Пробовал добавлять этот код в приложение и в сервисuses Windows, Forms,
// и всё остальное из dpr-файла
...
var hndl : THandle;
const AppId="POST_MS";
...
begin Hndl:=CreateFileMapping($FFFFFFFF,Nil,PAGE_READONLY,0,1,AppID);
If GetLastError=183
// приложение уже запущено, второй экземпляр не нужен
then exit
else try
Application.Run;
finally
// уничтожаем метку
CloseHandle (Hndl);
end;
end.
CloseHandle (Hndl); Реагирует только на повторный запуск сервиса... Помогите плз...
← →
Юрий Зотов © (2010-07-23 07:07) [1]Хм... а каким образом Вы с помощью этого кода хотели решить задачу "Как сделать так, чтобы сервис знал, что моё приложение закрылось"?
Можно, например, так:
1. В сервисе делаем поток, который вызывает WaitForSingleObject и ждет освобождения любого подходящего объекта синхронизации (например, мьютекса).
2. Периодически (например, раз в несколько секунд) этот поток прерывает ожидание по таймауту и проверяет, не выдал ли SCM команду на завершение сервиса. Если да, то поток завершается.
3. Приложение при старте этот объект синхронизации захватывает, а перед завершением освобождает - таким образом, сервис получает уведомление о завершении.
← →
defen © (2010-07-23 07:29) [2]Спасибо, правда я даже не представляю как это реализовать кодом...
← →
brother © (2010-07-23 07:29) [3]говнокод
← →
defen © (2010-07-23 07:49) [4]
> говнокод
и что это может значить?
← →
brother © (2010-07-23 07:50) [5]оформление бяка - читать, а значит - анализировать ошибки, не удобно...
← →
brother © (2010-07-23 07:51) [6]http://citforum.ru/programming/delphi/style_delphi/
почитай - полезно, и код оформляй сразу правильно, дебаг итд себе и другим облегчишь
← →
defen © (2010-07-23 08:02) [7]
> анализировать ошибки, не удобно...
Скажу так, ошибок в коде нет... И 15 строчек прочитать знающему человеку, как я думаю, не проблема...
← →
defen © (2010-07-23 08:05) [8]на самом деле, я думаю, что приведенный код не совсем соответствует той задаче, которую на него повесили. Код предотвращает запуск второй копии программы, следовательно среагировать на закрытие программы не сможет т.к. значение GetLastError идентичен в обоих случаях...
← →
defen © (2010-07-23 08:14) [9]Есть ещё код для перезапуска приложения, которое уже запущено... Из него можно слепить то, что мне надо? И как?
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,TlHelp32, PsAPI, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hSnapShot,
hProcID: THandle;
pe32: TProcessEntry32;
lpExitCode: Cardinal;
lpProcName: array[0..MAX_PATH - 1] of Char;
const
// Имя искомого процесса
strExplorer: String = "1.exe";
Begin
// Получаем "снимок" процессов
hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
If (hSnapShot = 0) then
// "Снимок" не получен
Exit; // Ошибка
try
// Подготавливаем структуру TProcessEntry32
pe32.dwSize:= sizeof(TProcessEntry32);
// Если есть хоть один процесс, то начинаем цикл
if (Process32First(hSnapShot, pe32)) then
repeat
// Сравниваем имя ехе-файла процесса с искомым
if (LowerCase(pe32.szExeFile) = strExplorer) then
begin
// Получаем хэндл процесса (со всеми правами)
hProcID:= OpenProcess(PROCESS_ALL_ACCESS, false, pe32.th32ProcessID);
// Если хэндл не получен, то завершаем работу
if (hProcID = 0) then
Exit; // Ошибка
try
// Получаем полный путь к программе
GetModuleFileNameEx(hProcID, 0, lpProcName, MAX_PATH);
lpExitCode:= 0;
// Получаем код завершения процесса
if not (GetExitCodeProcess(hProcID, lpExitCode)) then
Exit; // Ошибка
// Завершаем процесс
TerminateProcess(hProcID, lpExitCode);
finally
// Закрываем хэндл процесса
CloseHandle(hProcID);
end;
// Запускаем новый процесс
WinExec(lpProcName, SW_SHOWNORMAL);
// Завершаем цикл
Break;
end;
// Цикл пока есть еще процессы в списке ("снимке")
until not Process32Next(hSnapShot, pe32);
finally
// Закрываем список ("снимок") процессов
CloseHandle(hSnapShot);
end;
end;
← →
defen © (2010-07-23 08:18) [10]код рабочий, есть описание к каждой строчке. Код не мой разобраться, не могу из-за неопытности.
← →
defen © (2010-07-23 08:20) [11]по сути, при отрицательном выполнении условия
if (LowerCase(pe32.szExeFile) = strExplorer) then
надо запускать приложение, так?
← →
Anatoly Podgoretsky © (2010-07-23 08:49) [12]> defen (23.07.2010 08:02:07) [7]
Ну и думай, а мы читать не будем.
← →
Юрий Зотов © (2010-07-23 09:35) [13]> defen
Для неопытного программиста задача "Как сделать так, чтобы сервис знал, что моё приложение закрылось" довольно сложна. И форумы тут вряд ли помогут, потому что нужно знание WinAPI - а объяснять документацию на многие сотни страниц на форуме бесполезно.
Но есть подозрение, что Вам нужна совсем не эта задача. Поэтому предлагаю начать с начала - простыми словами объясните, что Вы хотите сделать. Без всяких терминов, "на пальцах".
← →
sniknik © (2010-07-23 09:35) [14]> И 15 строчек прочитать знающему человеку, как я думаю, не проблема...
читать написанное дерьмом тоже проблем не составляет но неприятно...
аналогия понятна?
← →
defen © (2010-07-23 09:40) [15]Прошу прощения за проявленную невежественность. Вроде всё так, как просили, если нет, поправьте...
uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, Dialogs,
TlHelp32, PsAPI, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
hSnapShot,
hProcID: THandle;
pe32: TProcessEntry32;
lpExitCode: Cardinal;
lpProcName: array[0..MAX_PATH - 1] of Char;
const
strExplorer: String = "1.exe"; // Имя искомого процесса
Begin
hSnapShot:= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // Получаем "снимок" процессов
if (hSnapShot = 0) then // "Снимок" не получен
Exit; // Ошибка
try
pe32.dwSize:= sizeof(TProcessEntry32);// Подготавливаем структуру TProcessEntry32
if (Process32First(hSnapShot, pe32)) then // Если есть хоть один процесс, то начинаем цикл
repeat
if (LowerCase(pe32.szExeFile) = strExplorer) then // Сравниваем имя ехе-файла процесса с искомым
begin
hProcID:= OpenProcess(PROCESS_ALL_ACCESS, false, // Получаем хэндл процесса
pe32.th32ProcessID); //
if (hProcID = 0) then // Если хэндл не получен, то завершаем работу
Exit; // Ошибка
try
GetModuleFileNameEx(hProcID, 0, lpProcName, MAX_PATH); // Получаем полный путь к программе
lpExitCode:= 0; //
if not (GetExitCodeProcess(hProcID, lpExitCode)) then // Получаем код завершения процесса
Exit; // Ошибка
TerminateProcess(hProcID, lpExitCode);// Завершаем процесс
finally
CloseHandle(hProcID); // Закрываем хэндл процесса
end;
WinExec(lpProcName, SW_SHOWNORMAL); // Запускаем новый процесс
Break; // Завершаем цикл
end;
until not Process32Next(hSnapShot, pe32); // Цикл пока есть еще процессы в списке ("снимке")
finally
CloseHandle(hSnapShot); // Закрываем список ("снимок") процессов
end;
end;
← →
defen © (2010-07-23 09:43) [16]
> "на пальцах"
надо, чтобы сервис в случае закрытия программы запускал её снова. Проверку запущенного приложения желательно сделать по таймеру, чтобы можно было при необходимости отключить.
← →
Anatoly Podgoretsky © (2010-07-23 09:50) [17]> defen (23.07.2010 09:40:15) [15]
Дальше этого читать не стал
> private
> public
> end;
← →
Юрий Зотов © (2010-07-23 09:51) [18]
> defen © (23.07.10 09:43) [16]
А разве не проще саму эту программу сделать в виде сервиса? И следить ни за чем не надо будет.
← →
Anatoly Podgoretsky © (2010-07-23 09:52) [19]> defen (23.07.2010 09:43:16) [16]
Мьютех, поиск окна, обмен сообщениями и так далее и далее.
← →
sniknik © (2010-07-23 09:53) [20]>> "на пальцах"
пальцы выпрями.
> в случае закрытия программы запускал её снова
в случае закрытия зачем "убивать" процесс закрытой программы?
Кстати в сервисе начиная с какой-то версии винды, не знаю с какой, столкнулся только в 2008м такой код работать не будет. нужно дополнительно привилегии включать да еще и права системному/тому от кого запустил юзеру "подымать" (не программно, админскими методами).
← →
sniknik © (2010-07-23 09:56) [21]> такой код работать не будет.
+ запуск программы из под сервиса, не равно обычному. она у тебя с интерфейсом? взаимодействует с юзером? если да то нужно запускать в нужном "терминале". если нет то -
> А разве не проще саму эту программу сделать в виде сервиса? И следить ни за чем не надо будет.
← →
defen © (2010-07-23 09:57) [22]Права у пользователей админские
> Юрий Зотов © (23.07.10 09:51) [18]
Не знаю всю прогу прийдется перелопачивать...
← →
Юрий Зотов © (2010-07-23 10:06) [23]
> defen © (23.07.10 09:57) [22]
Так это все равно проще, чем и прогу перелопачивать, да еще и сервис писать.
← →
defen © (2010-07-23 10:08) [24]
> в случае закрытия зачем "убивать" процесс закрытой программы
Есть программа, которая запрещает использование сторонних USB носителей в компании "n", сотрудником которой я евляюсь. Сторонние, значит не находящиеся на учете в конторе (такая уж политика компании)Некоторые продвинутые пользователи вырубали мою програмку с процессов, дабы использовать свои домашние флеш. Было решено скрыть процесс от нежелательных глаз. Все бы ничего, да только Каспер ругается на библиотеку, которую я исользовал, поэтому я решил начать работу с сервисом.
← →
Юрий Зотов © (2010-07-23 10:14) [25]> defen © (23.07.10 09:57) [22]
Если "права у пользователей админские", так они и сервис точно так же срубят, без проблем.
Не в ту сторону копаете. Надо нормальную политику раздачи прав внедрять, а не самопальные затычки делать.
← →
defen © (2010-07-23 10:15) [26]
> Юрий Зотов © (23.07.10 09:51) [18]
Да и время поджимает. Через пару дней надо ввести в эксплуатацию. После буду переделывать непосредственно ввиде сервиса...
← →
sniknik © (2010-07-23 10:15) [27]> Права у пользователей админские
начиная с vista нет "нормальных админских учеток"
← →
defen © (2010-07-23 10:17) [28]Права пользователей ограничены доменом, некоторое СПО, которое мы используем требует локальных админских прав...
← →
Anatoly Podgoretsky © (2010-07-23 10:18) [29]> defen (23.07.2010 09:57:22) [22]
А как тебя будут ругать, когда перейдут на нормальные отношения в сети,
когда у пользователей только пользовательские права.
← →
defen © (2010-07-23 10:18) [30]
> sniknik © (23.07.10 10:15) [27]
Пока рассматривается только WinXP, Win2000 Server и Win2003 Server.
← →
Anatoly Podgoretsky © (2010-07-23 10:19) [31]> defen (23.07.2010 10:15:26) [26]
Знакомая песня.
← →
Anatoly Podgoretsky © (2010-07-23 10:20) [32]> sniknik (23.07.2010 10:15:27) [27]
Я и говорю, хлебнут горя с этой программой.
← →
sniknik © (2010-07-23 10:20) [33]> Если "права у пользователей админские", так они и сервис точно так же срубят, без проблем.
нет. с данным кодом точно будут проблемы.
вот пример, таких проблем
http://delphimaster.net/view/4-1276760569/
тут не показано, но часть из этого решается если дать процессу дебаг привилегию, т.е. тут обсуждали методы "обхода", рабочих решений, но причина в ограниченности прав, где-то на нижнем уровне их "срезали" и функции перестали работать (как понял).
← →
Anatoly Podgoretsky © (2010-07-23 10:20) [34]> defen (23.07.2010 10:17:28) [28]
Нет такого СПО, есть неквалифицированые администраторы.
← →
defen © (2010-07-23 10:21) [35]
> Anatoly Podgoretsky © (23.07.10 10:18) [29]
Не понял суть вопроса.
Сервис можно заставить перезапускать себя при несанкционированном закрытии...
← →
defen © (2010-07-23 10:22) [36]
> Anatoly Podgoretsky © (23.07.10 10:20) [34]
Опрометчивое заявление...
← →
Anatoly Podgoretsky © (2010-07-23 10:45) [37]
> defen © (23.07.10 10:22) [36]
Какие конкретно админстративные функции нужны приложению?
← →
defen © (2010-07-23 10:52) [38]Да вам собственно какая разница? Мы сейчас говорим не о СПО моей компании, а был задан конкретный вопрос, который, в принципе, больше не актуален... Тему можно закрыть...
← →
defen © (2010-07-23 10:54) [39]Чтобы Вам так помогали, как Вы мне...
var
hSnapShot,
hProcID: THandle;
pe32: TProcessEntry32;
lpExitCode: Cardinal;
lpProcName: array[0..MAX_PATH - 1] of Char;
const
strExplorer: String = "1.exe";
begin
check:=false;
hSnapShot:= CreateToolhelp32Snapshot
(TH32CS_SNAPPROCESS, 0);
if (hSnapShot = 0) then
Exit;
try
pe32.dwSize:= sizeof(TProcessEntry32); TProcessEntry32
if (Process32First (hSnapShot, pe32)) then
repeat
if (LowerCase(pe32.szExeFile) = strExplorer) then
check:=true;
until not Process32Next(hSnapShot, pe32);
finally
CloseHandle(hSnapShot);
end;
If check<> True Then
ExecCmd("c:\1.exe",true,false);
end;
← →
Anatoly Podgoretsky © (2010-07-23 11:15) [40]
> defen © (23.07.10 10:52) [38]
Про СПО говоришь ты и если не видишь разницы, то гото в Общее
Страницы: 1 2 вся ветка
Форум: "Прочее";
Текущий архив: 2010.10.31;
Скачать: [xml.tar.bz2];
Память: 0.61 MB
Время: 0.005 c