Как да се определи надеждно, че програмата се изпълнява като услуга

Как да се определи надеждно, че програмата се изпълнява като услуга?

Бях някъде в моя пример, но той дърпа потребителското име, с което услугата се изпълнява, и го сравнява с името, под което е стартиран процеса. По стечение на обстоятелствата - както ние услуга. Но един и същи потребител, не означава, че нашият процес - услуга. Услугата може да се управлява от името на друг uchetki, така че този метод е отстранен. Как да се определи кой процес се изпълнява мениджъра на услугата, а не някой друг?








> Как да се определи кой процес се изпълнява мениджъра на услугата,
> # XA0; а не някой друг

Смятате ли, че ако отида в конзолата за управление и услугата се изпълнява, той ще бъде изготвен от мое име?


> Услугата може да се управлява от името на друг uchetki така
> Този метод елиминира
Не е много подходящо казва. Ще се поправи:

Процесът може да се управлява от едно и също име, а именно на услугата, а след това равнение на имената дават неточен резултат.


> Смятате ли, че ако отида в конзолата за управление и
> Service работи, той ще бъде изготвен от мое име?

Настройките на услуги могат да бъдат отнесени към нито един uchetku използва за изпълнение на услугата. Въпреки, че по силата на посетителя да се изпълнява. И това ще бъде не едно и също нещо, ще се очаква да съвсем различно поведение на програмата, отколкото ако гостът след като той започва програмата. Ето и нещо.

Ако не да ги смесва, а след това, когато стартирате "като услуга" програма получава специален. параметри (или от спец. наричат-назад "и потрепване? напълно забравени).
И така, въпросът не е ясно: на програмата, ако услугата - работи изцяло по определен начин.

PS
ръката не е мястото, където да се търси бързо, но се надявам, че аз не лъжа


> И какво? Zapuskatsya то ще по никакъв managery случай обслужване

Ти не разбираш :) Потребителят може, например, в Windows Explorer и изпълнете .exe да вземете със себе услуга. И това не е нещо, което трябва да бъде)

Какво е всичко: напиши услуга, която трябва да работи стриктно под uchetki възложената му. Но вие трябва да отстраняване на грешки, така че той може да работи и като услуга и като нормална програма, малко регулиране на вътрешната логика. По-късно, когато се приближава към края, ще трябва да се забрани пускането на друг, освен на услуги.

> Ти си в услугата е необходимо да се определи под чийто uchetki тя работи, но не и да се определи, когато услугата се изпълнява.
и как след това с опцията, ако тя се управлява като програма? uchetki не разбера, тъй като може да се стартира от всеки, единственият вариант е да се намери някой, който да споделите (от) стартиране на програмата.
т.е. "Когато услугата работи" само определя дали дадена услуга или програма.

ние говорим за споделяне и съответно разклонения код, в зависимост от това как програмата ще започне като услуга или като програма.
например, можем да видим scktsrvr.exe (има източник) в Делфи, това е метод за определянето им (за това, което той не винаги се определи в дясно).
> Имаше някъде моя пример
там със сигурност.

пфу палачинка. Ами разделят на концепцията за услуги и приложения. доста объркан. )

typedef структура _SYSTEM_PROCESS_INFORMATION # XA0; # XA0; ULONG NextEntryOffset;
# XA0; # XA0; ULONG NumberOfThreads;
# XA0; # XA0 битове Reserved1 [48];
# XA0; # XA0; PVOID Reserved2 [3];
# XA0; # XA0; ТРЕТИРА UniqueProcessId;
# XA0; # XA0; PVOID Reserved3;
# XA0; # XA0; ULONG HandleCount;
# XA0; # XA0 битове Reserved4 [4];
# XA0; # XA0; PVOID Reserved5 [11];
# XA0; # XA0; size_t PeakPagefileUsage;
# XA0; # XA0; size_t PrivatePageCount;
# XA0; # XA0; LARGE_INTEGER Reserved6 [6];
> SYSTEM_PROCESS_INFORMATION;

Тогава няма какво да се чудят. Просто завърши отстраняване на грешки.

Дръжката трябва да има права за достъп на PROCESS_QUERY_INFORMATION и PROCESS_VM_READ

Като цяло, ние имаме код. интересуват критика

функция GetProcessParentID: кардинал;
Var
# XA0; ProcEntry: TProcessEntry32;
# XA0; hSnapshot: THandle;
# XA0; CurrID: кардинал;
# XA0; Успех: Булева;
започвам
# XA0; Резултати: = 0;
# XA0; hSnapshot: = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
# XA0; ако (hSnapshot <> INVALID_HANDLE_VALUE) след това
# XA0; # XA0; опитате
# XA0; # XA0; # XA0; ProcEntry.dwSize: = SizeOf (ProcEntry);
# XA0; # XA0; # XA0; успех: = Process32First (hSnapshot, ProcEntry);
# XA0; # XA0; # XA0; ако успех след това
# XA0; # XA0; # XA0; започне
# XA0; # XA0; # XA0; # XA0; CurrID: = GetCurrentProcessId;
# XA0; # XA0; # XA0; # XA0; SetLastError (ERROR_SUCCESS);
# XA0; # XA0; # XA0; # XA0, докато успех правя
# XA0; # XA0; # XA0; # XA0; # XA0; ако (ProcEntry.th32ProcessID = CurrID) след това
# XA0; # XA0; # XA0; # XA0; # XA0; започне
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Резултат: = ProcEntry.th32ParentProcessID;






# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Break;
# XA0; # XA0; # XA0; # XA0; # XA0; край
# XA0; # XA0; # XA0; # XA0; # XA0; останало
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; успех: = Process32Next (hSnapshot, ProcEntry);
# XA0; # XA0; # XA0; край;
# XA0; # XA0; # XA0; Win32Check (GetLastError);
# XA0; # XA0; накрая
# XA0; # XA0; # XA0; CloseHandle (hSnapshot);
# XA0; # XA0; край
# XA0; останало
# XA0; # XA0; Win32Check (GetLastError);
приключи;

функция GetProcessParentName: низ;
Var
# XA0; ProcEntry: TProcessEntry32;
# XA0; hSnapshot: THandle;
# XA0; Успех: Булева;
# XA0; ParentPID: кардинал;
започвам
# XA0; Резултат: = "";
# XA0; hSnapshot: = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0);
# XA0; ако (hSnapshot <> INVALID_HANDLE_VALUE) след това
# XA0; # XA0; опитате
# XA0; # XA0; # XA0; ProcEntry.dwSize: = SizeOf (ProcEntry);
# XA0; # XA0; # XA0; успех: = Process32First (hSnapshot, ProcEntry);
# XA0; # XA0; # XA0; ако успех след това
# XA0; # XA0; # XA0; започне
# XA0; # XA0; # XA0; # XA0; ParentPID: = GetProcessParentID;
# XA0; # XA0; # XA0; # XA0; SetLastError (ERROR_SUCCESS);
# XA0; # XA0; # XA0; # XA0, докато успех правя
# XA0; # XA0; # XA0; # XA0; # XA0; ако (ProcEntry.th32ProcessID = ParentPID) след това
# XA0; # XA0; # XA0; # XA0; # XA0; започне
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Резултат: = ProcEntry.szExeFile;
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; Break;
# XA0; # XA0; # XA0; # XA0; # XA0; край
# XA0; # XA0; # XA0; # XA0; # XA0; останало
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; успех: = Process32Next (hSnapshot, ProcEntry);
# XA0; # XA0; # XA0; край;
# XA0; # XA0; # XA0; Win32Check (GetLastError);
# XA0; # XA0; накрая
# XA0; # XA0; # XA0; CloseHandle (hSnapshot);
# XA0; # XA0; край
# XA0; останало
# XA0; # XA0; Win32Check (GetLastError);
приключи;

# XA0; # XA0; # XA0; CloseServiceHandle (SVC);
# XA0; # XA0; край;
# XA0; # XA0; CloseServiceHandle (монс);
# XA0; край;
приключи;

процедура Win32Check (ERRORCODE: кардинал);
започвам
# XA0; ако (ERRORCODE <> ERROR_SUCCESS) след това
# XA0; # XA0; повиши Win32Exception.Create (SysErrorMessage (ERRORCODE));
приключи;

Можете да опитате да предаде на клавиша линия старт.
Това е, ако не се научат да работят с услуги и управление на услугата

> По принцип имаме код. интересуват критика
Вие плащате за реда? тогава всичко е наред, добре. но като цяло има Rouse_ предложим по-компактен, интуитивен опция, която не струва нищо да се промени.
Но в този случай

функция ParentProcName: низ;
конст
# XA0; ProcessBasicInformation = 0;
Var
# XA0; Инфо: PROCESS_BASIC_INFORMATION;
# XA0; dwProcessHandle: DWORD;
# XA0; ProcessName: низ;
# XA0; Hndl: THandle;
започвам
# XA0; Резултат: = "Noname";
# XA0; dwProcessHandle: = GetCurrentProcess;
# XA0; ако NtQueryInformationProcess (dwProcessHandle, ProcessBasicInformation, @Info, SizeOf (Info), нула) = NO_ERROR
# XA0; # XA0; след това да започне
# XA0; # XA0; # XA0; Hndl: = OpenProcess (PROCESS_QUERY_INFORMATION или PROCESS_VM_READ, False, Info.uInheritedFromUniqueProcessId);
# XA0; # XA0; # XA0; ако Hndl <> 0 след това
# XA0; # XA0; # XA0; # XA0; опитате
# XA0; # XA0; # XA0; # XA0; # XA0; SetLength (ProcessName, MAX_PATH);
# XA0; # XA0; # XA0; # XA0; # XA0; ако GetModuleBaseNameA (Hndl, 0, PChar (ProcessName), MAX_PATH)> 0
# XA0; # XA0; # XA0; # XA0; # XA0; # XA0; след това Резултат: = PChar (ProcessName);
# XA0; # XA0; # XA0; # XA0; накрая
# XA0; # XA0; # XA0; # XA0; # XA0; CloseHandle (Hndl);
# XA0; # XA0; # XA0; # XA0; край;
# XA0; # XA0; край;
приключи;

замества две трети от своя код.

> Защо roditelstkie обработва Suka - това не ми е ясно.
ако не само за отстраняване на грешки, ако програмата е написана като примера, даден от мен по-рано Borland програма.


> Run - тя регистрира своя призив-назад и всичко. и
> Не може да бъде нищо друго, освен за услуга, по дефиниция,

Може би :) услуга - това е един и същ процес, и не се различава от традиционния метод, с изключение на това започна и се управлява от управителя на системата.


> Това замества две трети от своя код

Така че това е вярно, но в допълнение към червените предупрежденията за NtQueryInformationProcess, там е друга точка, която аз също спомена:

Дръжката трябва да има права за достъп на PROCESS_QUERY_INFORMATION и PROCESS_VM_READ

Това, както и GetModuleFileNameEx # XA0 отнася също до GetModuleBaseName. Погледнете MSDN, ако не вярвате. И на услугата, не забравяйте, не е задължително да има тези права, защото това може да се управлява от всеки потребител.

> Дръжката трябва да има права за достъп на PROCESS_QUERY_INFORMATION и PROCESS_VM_READ
Ето защо те са тук и се изисква
Hndl: = OpenProcess (PROCESS_QUERY_INFORMATION или PROCESS_VM_READ False, Info.uInheritedFromUniqueProcessId).
защото дръжката трябва да ги има.

и с NtQueryInformationProcess. там се иска INFA собствен процес, че е смешно, ако правото не е дори да чете. това не може да бъде.

всички права за четене на информация, на IMHO, има дори гост. се провери, като се започне своята услуга от потребители с гости привилегии. в версии на този код с / без него.
но по правата на двустранен процес snepshot за тяхното четене на информация не е необходимо? Той е също така да го прочетете.

> Тъй като това може да се управлява от всеки потребител.
дори и тогава логиката не мога. Самата услуга за своята услуга трябва да бъде нещо, което на човека. и те са, IMHO, повече, отколкото е необходимо, за да прочете името на модула.


> Ето защо те са тук и се изисква
И това е така поради ограничените права juzverej OpenProcess връща Достъпът е отказан, когато се опитва да отвори процеса родител.


> Има се иска INFA собствен процес
Защо аз притежавам? Имам нужда от родител. PID получавам родителя, но името на родителския файл - само чрез ToolHelp, който работи от ограничен uchetki.


> Проверка чрез стартиране на услугата си от потребители с гости привилегии
Аз го имам от самото начало и са направили :) Въпреки това, не за гости, но под специален uchetki, който се състои от група от потребители. Право на NT / ZwHHH функции не е тестван, но на GetModuleFileNameEx и GetModuleBaseName спъна веднага. След моментна снимка на всичко се оказа, без да задава въпроси.

Между другото, аз работя тук и с правата. Оказа се, че обявената nepravilno.BuildExplicitAccessWithName и GetSecurityInfo неправилно обявен на Borland няколко функции. И до BuildExplicitAccessWithName още видях функции, които един постфиксната W са PAnsiChar параметри.


> Установено е, че Borland обяви няколко функции правилно.
> BuildExplicitAccessWithName и GetSecurityInfo неправилно
> Обявени. И до BuildExplicitAccessWithName все още се гледа
> Функция, която с Postfix W са PAnsiChar параметри.
>

И слънцето има петна.

Не малко, но много, и се коригират или бавно или никога.