Как сделать, чтобы сервис при старте имел argc>=2?
От: yaroslav_v http://yaroslav-v.chat.ru
Дата: 13.12.01 08:53
Оценка:
Как сделать, чтобы сервис при старте получал командную строку?

Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.
если его запустит user, то exe-шник должен вывести диалог.
Думаю отличать user'а от системы анализируя командную строку.
User может просто запустить exe-шник — без параметров.
Пока есть лишь решение сделать exe-шник скрытым, а поставлять
*.lnk-файл с командной строкой типа "file.exe /user", а сервис
будет по-прежнему стартоваться системой без параметров.
Второе решение — можно видимо смотреть, кто нас запустил и соответственно
действовать.
Re: Как сделать, чтобы сервис при старте имел argc>=2?
От: TSS Россия http://www.sdl.ru
Дата: 13.12.01 09:05
Оценка:
Здравствуйте yaroslav_v, Вы писали:

YV>Как сделать, чтобы сервис при старте получал командную строку?


YV>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

YV>если его запустит user, то exe-шник должен вывести диалог.

Когда система запускает твою службу, то вызов StartServiceCtrlDispatcher () успешен, когда ты поднимаешь екзешник руками -- то нет. Вот и вся проверка.
Signed, [TSS] /SDL/
Re[2]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Аноним  
Дата: 13.12.01 11:03
Оценка:
Здравствуйте TSS, Вы писали:

TSS>Здравствуйте yaroslav_v, Вы писали:


YV>>Как сделать, чтобы сервис при старте получал командную строку?


YV>>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

YV>>если его запустит user, то exe-шник должен вывести диалог.

TSS>Когда система запускает твою службу, то вызов StartServiceCtrlDispatcher () успешен, когда ты поднимаешь екзешник руками -- то нет. Вот и вся проверка.

именно т.к. сервис тоже можно запускать с параметрами =)
вот пример кода, который я использовал для подобной реализации. НО она отличается низким быстродействием при запуске как экзешника. т.к. вышеупомянутая функция при запуске не как сервис тормозит очень сильно.
причина моей реализации была : СОМ-компонент, который запущенный как сервис регистрирует себя. зачем это нужно было — для регистрации компонентов на удаленной машине.
вот кусок кода.
// ServiceSample.cpp : Defines the entry point for the console application.
//

#include "dcomservice.h"
#include "process.h"
#ifndef __dcomservice_cpp__
namespace DCOMService
{

long init(_TCHAR* servicename)
{
_TCHAR* m_commandline = new _TCHAR[1024];
m_commandline = ::GetCommandLine();
char* m_char = new char[1024];
sprintf (m_char,"%S",m_commandline);
SvcDebugOut(m_char,0);
m_servicename = new _TCHAR[wcslen(servicename)];
wcscpy(m_servicename,servicename);
SvcDebugOut("In main()",::GetLastError());
sprintf (m_char,"%S",m_servicename);
SvcDebugOut(m_char,0);
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ m_servicename, &ServiceStart },
{ NULL, NULL }
};
SvcDebugOut("Starting Dispatcher",::GetLastError());
if (!StartServiceCtrlDispatcher( DispatchTable))
{
char * m_char = new char [256];
sprintf(m_char,"[%S] StartServiceCtrlDispatcher error =",m_servicename);
long err = ::GetLastError();
SvcDebugOut(m_char, err);
return err;
}
return 0;

}
void __stdcall SvcDebugOut(LPSTR String, DWORD Status)
{
#ifdef _DEBUG
long err = ::GetLastError();
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
_TCHAR* m_path = new _TCHAR[1024];
swprintf(m_path,L"%s",m_servicename);
FILE * file = _wfopen (m_path,L"a");
if (file !=NULL ){
fprintf(file,"\n--\n%s %d\n--\n",String,Status);
fclose (file);
};
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
::SetLastError(err);
}
#endif //_DEBUG
}


void __stdcall ServiceStart (DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;

ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SvcDebugOut("in ServiceStart",::GetLastError());
ServiceStatusHandle = RegisterServiceCtrlHandler(
m_servicename,
ServiceCtrlHandler);

if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut("RegisterServiceCtrlHandler failed %d\n", GetLastError());
return;
}

// Initialization code goes here.
status = ServiceInitialization(argc,argv, &specificError);
SvcDebugOut("Status",status);
// Handle error condition
if (status != NO_ERROR)
{
SvcDebugOut("Handling Error Condition",status);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = status;
ServiceStatus.dwServiceSpecificExitCode = specificError;

SetServiceStatus (ServiceStatusHandle, &ServiceStatus);
return;
}

// Initialization complete — report running status.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SvcDebugOut("Compliting Initialization",ServiceStatus.dwCurrentState);

if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}

// This is where the service does its work.
SvcDebugOut("Returning the Main Thread \n",0);

return;
}

// Stub initialization function.
DWORD ServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError)
{
argv;
argc;
specificError;
// return(0);
m_thread=_beginthread(MainThread,0,NULL);
if (m_thread==-1){ return (-1) ;}
SvcDebugOut("Created Main Thread:",m_thread);
if (NULL == (htermevent = CreateEvent(NULL,TRUE,FALSE,_T("breakevent")))){
SvcDebugOut("Can't Register Event",0);
};
if (!ResetEvent(htermevent)){ SvcDebugOut("Can't Reset Event",0);} ;

return (0);
}
void __stdcall ServiceCtrlHandler (DWORD Opcode)
{
DWORD status;
SvcDebugOut("in ServiceCtrlHandler opcode is " ,Opcode);
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.

ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:
ServiceStop();
// Do whatever it takes to stop here.
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (ServiceStatusHandle,
&ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}

SvcDebugOut("Leaving Service \n",0);
return;

case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;

default:
SvcDebugOut("Unrecognized opcode %ld\n", Opcode);
}

// Send current status.
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}
return;
}
void ServiceStop ()
{
SetEvent(htermevent);
}
long SelfStop(_TCHAR *service)
{
SC_HANDLE scm_handle = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm_handle == NULL ) {return ::GetLastError();};
SC_HANDLE service_handle = ::OpenService(scm_handle,service,SERVICE_STOP);
if (service_handle == NULL) {::CloseServiceHandle(scm_handle);return ::GetLastError();};
SERVICE_STATUS svc_status;
memset (&svc_status,0,sizeof(SERVICE_STATUS));
long err = ::ControlService(service_handle,SERVICE_CONTROL_STOP,&svc_status);
if (err == 0 ) {::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);return ::GetLastError();};
::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);
return 0;

}
long SelfDelete(_TCHAR *service)
{
SC_HANDLE scm_handle = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm_handle == NULL ) {return ::GetLastError();};
SC_HANDLE service_handle = ::OpenService(scm_handle,service,DELETE|SERVICE_QUERY_STATUS|SERVICE_STOP );
if (service_handle == NULL) {::CloseServiceHandle(scm_handle);return ::GetLastError();};
long err = ::DeleteService(service_handle);
if (err == 0 ) {::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);return ::GetLastError();};
::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);
HKEY m_reg;
if (RegConnectRegistry(NULL,HKEY_LOCAL_MACHINE,&m_reg) ==ERROR_SUCCESS){
// HKEY m_key;
SvcDebugOut("After Connect Registry",::GetLastError());
_TCHAR * m_regkey = new _TCHAR[1024];
char * testchar = new char[2048];
swprintf(m_regkey,L"SYSTEM\\CurrentControlSet\\Services\\%s",service);
sprintf(testchar,"%S",m_regkey);
SvcDebugOut(testchar,0);
err = SHDeleteKey(m_reg,m_regkey);
SvcDebugOut("After SHDeleteKey",err);
}
return 0;

}

void _cdecl MainThread (void* inputparms)
{
HKEY m_reg;
long err;
if (RegConnectRegistry(NULL,HKEY_LOCAL_MACHINE,&m_reg) ==ERROR_SUCCESS){
HKEY m_key;
err = RegCreateKey(m_reg,L"SOFTWARE\\Lokki",&m_key);
SvcDebugOut("CreateKey ",err);
err = RegSetValueEx(m_key,L"test",0,REG_SZ,(LPBYTE)L"Installed",sizeof("Installed")*2);
SvcDebugOut("After SetValue",err);
SvcDebugOut("In Main thread",0);
_TCHAR** arg= new _TCHAR*[];
int z;
arg=CommandLineToArgvW(GetCommandLine(),&z);
char * cmdline = new char[1024];
sprintf (cmdline,"%S /regserver",arg[0]);
SvcDebugOut("Before register",0);
SvcDebugOut(cmdline,0);
err = system(cmdline);
SvcDebugOut("After register",err);
SvcDebugOut("Before Sleep",0);
Sleep(10000);
SvcDebugOut("After Sleep,Before Delete",0);
err = SelfDelete(m_servicename);
SvcDebugOut("After Delete,Before Stop",0);
Sleep(10000);
err = SelfStop(m_servicename);
SvcDebugOut("After SelfStop",err);

}
}
}
#define __dcomservice_cpp__
#endif
Re[2]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Lokki Зимбабве  
Дата: 13.12.01 11:04
Оценка:
Здравствуйте TSS, Вы писали:

TSS>Здравствуйте yaroslav_v, Вы писали:


YV>>Как сделать, чтобы сервис при старте получал командную строку?


YV>>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

YV>>если его запустит user, то exe-шник должен вывести диалог.

TSS>Когда система запускает твою службу, то вызов StartServiceCtrlDispatcher () успешен, когда ты поднимаешь екзешник руками -- то нет. Вот и вся проверка.

именно т.к. сервис тоже можно запускать с параметрами =)
вот пример кода, который я использовал для подобной реализации. НО она отличается низким быстродействием при запуске как экзешника. т.к. вышеупомянутая функция при запуске не как сервис тормозит очень сильно.
причина моей реализации была : СОМ-компонент, который запущенный как сервис регистрирует себя. зачем это нужно было — для регистрации компонентов на удаленной машине.
вот кусок кода.
// ServiceSample.cpp : Defines the entry point for the console application.
//

#include "dcomservice.h"
#include "process.h"
#ifndef __dcomservice_cpp__
namespace DCOMService
{

long init(_TCHAR* servicename)
{
_TCHAR* m_commandline = new _TCHAR[1024];
m_commandline = ::GetCommandLine();
char* m_char = new char[1024];
sprintf (m_char,"%S",m_commandline);
SvcDebugOut(m_char,0);
m_servicename = new _TCHAR[wcslen(servicename)];
wcscpy(m_servicename,servicename);
SvcDebugOut("In main()",::GetLastError());
sprintf (m_char,"%S",m_servicename);
SvcDebugOut(m_char,0);
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ m_servicename, &ServiceStart },
{ NULL, NULL }
};
SvcDebugOut("Starting Dispatcher",::GetLastError());
if (!StartServiceCtrlDispatcher( DispatchTable))
{
char * m_char = new char [256];
sprintf(m_char,"[%S] StartServiceCtrlDispatcher error =",m_servicename);
long err = ::GetLastError();
SvcDebugOut(m_char, err);
return err;
}
return 0;

}
void __stdcall SvcDebugOut(LPSTR String, DWORD Status)
{
#ifdef _DEBUG
long err = ::GetLastError();
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
_TCHAR* m_path = new _TCHAR[1024];
swprintf(m_path,L"%s",m_servicename);
FILE * file = _wfopen (m_path,L"a");
if (file !=NULL ){
fprintf(file,"\n--\n%s %d\n--\n",String,Status);
fclose (file);
};
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
::SetLastError(err);
}
#endif //_DEBUG
}


void __stdcall ServiceStart (DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;

ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SvcDebugOut("in ServiceStart",::GetLastError());
ServiceStatusHandle = RegisterServiceCtrlHandler(
m_servicename,
ServiceCtrlHandler);

if (ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut("RegisterServiceCtrlHandler failed %d\n", GetLastError());
return;
}

// Initialization code goes here.
status = ServiceInitialization(argc,argv, &specificError);
SvcDebugOut("Status",status);
// Handle error condition
if (status != NO_ERROR)
{
SvcDebugOut("Handling Error Condition",status);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwWin32ExitCode = status;
ServiceStatus.dwServiceSpecificExitCode = specificError;

SetServiceStatus (ServiceStatusHandle, &ServiceStatus);
return;
}

// Initialization complete — report running status.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
SvcDebugOut("Compliting Initialization",ServiceStatus.dwCurrentState);

if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}

// This is where the service does its work.
SvcDebugOut("Returning the Main Thread \n",0);

return;
}

// Stub initialization function.
DWORD ServiceInitialization(DWORD argc, LPTSTR *argv, DWORD *specificError)
{
argv;
argc;
specificError;
// return(0);
m_thread=_beginthread(MainThread,0,NULL);
if (m_thread==-1){ return (-1) ;}
SvcDebugOut("Created Main Thread:",m_thread);
if (NULL == (htermevent = CreateEvent(NULL,TRUE,FALSE,_T("breakevent")))){
SvcDebugOut("Can't Register Event",0);
};
if (!ResetEvent(htermevent)){ SvcDebugOut("Can't Reset Event",0);} ;

return (0);
}
void __stdcall ServiceCtrlHandler (DWORD Opcode)
{
DWORD status;
SvcDebugOut("in ServiceCtrlHandler opcode is " ,Opcode);
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.

ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:
ServiceStop();
// Do whatever it takes to stop here.
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (ServiceStatusHandle,
&ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}

SvcDebugOut("Leaving Service \n",0);
return;

case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;

default:
SvcDebugOut("Unrecognized opcode %ld\n", Opcode);
}

// Send current status.
if (!SetServiceStatus (ServiceStatusHandle, &ServiceStatus))
{
status = GetLastError();
SvcDebugOut("SetServiceStatus error %ld\n",status);
}
return;
}
void ServiceStop ()
{
SetEvent(htermevent);
}
long SelfStop(_TCHAR *service)
{
SC_HANDLE scm_handle = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm_handle == NULL ) {return ::GetLastError();};
SC_HANDLE service_handle = ::OpenService(scm_handle,service,SERVICE_STOP);
if (service_handle == NULL) {::CloseServiceHandle(scm_handle);return ::GetLastError();};
SERVICE_STATUS svc_status;
memset (&svc_status,0,sizeof(SERVICE_STATUS));
long err = ::ControlService(service_handle,SERVICE_CONTROL_STOP,&svc_status);
if (err == 0 ) {::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);return ::GetLastError();};
::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);
return 0;

}
long SelfDelete(_TCHAR *service)
{
SC_HANDLE scm_handle = ::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
if (scm_handle == NULL ) {return ::GetLastError();};
SC_HANDLE service_handle = ::OpenService(scm_handle,service,DELETE|SERVICE_QUERY_STATUS|SERVICE_STOP );
if (service_handle == NULL) {::CloseServiceHandle(scm_handle);return ::GetLastError();};
long err = ::DeleteService(service_handle);
if (err == 0 ) {::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);return ::GetLastError();};
::CloseServiceHandle(scm_handle);::CloseServiceHandle(service_handle);
HKEY m_reg;
if (RegConnectRegistry(NULL,HKEY_LOCAL_MACHINE,&m_reg) ==ERROR_SUCCESS){
// HKEY m_key;
SvcDebugOut("After Connect Registry",::GetLastError());
_TCHAR * m_regkey = new _TCHAR[1024];
char * testchar = new char[2048];
swprintf(m_regkey,L"SYSTEM\\CurrentControlSet\\Services\\%s",service);
sprintf(testchar,"%S",m_regkey);
SvcDebugOut(testchar,0);
err = SHDeleteKey(m_reg,m_regkey);
SvcDebugOut("After SHDeleteKey",err);
}
return 0;

}

void _cdecl MainThread (void* inputparms)
{
HKEY m_reg;
long err;
if (RegConnectRegistry(NULL,HKEY_LOCAL_MACHINE,&m_reg) ==ERROR_SUCCESS){
HKEY m_key;
err = RegCreateKey(m_reg,L"SOFTWARE\\Lokki",&m_key);
SvcDebugOut("CreateKey ",err);
err = RegSetValueEx(m_key,L"test",0,REG_SZ,(LPBYTE)L"Installed",sizeof("Installed")*2);
SvcDebugOut("After SetValue",err);
SvcDebugOut("In Main thread",0);
_TCHAR** arg= new _TCHAR*[];
int z;
arg=CommandLineToArgvW(GetCommandLine(),&z);
char * cmdline = new char[1024];
sprintf (cmdline,"%S /regserver",arg[0]);
SvcDebugOut("Before register",0);
SvcDebugOut(cmdline,0);
err = system(cmdline);
SvcDebugOut("After register",err);
SvcDebugOut("Before Sleep",0);
Sleep(10000);
SvcDebugOut("After Sleep,Before Delete",0);
err = SelfDelete(m_servicename);
SvcDebugOut("After Delete,Before Stop",0);
Sleep(10000);
err = SelfStop(m_servicename);
SvcDebugOut("After SelfStop",err);

}
}
}
#define __dcomservice_cpp__
#endif
Re[3]: Как сделать, чтобы сервис при старте имел argc>=2?
От: TSS Россия http://www.sdl.ru
Дата: 13.12.01 12:04
Оценка: 8 (2)
Здравствуйте Lokki, Вы писали:

YV>>>Как сделать, чтобы сервис при старте получал командную строку?


Задать в свойствах службы / в реестре.

YV>>>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

YV>>>если его запустит user, то exe-шник должен вывести диалог.

TSS>>Когда система запускает твою службу, то вызов StartServiceCtrlDispatcher () успешен, когда ты поднимаешь екзешник руками -- то нет. Вот и вся проверка.


L>именно т.к. сервис тоже можно запускать с параметрами =)


Это к чему ?
У службы есть две функции которые можно "запустить с параметрами". Одна из них -- main (argc, argv), которая вызываеться из C/C++ Runtime. Вторая -- ServiceMain (argc, argv), вызываемая через StartService.
Это разные функции с разными параметрами. Одни (для main) задаються в командной строке (например при CreateProcess), другие в реестре, которые находяться в реестре и используються MMC (например) при запуске службы через StartService ()

P.S. См. MSDN на предмет описания main() и StartService ()
Signed, [TSS] /SDL/
Re[4]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Lokki Зимбабве  
Дата: 13.12.01 12:08
Оценка:
Здравствуйте TSS, Вы писали:

TSS>Здравствуйте Lokki, Вы писали:


YV>>>>Как сделать, чтобы сервис при старте получал командную строку?


TSS>Задать в свойствах службы / в реестре.


YV>>>>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

YV>>>>если его запустит user, то exe-шник должен вывести диалог.

TSS>>>Когда система запускает твою службу, то вызов StartServiceCtrlDispatcher () успешен, когда ты поднимаешь екзешник руками -- то нет. Вот и вся проверка.


L>>именно т.к. сервис тоже можно запускать с параметрами =)


TSS>Это к чему ?

TSS>У службы есть две функции которые можно "запустить с параметрами". Одна из них -- main (argc, argv), которая вызываеться из C/C++ Runtime. Вторая -- ServiceMain (argc, argv), вызываемая через StartService.
TSS>Это разные функции с разными параметрами. Одни (для main) задаються в командной строке (например при CreateProcess), другие в реестре, которые находяться в реестре и используються MMC (например) при запуске службы через StartService ()

TSS>P.S. См. MSDN на предмет описания main() и StartService ()

я говорю о проблеме определения — как сервис мы или нет.
если использовать соглашение, что
argv[1]=="Service"
argv[1]=="Prog"
то это всё же не гарантирует , что программа запущена как сервис потому, что можно сделать cmd.exe /c prog.exe Service
Re[5]: Как сделать, чтобы сервис при старте имел argc>=2?
От: TSS Россия http://www.sdl.ru
Дата: 13.12.01 13:23
Оценка:
Здравствуйте Lokki, Вы писали:

TSS>>Это к чему ?

TSS>>У службы есть две функции которые можно "запустить с параметрами". Одна из них -- main (argc, argv), которая вызываеться из C/C++ Runtime. Вторая -- ServiceMain (argc, argv), вызываемая через StartService.
TSS>>Это разные функции с разными параметрами. Одни (для main) задаються в командной строке (например при CreateProcess), другие в реестре, которые находяться в реестре и используються MMC (например) при запуске службы через StartService ()

TSS>>P.S. См. MSDN на предмет описания main() и StartService ()

L>я говорю о проблеме определения — как сервис мы или нет.
L>если использовать соглашение, что
L>argv[1]=="Service"
L>argv[1]=="Prog"
L>то это всё же не гарантирует , что программа запущена как сервис потому, что можно сделать cmd.exe /c prog.exe Service

Гарантия, что сервис запущен как сервис находиться в Service Control Manager: StartService () -> StartServiceCtrlDispatcher () -- см. предыдущие мои ответы.
Signed, [TSS] /SDL/
Сервис: запущен как сервис или как просто exe?
От: Игорь Вартанов Ниоткуда  
Дата: 15.12.01 13:25
Оценка: 10 (1) +1
#Имя: FAQ.winapi.serviceornot
YV>Как сделать, чтобы сервис при старте получал командную строку?
YV>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.

Итак, командная строка ни при чем.

Нужно получить имя процесса, породившего процесс твоего экзешника. Если это не %SystemRoot%\system32\services.exe (WinNT 4.0, для W2k подскажет Alex Fedotov, я сам не помню), то мы работаем в user mode. Если же родитель процесса — services.exe (AKA SCM), то мы работаем в режиме сервиса. В системе сервисы запускает только SCM.
---
С уважением,
Игорь
Re[2]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Alex Fedotov США  
Дата: 15.12.01 18:59
Оценка:
Здравствуйте Игорь Вартанов, Вы писали:

YV>>Задача: отличить запуск exe-шника user'ом от запуска его системой как сервиса.


ИВ>Нужно получить имя процесса, породившего процесс твоего экзешника. Если это не %SystemRoot%\system32\services.exe (WinNT 4.0, для W2k подскажет Alex Fedotov, я сам не помню)


В Win2K/XP все тоже самое.
-- Alex Fedotov
Re[6]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Lokki Зимбабве  
Дата: 15.12.01 19:07
Оценка:
Здравствуйте TSS, Вы писали:

TSS>Здравствуйте Lokki, Вы писали:


TSS>>>Это к чему ?

TSS>>>У службы есть две функции которые можно "запустить с параметрами". Одна из них -- main (argc, argv), которая вызываеться из C/C++ Runtime. Вторая -- ServiceMain (argc, argv), вызываемая через StartService.
TSS>>>Это разные функции с разными параметрами. Одни (для main) задаються в командной строке (например при CreateProcess), другие в реестре, которые находяться в реестре и используються MMC (например) при запуске службы через StartService ()

TSS>>>P.S. См. MSDN на предмет описания main() и StartService ()

L>>я говорю о проблеме определения — как сервис мы или нет.
L>>если использовать соглашение, что
L>>argv[1]=="Service"
L>>argv[1]=="Prog"
L>>то это всё же не гарантирует , что программа запущена как сервис потому, что можно сделать cmd.exe /c prog.exe Service

TSS>Гарантия, что сервис запущен как сервис находиться в Service Control Manager: StartService () -> StartServiceCtrlDispatcher () -- см. предыдущие мои ответы.

дык я именно это и сказал.
хм.
кроме того привел кусок кода, который сам же и юзал.
Re[3]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Дмитрий Глебенок Германия  
Дата: 29.04.02 13:27
Оценка:
Здравствуйте всем.

Так а как получить имя процеса, породившего процесс экзешника?

Best regards,
Dmitriy Glebenok.
Re[4]: Как сделать, чтобы сервис при старте имел argc>=2?
От: Alex Fedotov США  
Дата: 29.04.02 15:36
Оценка:
Здравствуйте Дмитрий Глебенок, Вы писали:

ДГ>Так а как получить имя процеса, породившего процесс экзешника?


http://www.rsdn.ru/?qna/?baseserv/enumproc.xml
-- Alex Fedotov
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.