سلام
از نظر تئوریک هر مشتری (client) (برنامه که از سرویس استفاده میکنه) باید تمامی پیامهای اون سرویس رو درک کنه و بتونه یکسری پیام پایه رو ساپورت کنه. و سرویس دهنده (server یا همون سرویس ویندوز) هم باید بتونه نسبت به نوع سرویس تعریف شده براش درست عکس العمل نشون بده
این چیزی که شما نوشتید معماری client -server هستش خب حالا می ریم جلو تر
توی ویندوز به برنامه ای که سرویس میگیره برنامه کاربردی گفته میشه (application) و به برنامه ای که سرویس رو میده (service) گفته میشه. به نظر من نام گذاری خوبی نیستش.
الان اینجا اشتباه مفهومی شده .
چون این چزی که شما گفتی بازم معماری client -server شد . نه service
یه service می تونه خودش client باشه یا به عبارت دیگه server نباشه یا باشه
server != service
سرویس یا هر برنامه ای توی ویندوز می تونه از یکی از روش های IPC استفاده کنه و یه معماری Client -Server رو پیاده سازی کنه ( RPC , Pipe ,socket , mailslot و... )
توی ویندوز به برنامه ای که توسط معماری خاص خودش نوشته شده باشد که می تونه خود کار اجرا بشه نیاز به UI نداره می تونه قبل login هم اجرا بشه سرویس های باید توی
HKLM\SYSTEM\CurrentControlSet\Services
ثبت بشن
سرویس ها توسط service.exe اجرا می شن
سرویس می تونه پراسس خودش رو داشته باشه یا می تونن چند تا سریس توسط یه پراسس svchost.exe بیاد بالا ( در این حالت سرویس باید dll باشه
مثال:http://dralu.com/?p=234
)
توی ویندوز vista سرویس ها سشنشون از برنامه های معمولی عوض شد
و چیز های دیگه :)
کد زیر یه سرویس هسش به صورت Dll(یا exe ) که می تونه داخل svchost اجرا بشه ( معمولا ویروس ها از این روش استفاده می کنن برای مخفی شدن ) یا تکی
برای اینکه بتونید از Svchost استفاده کنید به لینک بالا مراجعه کنید برای اجرا معمولی هم هیچی نمیخواد
درمورد pipe در ویندوز :
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
// Beeper Service.cpp
// geek1982.
#include <windows.h>
#include <tchar.h>
#include<stdio.h>
TCHAR* serviceName = TEXT("Beeper Service");
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
HANDLE stopServiceEvent = 0;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
DWORD WINAPI ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext
)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
break;
case SERVICE_CONTROL_PAUSE:
serviceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
serviceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
};
SetServiceStatus(serviceStatusHandle, &serviceStatus);
return NO_ERROR;
}
VOID WINAPI ServiceMain(__in DWORD dwArgc ,__in LPTSTR *lpszArgv)
{
// initialise service status
//strcpy(serviceStatus,"NativeService");
DWORD status = 0;
DWORD specificError = 0xfffffff;
serviceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
serviceStatusHandle = RegisterServiceCtrlHandlerExA("geek1982", ServiceControlHandler, NULL);
if (serviceStatusHandle==0)
{
return;
}
serviceStatus.dwCurrentState = SERVICE_RUNNING;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
FILE* f=fopen("c:\\t.txt","w+");
fwrite("hi",2,2,f);
//GetModuleFileName( NULL, szBuf, 1024 );
OutputDebugString( L" *** *** " );
OutputDebugString(L" *** ***\n" );
OutputDebugString( L" *** *** " );
OutputDebugString(L" *** ***\n" );
}
void RunService()
{
SERVICE_TABLE_ENTRY serviceTable[] =
{
{ serviceName, ServiceMain },
{ 0, 0 }
};
StartServiceCtrlDispatcher( serviceTable );
}
void InstallService()
{
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CREATE_SERVICE );
if ( serviceControlManager )
{
TCHAR path[ _MAX_PATH + 1 ];
if ( GetModuleFileName( 0, path, sizeof(path)/sizeof(path[0]) ) > 0 )
{
SC_HANDLE service = CreateService( serviceControlManager,
serviceName, serviceName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
0, 0, 0, 0, 0 );
if ( service )
CloseServiceHandle( service );
}
CloseServiceHandle( serviceControlManager );
}
}
void UninstallService()
{
SC_HANDLE serviceControlManager = OpenSCManager( 0, 0, SC_MANAGER_CONNECT );
if ( serviceControlManager )
{
SC_HANDLE service = OpenService( serviceControlManager,
serviceName, SERVICE_QUERY_STATUS | DELETE );
if ( service )
{
SERVICE_STATUS serviceStatus;
if ( QueryServiceStatus( service, &serviceStatus ) )
{
if ( serviceStatus.dwCurrentState == SERVICE_STOPPED )
DeleteService( service );
}
CloseServiceHandle( service );
}
CloseServiceHandle( serviceControlManager );
}
}
int _tmain( int argc, TCHAR* argv[] )
{
if ( argc > 1 && lstrcmpi( argv[1], TEXT("install") ) == 0 )
{
InstallService();
}
else if ( argc > 1 && lstrcmpi( argv[1], TEXT("uninstall") ) == 0 )
{
UninstallService();
}
else
{
RunService();
}
return 0;
}
کد زیر هم می تونه سرویس رو برای اجرا شدن در داخل svchsot ثبت کنه (با Python نوشتم )
ServiceName = sys.argv[1]
ImagePath = sys.argv[2]
ServiceArgs = sys.argv[3:]
hscm = win32service.OpenSCManager(
None, None, win32service.SC_MANAGER_ALL_ACCESS)
try:
hs = win32service.CreateService(hscm,
ServiceName,
"",
win32service.SERVICE_ALL_ACCESS,
win32service.SERVICE_WIN32_SHARE_PROCESS,
win32service.SERVICE_DEMAND_START,
win32service.SERVICE_ERROR_NORMAL,
"C:\\WINDOWS\\System32\\svchost.exe -k " + ServiceName,
None,
0,
None,
None,
None)
except:
print "Cannot create service!"
sys.exit()
key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE,
"System\\CurrentControlSet\\Services\\%s\\Paramete rs" % ServiceName)
try:
win32api.RegSetValueEx(key,
"ServiceDll",
0,
win32con.REG_EXPAND_SZ,
ImagePath);
finally:
win32api.RegCloseKey(key)
key = win32api.RegCreateKey(win32con.HKEY_LOCAL_MACHINE,
"Software\\Microsoft\\Windows NT\\CurrentVersion\\SvcHost")
try:
win32api.RegSetValueEx(key,
ServiceName,
0,
win32con.REG_MULTI_SZ,
[ServiceName, '']);
finally:
win32api.RegCloseKey(key)
win32service.StartService(hs, ServiceArgs)
win32service.CloseServiceHandle(hs)
win32service.CloseServiceHandle(hscm)
کد ها رو توی ارشیوام پیدا کردم ( نمی دونم نیاز به اصلاح داره یه نه )
شرمنده من نمی تونم مثل استاد موسوی درست چیزی رو بنویسم