Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2007, 17:11   #1
=LeonZone=
Форумчанин
 
Аватар для =LeonZone=
 
Регистрация: 15.08.2007
Сообщений: 118
Вопрос Проблема со службой...

Нужно написать службу, которая проверяет запущена ли моя программа и если нет - запускает её. Я сделал через FindWindow и тут появилась проблема... Служба же запускается сразу же с Windows и начитает запускатьмою программу!
Как сделать, чтобы служба запускалась после того, как пользователь войдет в систему? Или как узнать залогинился ли пользователь?
=LeonZone= вне форума Ответить с цитированием
Старый 29.10.2007, 19:24   #2
Tayfun
Форумчанин
 
Аватар для Tayfun
 
Регистрация: 24.06.2007
Сообщений: 351
По умолчанию Запретить запуск второго экземпляра программы

Этот текст должен находиться в модуле проекта (добраться до него можно через меню View/Project Source).

Код:
program Project1;
uses
  Forms,
  Windows, // не забудьте эту строчку
  Unit1 in 'Unit1.pas' {Form1};
{$R *.RES}

var
  HM: THandle;
function Check: boolean;
begin
  HM := OpenMutex(MUTEX_ALL_ACCESS, false, 'MyOwnMutex');

  Result := (HM <> 0);
  if HM = 0 then HM := CreateMutex(nil, false, 'MyOwnMutex');
end;

begin
  if Check then Exit;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.
Попробуй... Может поможет.
Я не маюсь бездельем, я от него тащусь!
Tayfun вне форума Ответить с цитированием
Старый 30.10.2007, 05:05   #3
joker
Форумчанин
 
Регистрация: 23.09.2007
Сообщений: 147
По умолчанию

попробуй ждать пока не появиться проц explorer.exe, а потом подожди ещё секунды две, потом выполняй остальной код службы
вот функция поиска проца

Код:
uses TlHelp32,sysutils,windows;


function ProcessExists(ExeFileName: string): boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  result := false;

  FSnapshotHandle := CreateToolhelp32Snapshot
                     (TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := Sizeof(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle,
                                 FProcessEntry32);

  while integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
         UpperCase(ExeFileName))
     or (UpperCase(FProcessEntry32.szExeFile) =
         UpperCase(ExeFileName))) then
      Result := true;
    ContinueLoop := Process32Next(FSnapshotHandle,
                                  FProcessEntry32);
  end;

  CloseHandle(FSnapshotHandle);
end;

Вот у тя чё должно первым в проекте идти

Код:
repeat
sleep(1000);
until ProcessExists('explorer.exe');
sleep(2000); /////если в начале проги идет обращение к файлам, то 
                /////лучше  ещё немного подождать
Я надеваю тапочки, ищу чем похмелиться, ах, если я сейчас умру, то на... я родился
joker вне форума Ответить с цитированием
Старый 30.10.2007, 19:06   #4
=LeonZone=
Форумчанин
 
Аватар для =LeonZone=
 
Регистрация: 15.08.2007
Сообщений: 118
По умолчанию

2 joker:
Спасибо! Это как-раз то, что мне нужно!!!

А кто-нибудь знает как узнать под каким именем залогинился юзер? Только спотреть нужно не по тому от кого запущена твоя прога, тк из-под службы она запускается как SYSTEM
=LeonZone= вне форума Ответить с цитированием
Старый 31.10.2007, 12:33   #5
Slovinsky
Пользователь
 
Регистрация: 26.10.2007
Сообщений: 79
По умолчанию

Цитата:
Как сделать, чтобы служба запускалась после того, как пользователь войдет в систему?
Я с сервисами сильно дело не имел, но думаю, Вам нужно следить не за пользователями, а за сессиями.
Пусть лучше служба запускается вместе с системой, а момент логина определяет по сообщению WM_WTSSESSION_CHANGE. Для этого создайте в своем сервисе Message-only окошко (ему будут отправляться сообщения) и зарегистрируйте его на получение нотификации о смене сессии (WTSRegisterSessionNotification). Посмотрите этот и смежные разделы:
http://msdn2.microsoft.com/en-us/library/aa383841.aspx

Так вы определите момент входа в систему. И пусть при этом происходит запуск вашей программы. А уже в ней предусмотрите запрет запуска второй копии, например, так:
1. Приложение при запуске пытается создать мьютекс с уникальным именем ('MySuperPuperApplication', например) вызовом CreateMutex
2. Если GetLastError возвращает ERROR_ALREADY_EXISTS, значит приложение уже запущено, выходим из программы. Иначе - продолжаем обычное выполнение.
Slovinsky вне форума Ответить с цитированием
Старый 31.10.2007, 18:57   #6
=LeonZone=
Форумчанин
 
Аватар для =LeonZone=
 
Регистрация: 15.08.2007
Сообщений: 118
По умолчанию

2 Slovinsky:
Спасибо, но вариант joker'а мне как-то ближе...
=LeonZone= вне форума Ответить с цитированием
Старый 01.11.2007, 19:22   #7
=LeonZone=
Форумчанин
 
Аватар для =LeonZone=
 
Регистрация: 15.08.2007
Сообщений: 118
По умолчанию

Как узнать под каким именем залогинился юзер(см. 4й пост)?
Оооочень нужно!
=LeonZone= вне форума Ответить с цитированием
Старый 02.11.2007, 18:37   #8
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  str:array[0..255] of char;
  x:DWORD;
begin
  x:=256;
  GetUserName(@str, x);
  ShowMessage(str);
end;
rpy3uH вне форума Ответить с цитированием
Старый 02.11.2007, 20:14   #9
=LeonZone=
Форумчанин
 
Аватар для =LeonZone=
 
Регистрация: 15.08.2007
Сообщений: 118
По умолчанию

2 rpy3uH:
Если прогу запустить из под сервиса, то имя пользователя будет SYSTEM, а мне нужно узнать РЕАЛЬНОЕ имя...
=LeonZone= вне форума Ответить с цитированием
Старый 03.11.2007, 11:05   #10
Slovinsky
Пользователь
 
Регистрация: 26.10.2007
Сообщений: 79
По умолчанию

Цитата:
Если прогу запустить из под сервиса, то имя пользователя будет SYSTEM, а мне нужно узнать РЕАЛЬНОЕ имя...
Это и есть РЕАЛЬНОЕ имя учетки, от имени которой запущен вызывающий процесс. А вам нужно имя интерактивного пользователя. Вот поэтому я и предлагал следить за сессиями.

Жаль, что вас мой вариант не устроил, там бы этого даже не требовалось, а так - задача становится трудноватой. Код приводить не стану, уж извините. Порядок действий:
1. Чуть-чуть переделайте свою ProcessExists, чтобы вместо true/false возвращался идентификатор просесса.
2. Получаете привилегию SeDebugName, без нее вы не сможете открыть процесс (п.3.)
3. Открываем процесс (OpenProcess) с маской доступа PROCESS_QUERY_INFORMATION
4. Открываем маркер доступа процесса (OpenProcessToken) с флагом TOKEN_QUERY.
5. Вызываем GetTokenInformation с флагом TokenUser
6. Если нужен не SID, а имя пользователя (ума не приложу, зачем), то вызываем LookupAccountSid
7. Закрываем дескриптор маркера и процесса.

PS: Примеры здесь:
http://programmersforum.ru/showthrea...4241#post44241 - в конце - получение привилегий
http://www.delphikingdom.com/asp/vie...catalogid=1322 - теория того, что я вам написал.

Последний раз редактировалось Slovinsky; 03.11.2007 в 11:59.
Slovinsky вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
И ещё проблема с DLL Altera Общие вопросы Delphi 7 25.06.2008 23:45
проблема с службой Pitbull Работа с сетью в Delphi 6 22.06.2008 19:08
проблема bill Свободное общение 7 08.07.2007 21:05
проблема с SQL 5.0.37 Pitbull БД в Delphi 0 15.06.2007 10:31