На faqmakers доступ не для всех.. Надо попросить dl-я, чтобы выложил уже, если замечаний нет.24.05.04 18:36 Число просмотров: 1769 Автор: !mm <Ivan Ch.> Статус: Elderman
В продолжение темы:
А чем отличаются сервисы, от обычнх приложений?
Наскоко трудно переделать обычную прогу в сервис - наверно нужно поддерживать некий специфический интерфейс?
Кстати, наскоко я понимаю запускать приложения в качестве сервиса пожет токо супер пользователь?
О супер пользователе.15.05.04 01:27 Автор: void <Grebnev Valery> Статус: Elderman
> Кстати, наскоко я понимаю запускать приложения в качестве > сервиса пожет токо супер пользователь?
Терминологически неверно.
"...супер пользователь ...", это термин, который определяет полномочия пользователя в Российских, как правило, сертифицированных ГТК приложениях, типа сикретнет, аккорд и т.д., которые при определённых обстоятельствах и требованиях могут устанавливаются в том числе и на W2k.
В NT и W2k пользуются другой терминологией.
[Win32] Хых, руки у мадемуазель зачесались ;-)14.05.04 19:47 Автор: HandleX <Александр М.> Статус: The Elderman Отредактировано 18.05.04 08:04 Количество правок: 5
> В продолжение темы: > А чем отличаются сервисы, от обычнх приложений? > Наскоко трудно переделать обычную прогу в сервис - наверно > нужно поддерживать некий специфический интерфейс? Итак, службы... Да, поддерживают они особый интерфейс для "общения" с Service Control Manager'ом.
SCM их и запускает, исходя из того, какие параметры имеются в записи реестра об этой службе. Между
прочим, SCM запускает также и драйверы, поэтому "захват власти" над SCM является лакомой добычей
хакеров и вирусов, поскольку именно оттуда они могут запустить драйвер ядра. А драйвер ядра может
поиметь абсолютно полный контроль над системой.
Но написание драйверов ядра задача не для слабонервных. И не всякий компилятор сможет это
сделать. К примеру, Delphi даже при создании простейшего *.exe, который запускается и тут же
выходит, запихивает в него некий run-time, который использует user-mode API, и запуск
такого "драйвера" вызовет ошибку. Вообще, я не слышал, чтобы драйверы компилировали на
чём-нибудь отличном от M$ VC.
Однако вернёмся к user-mode службам. Сперва службу нужно написать ;-) Там всё просто, в MSDN есть
примеры ;-) Поскольку службу запускает SCM, он некоторое время ждёт, когда служба вызовет
StartServiceCtrlDispatcher(), параметром этой функции является массив из записей вида
"Имя службы-Точка входа в MainServiceProc), из чего делаем вывод, что в одном исполняемом файле
службы может "содержаться" несколько служб. Интересно, что возврат из StartServiceCtrlDispatcher()
происходит только после остановки всех прописанных в этом вызове служб. Если
StartServiceCtrlDispatcher() возвращает false, значит что-то не так, и поможет GetLastError() ;-)
Итак, если всё в порядке, SCM запускает новый поток и в конце концов передаёт управление на
ServiceMain(). В этой функции программист должен первым делать зарегистрировать свою функцию
ServiceControlHandler(), в которую SCM будет "кидать" сообщения о том, что нужно делать службе -
запуститься, перейти в паузу, выйти из паузы, остановиться и проч. Необходимо сказать о
многопоточности. ServiceControlHandler() и ServiceMain() исполняются в отдельных потоках, это нужно
учитывать. Но это и кое-что облегчает... Часто программисты для перевода службы в "паузу" просто
исполняют SuspendThread() для потока ServiceMain(), а с помощью ResumeThread восстанавливают
работу службы. Сервис может "отчитываться" SCM о своём состоянии, докладывать ему об ошибках
во время запуска, "говорить" SCM о том, какие "команды" он может в данный момент воспринимать.
В частности, службу можно запрограммировать так, что остановить её после запуска, или загнать в
паузу, будет невозможно, эдакий "неубиваемый" сервис... Единственное, его можно грохнуть через
TerminateProcess(), но это отдельная история...
И вот, "скелет" службы создан, и руки чешутся нажать на кнопку "Run" компилятора... Однако спешка
нужна сами знаете где... Теперь службу нужно "прописать" в систему. Нужно или в самой программе
службы встроить реакцию на скажем, параметр командной строки типа -install либо написать
программу-установщик, которая зарегистрирует службу в системе. Делается это при помощи вызова
функций API OpenSCManager() и CreateService(), внимательное изучение параметров этих двух функций
поможет понять как управлять и инсталлировать службы, а также какие они бывают и когда SCM будет
их запускать. К примеру, можно указать SCM автоматический запуск службы во время старта OS, или
ручной, или вообще отключить службу...
Ну и наконец, после того, как служба инсталлирована в систему, можно попробовать её запустить...
Делается это встроенным в OS "запускателем" командной строки net start ИмяСлужбы или через
оснастку управления службами.
Отладка служб тоже занятие не для слабонервных ;-) Однако есть подсказки от M$ о том, как это делается.
> Кстати, наскоко я понимаю запускать приложения в качестве > сервиса пожет токо супер пользователь? При вызове функции OpenSCManager() одним из параметров является уровень доступа к службам...
По умолчанию обычный пользователь не может установить службу. А вот дальше доступ
(сможет ли пользователь запустить, остановить или даже удалить уже прописанную службу) задаётся
после создании службы при помощи функции SetServiceObjectSecurity(), иныим словами для каждой
службы можно сконфигурировать любой Список Контроля Доступа для любых пользователей и групп в системе.
Ну как, после всего вышесказанного не отпало желание написать службу? ;-)
Для интересующихся и начинающих изучать программирование приведу пример простейшей службы на
Delphi, которая может себя устанавливать и удалять, при запуске "пикает" в системный спикер, может
войти в паузу и быть остановлена.
Успехов.
program SimpleServ;
{$APPTYPE CONSOLE}
uses Windows, WinSVC; //Не используем SysUtils и прочий хлам - размер екзешника у нас будет всего ~25 килобайт
Function IsWin2KorHigher: BOOL;
Var aVer: OSVERSIONINFO;
Begin
ZeroMemory(@aVer, SizeOf(aVer));
aVer.dwOSVersionInfoSize := SizeOf(aVer);
GetVersionEx(aVer);
Result := (aVer.dwPlatformId = VER_PLATFORM_WIN32_NT) And (aVer.dwMajorVersion >= 5);
End;
Const
ServicesCount = 1;
ServiceName = 'SimpleServ';
DisplayName = 'Simple Service';
ServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceDescription = 'SimpleServ from Handlex ;-))) This simple program will help you to understand WinNT Services. Mail to alex_wh@mail.ru.';
Var
ServThrHndl: THandle = 0;
StopEvent: THandle = 0;
aServHndl: DWord = 0;
aServStatus: SERVICE_STATUS;
Function IntToStr(Value: Integer): String; //Included because we don't use SysUtils
Var aSign: Bool;
Begin
Result := '';
aSign := Value >= 0;
If Not aSign Then Value := -Value;
Repeat
Result := Char(Value - (Value Div 10) * 10 + Byte('0')) + Result;
Value := Value Div 10;
Until Value = 0;
If Not aSign Then Result := '-' + Result;
End;
// Helper function for windows error strings
function SysErrorMessage(ErrorCode: Integer): string; //Included because we don't use SysUtils
var
Len: Integer;
Buffer: array[0..255] of Char;
begin
Len := FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM or
FORMAT_MESSAGE_ARGUMENT_ARRAY, nil, ErrorCode, 0, Buffer,
SizeOf(Buffer), nil);
while (Len > 0) and (Buffer[Len - 1] in [#0..#32]) do Dec(Len);
SetString(Result, Buffer, Len);
UniqueString(Result);
ANSItoOEM(PChar(Result), PChar(Result));
If Result <> '' Then
Result := '(' + IntToStr(ErrorCode) + ') ' + Result;
end;
Procedure ShowInfo;
Begin
WriteLn;
WriteLn(' -=* SIMPLE TRAINING SERVICE BY HandleX *=-');
End;
Procedure ProcessStartupParams; //Реакция на install, uninstall
Function SetServiceDescription(aSHndl: THandle; aDesc: String): Bool; //Устанавливает "описание" для службы, Win2k и выше
Const SERVICE_CONFIG_DESCRIPTION: DWord = 1;
Var
DynChangeServiceConfig2: Function(
hService: SC_HANDLE; // handle to service
dwInfoLevel: DWORD; // information level
lpInfo: Pointer): Bool; StdCall; // new data
aLibHndl: THandle;
TempP: PChar;
Begin
aLibHndl := GetModuleHandle(advapi32);
Result := aLibHndl <> 0; If Not Result Then Exit;
DynChangeServiceConfig2 := GetProcAddress(aLibHndl, 'ChangeServiceConfig2A');
Result := @DynChangeServiceConfig2 <> Nil; If Not Result Then Exit;
TempP := PChar(aDesc); //ChangeServiceConfig2 хочет вместо строки указатель на указатель ;-)
Result := DynChangeServiceConfig2(aSHndl, SERVICE_CONFIG_DESCRIPTION, @TempP);
End;
Type
TToDo = (tdError, tdInstall, tdUninstall);
TToDo_s = Set of TToDo;
Const
ParamStrings: Array[tdInstall..tdUninstall] of String = ('install', 'uninstall');
Function MapParam(aParam: String): TToDo; //Узнаёт из параметра о вашем желании ;-)
Var
J: TToDo;
TempStr: String;
Begin
Result := tdError;
TempStr := aParam;
If TempStr[1] In ['/', '-'] Then
TempStr := Copy(TempStr, 2, Length(TempStr) - 1);
UniqueString(TempStr);
CharLower(PChar(TempStr));
For J := Low(ParamStrings) to High(ParamStrings) Do
If ParamStrings[J] = TempStr Then
Begin
Result := J;
Exit;
End;
End;
Var
J: Integer;
scHndl, sHndl: THandle;
aStatus: TServiceStatus;
toDo: TTodo_s;
Begin
toDo := [];
For J := 1 to ParamCount Do
Begin
Include(ToDo, MapParam(ParamStr(J)));
If tdError in toDo Then
Begin
ExitCode := ERROR_INVALID_PARAMETER;
WriteLn('Unknown parameter - ' + ParamStr(J) + '. RTFM, please...');
Exit;
End;
End;
If [tdInstall, tdUninstall] <= toDo Then
Begin
ExitCode := ERROR_INVALID_PARAMETER;
WriteLn('Error: you can not install and uninstall service simultaniosly. Check params.');
Exit;
End;
If tdInstall in toDo Then //Устанавливаем сервис
Begin
Write('Connecting Service Control Manager...');
scHndl := OpenSCManager(Nil, Nil, SC_MANAGER_CREATE_SERVICE);
If scHndl = 0 Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
Try
WriteLn('Ok');
Write('Creating service database record...');
sHndl := CreateService(
SCHndl, ServiceName, DisplayName,
SERVICE_QUERY_CONFIG Or SERVICE_CHANGE_CONFIG, ServiceType, SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL, PChar(ParamStr(0)), Nil, Nil, Nil, Nil, Nil);
If sHndl = 0 Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
Try
WriteLn('Ok');
If ServiceDescription <> '' Then
Begin
Write('Setting service description...');
If Not SetServiceDescription(sHndl, ServiceDescription) Then
Begin
WriteLn('Failed!');
WriteLn('Warning: ', SysErrorMessage(GetLastError));
WriteLn('Warning: SetServiceDesc() failed, but service is installed!');
End;
WriteLn('Ok');
End;
Finally
CloseServiceHandle(sHndl);
End;
Finally
CloseServiceHandle(SCHndl);
End;
WriteLn('Service "', DisplayName, '" install success.');
End;
If tdUninstall in toDo Then //Удаляем сервис...
Begin
Write('Connecting Service Control Manager...');
scHndl := OpenSCManager(Nil, Nil, GENERIC_EXECUTE);
If scHndl = 0 Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!');
WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
Try
WriteLn('Ok');
Write('Opening and Quering Service...');
sHndl := OpenService(SCHndl, ServiceName, STANDARD_RIGHTS_REQUIRED Or SERVICE_QUERY_STATUS Or SERVICE_STOP);
If sHndl = 0 Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
Try
If Not QueryServiceStatus(sHndl, aStatus) Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
WriteLn('Ok');
If aStatus.dwCurrentState <> SERVICE_STOPPED Then
Begin
Write('Service is running, wait until stopped...');
If Not ControlService(sHndl, SERVICE_CONTROL_STOP, aStatus) Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
While aStatus.dwCurrentState <> SERVICE_STOPPED Do
Begin
Sleep(250); Write('.');
If Not QueryServiceStatus(sHndl, aStatus) Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
End;
WriteLn('Stopped');
End;
Write('Deleting Service...');
If Not DeleteService(sHndl) Then
Begin
ExitCode := GetLastError;
WriteLn('Failed!'); WriteLn('Error: ', SysErrorMessage(ExitCode));
Exit;
End;
WriteLn('Ok');
Finally
CloseServiceHandle(sHndl);
End;
Finally
CloseServiceHandle(SCHndl);
End;
WriteLn('Service uninstall success.');
End;
End;
Function SetState(aState: DWORD): DWORD;
Begin
aServStatus.dwCurrentState := aState;
If aServHndl <> 0 Then
SetServiceStatus(aServHndl, aServStatus);
Result := aServStatus.dwCurrentState;
End;
Procedure ServiceHandler(fdwControl: DWORD); StdCall;
Begin
Case fdwControl Of
SERVICE_CONTROL_STOP: Begin //Requests the service to stop.
SetState(SERVICE_STOP_PENDING);
SetEvent(StopEvent);
ResumeThread(ServThrHndl); //Если сервис был в паузе, то рабочий поток надо возобновить
End;
SERVICE_CONTROL_PAUSE: Begin //Requests the service to pause.
SetState(SERVICE_PAUSE_PENDING);
SuspendThread(ServThrHndl); //Останавливаем рабочий поток сервиса
SetState(SERVICE_PAUSED);
End;
SERVICE_CONTROL_CONTINUE: Begin //Requests the paused service to resume.
SetState(SERVICE_CONTINUE_PENDING);
ResumeThread(ServThrHndl); //Восстанавливаем рабочий поток сервиса
SetState(SERVICE_RUNNING);
End;
SERVICE_CONTROL_INTERROGATE: Begin //Requests the service to update immediately its current status information to the service control manager.
SetState(aServStatus.dwCurrentState); //Говорим SCM о том, в каком состоянии находится наша служба
End;
128..255: Begin //The service defines the action associated with the control code.
SuspendThread(ServThrHndl); //Протяжно пищим в спикер, потому что кто-то послал USER DEFINED CONTROL CODE ;-)
Windows.Beep(1000, 500);
ResumeThread(ServThrHndl);
End;
End;
End;
Procedure MainServiceProc( // Каждая служба может иметь параметры своего запуска. У нас не используется ;-)
dwArgc: DWORD; // number of arguments
lpszArgv: Pointer); StdCall // array of arguments
Begin
aServHndl := RegisterServiceCtrlHandler(ServiceName, @ServiceHandler);
If aServHndl = 0 Then
Begin
ExitCode := GetLastError;
Exit; //Какая-то ошибка, срочно выходим, SCM будет ругаться, но сообщить мы ему ничего не можем...
End;
ZeroMemory(@aServStatus, SizeOf(aServStatus));
aServStatus.dwServiceType := ServiceType;
aServStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP Or SERVICE_ACCEPT_PAUSE_CONTINUE;
//aServStatus.dwWaitHint := 500; //Здесь может быть подсказка для небыстрых служб о том, как долго она реагирует на команды
SetState(SERVICE_START_PENDING); //Извещаем SCM, что мы начали стартовать именно этот сервис...
// Тут идёт рутина инициализации...
If Not DuplicateHandle(GetCurrentProcess, GetCurrentThread, GetCurrentProcess, @ServThrHndl, 0, FALSE, DUPLICATE_SAME_ACCESS) Then
Begin //Нам нужен реальный дескриптор потока службы, делаем его...
aServStatus.dwWin32ExitCode := GetLastError;
SetState(SERVICE_STOPPED);
Exit;
End;
//Нам нужен unnamed event для реагирования на останов из ControlHandler...
StopEvent := CreateEvent(Nil, True, False, Nil);
If StopEvent = 0 Then //Какая-то ошибка - срочно останавливаемся и выходим...
Begin
aServStatus.dwWin32ExitCode := GetLastError;
SetState(SERVICE_STOPPED);
Exit;
End;
// Инит прошёл, пошла работа сервиса...
SetState(SERVICE_RUNNING); //Момент истины - извещаем SCM что мы работаем!!!
While WaitForSingleObject(StopEvent, 500) = WAIT_TIMEOUT Do
Windows.Beep(10000, 10); //Крутим цикл, бипаем по таймауту, иначе выходим...
// Выполняем остановку сервиса - вычищаемся и выходим...
CloseHandle(ServThrHndl);
ServThrHndl := 0;
CloseHandle(StopEvent);
StopEvent := 0;
SetState(SERVICE_STOPPED); // Работа сервиса закончена...
End;
Var
ServTableEntryArray: Array[0..ServicesCount] Of TServiceTableEntryA;
begin
{$R *.res}
//Старт программы...
If ParamCount > 0 Then //От нас что-то хотят...
Begin
ShowInfo;
ProcessStartupParams; //Выясняем что и выходим...
Exit;
End;
//Готовимся к вызову StartServiceCtrlDispatcher
ZeroMemory(@ServTableEntryArray, SizeOf(ServTableEntryArray));
ServTableEntryArray[0].lpServiceName := ServiceName;
ServTableEntryArray[0].lpServiceProc := @MainServiceProc;
If Not StartServiceCtrlDispatcher(ServTableEntryArray[0]) Then
Begin
ExitCode := GetLastError;
ShowInfo; //Какой-то косяк, поэтому выводим в консоль сообщение и выходим...
WriteLn('Error: ', SysErrorMessage(ExitCode));
WriteLn('This program is Windows NT Service, so it CAN NOT be run from command prompt.');
WriteLn('You can install it with "/install" parameter.');
Exit;
End;
// Все сервисы завершили свою работу, выходим...
end.
---
Ешё раз спасибо за код!!! Да пашет, классно. ;-)))
24.05.04 06:57 Автор: void <Grebnev Valery> Статус: Elderman
> Я туда кстати, специально для тебя про Security целый абзац > + пример программы привёл... Дерзай! ;-) Не открывается ссылка. :(
А у тебя есть FAQ Makers в списке досок? Зайди туда, там про службы должен быть он последним... dl пообещал скоро в FAQ выложить...24.05.04 18:22 Автор: HandleX <Александр М.> Статус: The Elderman
Хороший постинг. Думаю, если подчистить, так и статья неплохая получилась бы. Код есть, что привлекательно.
Один вопрос. Может ли интерактивный сервис создать окно (конечно, что бы туду что-нибудь написать в ответ на ControlService() ) на рабочем столе удалённой рабочей станции интерактивного пользователя.
Спрашиваю, потому, как не уверен. Буквально день назад тема немного обсуждалась на одном из форумов. По своей некомпетентности я , дай, да пропостил следующее:
[quote]Думаю, что нет. По крайней мере без гимора. Но могу ошибаться.
Интерактивный сервис имеет доступ к рабочему столу интерактивного пользователя для рабочей станции Winsta0, если она пущена под учётной записью LocalSystem и имеет флаг SERVICE_INTERACTIVE_PROCESS. Известно, что даже для служб к которым пользователь интерактится при помощи Terminal Services W2k - глючно. То, что ты удалённо можешь посылать коды пользовательских команд - понятно (хотя даже здесь в общем случае не так всё розово. могу ошибаться поскольку я как всегда несколько передёргиваю задачу). Но вот писать, как ты хочешь, служба будет .... куда? Думаю, никуда. Нет у неё доступа к твоему рабочему столу. Она ничего не знает про твой рабочий стол и процессы на нём. Она знает только рабочие столы своего компа. Служба не сможет по твоей команде (она-то доедет) создать на твоём рабочем столе окно и написать туда чего-нибудь. [/quote]
Вопрос - прав я, или мне всю жизнь теперь жить с этим позором.
Второе. Не могли бы Вы указать ссылку на примеры назначения прав группам пользователей на доступ к служдам при помощи SetServiceObjectSecurity(). В MSDN есть описание интерфейса функции. Примеров не обнаруживается.
Спасибо.
Если я правильно понимаю суть проблемы, то при наличии...19.05.04 09:22 Автор: amirul <Serge> Статус: The Elderman
> Один вопрос. Может ли интерактивный сервис создать окно > (конечно, что бы туду что-нибудь написать в ответ на > ControlService() ) на рабочем столе удалённой рабочей > станции интерактивного пользователя. Если я правильно понимаю суть проблемы, то при наличии нужных привелегий, установить для удаленной станции и десктопа нужные права проблем не составит.
Собственно вот даже пример есть:
http://msdn.microsoft.com/library/en-us/security/security/starting_an_interactive_client_process_in_c__.asp Тут правда открывается WinSta0 и ее десктоп, но что мешает заменить ее любой другой?
Проблема в другом. Человек хотел узнать, может ли сервис вывести GUI на рабочий стол пользователя, который конролирует этот сервис при помощи ControlService() с удалённой машины. Однозначно не может... Пользователь слишком далеко ;-)19.05.04 19:18 Автор: HandleX <Александр М.> Статус: The Elderman
Да, Вы совершенно правильно поняли мой вопрос. И меня радует, что несмотря на практическое полное отсутствие знаний у меня, я случайно пропосил на том форуме верно ;))) Повезло ;)))
Но, вот меня смутил ответ amirul, которому я верю, как себе ;))) Без иронии. Он сказал и указал пример MSDN, что принципиально сервис на удалённом хосте 1 может получить доступ к объекту рабочей станции WinSta0 и ёе рабочему столу интерактивного пользователя на хосте 2:
(HOST1-> servce) -> (HOST2-> WinSta0->DeskTop).
Вопрос, если это так, то может ли тогда ?:
1) сервис хоста1 создать процесс на хосте 2 , затем в этом процессе создать окно (CreateWindow) и туда чего-нибудь пропостить. Грубо говоря удалённый пользователь увидит на десктопе своего компа новое окно, созданное сервисом удалённого хоста.
2) сервис хоста1 посылать сообщения в очередь сообщений windows хоста 2 с тем, чтобы некая програ хоста 2 анализировала эти wParam, lParam сообщения
Спасибо.
Я думаю, что amirul другое имел ввиду...20.05.04 10:03 Автор: HandleX <Александр М.> Статус: The Elderman
> (HOST1-> servce) -> (HOST2-> WinSta0->DeskTop). Нет, так нельзя.
А по ссылке пример того, как подключится к оконной станции интерактивного пользователя... Но код исполняется _на той же машине_. Т.е. рабочая станция и оконная станция разные вещи ;-)
> Вопрос, если это так, то может ли тогда ?: > 1) сервис хоста1 создать процесс на хосте 2 , затем в этом > процессе создать окно (CreateWindow) и туда чего-нибудь > пропостить. Грубо говоря удалённый пользователь увидит на > десктопе своего компа новое окно, созданное сервисом > удалённого хоста. Нет. На той другой удалённой станции уже что-то должно быть запущено, чтобы "подчинятся".
> 2) сервис хоста1 посылать сообщения в очередь сообщений > windows хоста 2 с тем, чтобы некая програ хоста 2 > анализировала эти wParam, lParam сообщения Я думаю проще сделать GUI в отдельной программе, а «квинтэссенцию мудрости» работы этой программы передавать или через ControlService, или через NamedPipe, открытой сервисом.
> же машине_. Т.е. рабочая станция и оконная станция разные > вещи ;-)
Да, конечно, описался (виндовс стайшен). Имелось ввиду воркстайшен--виндовсстатйшен--десктоп :)))
Спасибо за ответ. Для меня это было важно, чтобы в в будущем не пойти по неверному пути.
ControlSirvices не поможет, т.к. нужно не только посылать сообщения пользователя сервису, но и получать удалённо некоторую информацию.
Конечно, именоваными каналами здорово, Вы правы. Но, можно было б и с сокетами. Это было б более универсально, устойчиво и для разных сеток, в которых сервис и управляющий клиент расположены по разные стороны межсетевого экрана. Могу ошибаться, конечно. Проже были б ACL. Нет? Но вот беда, с аунитнификацией в случае сокетов придётся всё самому делать. Как думаете?
Спасибо.
[Win32] еще gcc вроде умеет дрова виндовые компилить17.05.04 19:44 Автор: amirul <Serge> Статус: The Elderman
> Просветите плиз дуру грешную ;) > > Собственно, как написать прогу под windows которая не > открывает никаких окон? > > А то вот все пишу и пишу, и все с окноми, но ведь наверняка > есть возможность работы без окон? Короче много трепа тут вокруг милой дамы.