RegisterServiceCtrlHandler funktioniert nicht
Übersicht

andre72Betreff: RegisterServiceCtrlHandler funktioniert nicht |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nachdem hier das letzte mal so gut und schnell geholfen wurde, kommt jetzt direkt die nächste Frage.
RegisterServiceCtrlHandler funktioniert einfach nicht... Vielleicht ein Denkfehler bei der übergabe der Parameter? Hat jemand eine Idee...? Code: [AUSKLAPPEN] SuperStrict Import "-ladvapi32" 'API Constants Const SERVICES_ACTIVE_DATABASE:String = "ServicesActive" ' Service Control Const SERVICE_CONTROL_STOP:Int = $1 Const SERVICE_CONTROL_PAUSE:Int = $2 ' Service State - for CurrentState Const SERVICE_STOPPED:Int = $1 Const SERVICE_START_PENDING:Int = $2 Const SERVICE_STOP_PENDING:Int = $3 Const SERVICE_RUNNING:Int = $4 Const SERVICE_CONTINUE_PENDING:Int = $5 Const SERVICE_PAUSE_PENDING:Int = $6 Const SERVICE_PAUSED:Int = $7 Const SERVICE_ACCEPT_STOP:Int = $1 Const SERVICE_ACCEPT_PAUSE_CONTINUE:Int = $2 Const SERVICE_ACCEPT_SHUTDOWN:Int = $4 'Service Control Manager object specific access types Const STANDARD_RIGHTS_REQUIRED:Int = $F0000 Const SC_MANAGER_CONNECT:Int = $1 Const SC_MANAGER_CREATE_SERVICE:Int = $2 Const SC_MANAGER_ENUMERATE_SERVICE:Int = $4 Const SC_MANAGER_LOCK:Int = $8 Const SC_MANAGER_QUERY_LOCK_STATUS:Int = $10 Const SC_MANAGER_MODIFY_BOOT_CONFIG:Int = $20 Const SC_MANAGER_ALL_ACCESS:Int = $F003F 'STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK or SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG 'Service object specific access types Const SERVICE_QUERY_CONFIG:Int = $1 Const SERVICE_CHANGE_CONFIG:Int = $2 Const SERVICE_QUERY_STATUS:Int = $4 Const SERVICE_ENUMERATE_DEPENDENTS:Int = $8 Const SERVICE_START:Int = $10 Const SERVICE_STOP:Int = $20 Const SERVICE_PAUSE_CONTINUE:Int = $40 Const SERVICE_INTERROGATE:Int = $80 Const SERVICE_USER_DEFINED_CONTROL:Int = $100 Const SERVICE_ALL_ACCESS:Int = $1FF 'STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL ' Service Install - Types Const SERVICE_WIN32_OWN_PROCESS:Int = $10 Const SERVICE_ERROR_NORMAL:Int = $1 Const SERVICE_AUTO_START:Int = $2 Const SERVICE_DEMAND_START:Int = $3 ' Service Types Const SERVICE_WIN32_SHARE_PROCESS:Int = $20 Const SERVICE_WIN32:Int = $30 Type SERVICE_STATUS Field dwServiceType:Int Field dwCurrentState:Int Field dwControlsAccepted:Int Field dwWin32ExitCode:Int Field dwServiceSpecificExitCode:Int Field dwCheckPoint:Int Field dwWaitHint:Int End Type Type SERVICE_TABLE_ENTRY Field lpServiceName:String Field lpServiceProc:Byte ptr End Type Extern "Win32" Function CloseServiceHandle:Int (hSCObject:Int) = "CloseServiceHandle@4" Function ControlService:Int (hService:Int, dwControl:Int, lpServiceStatus:Byte ptr) = "ControlService@12" Function OpenSCManager:Int (lpMachineName:Byte Ptr, lpDatabaseName:Byte Ptr, dwDesiredAccess:Int) = "OpenSCManagerA@12" Function OpenService:Int (hSCManager:Int, lpServiceName:Byte Ptr, dwDesiredAccess:Int) = "OpenServiceA@12" Function QueryServiceStatus (hService:Int, lpServiceStatus:Byte ptr) = "QueryServiceStatus@8" Function StartService:Int (hService:Int, dwNumServiceArgs:Int, lpServiceArgVectors:Int) = "StartServiceA@12" Function CreateService:Int (hSCManager:Int, lpServiceName:Byte ptr, lpDisplayName:Byte ptr, dwDesiredAccess:Int, dwServiceType:Int, dwStartType:Int, dwErrorControl:Int, lpBinaryPathName:Byte ptr, lpLoadOrderGroup:Byte ptr, lpdwTagID:Int, lpDependencies:Byte ptr, lp:Byte ptr, lpPassword:Byte ptr) = "CreateServiceA@52" Function StartServiceCtrlDispatcher:Int (lpServiceStartTable:Byte ptr) = "StartServiceCtrlDispatcherA@4" Function RegisterServiceCtrlHandler:Int(lpServiceName:Byte ptr, lpHandlerProc:Byte ptr) = "RegisterServiceCtrlHandlerA@8" Function SetServiceStatus:Int(hService:Int, lpHandlerProc:Byte ptr) = "SetServiceStatus@8" Function GetLastError() End Extern Function ServiceCreate:Int(ServiceName:String) Local hSManager:Int = OpenSCManager(Null, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS) Local res:Int If hSManager <> 0 Local schService:Int = CreateService(hSManager, ServiceName, ServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, AppFile, Null, Null, Null, Null, Null) If schService <> 0 CloseServiceHandle schService Endif CloseServiceHandle hSManager EndIf Return res End Function ServiceCreate "TestService" Local svc:SERVICE_TABLE_ENTRY = New SERVICE_TABLE_ENTRY svc.lpServiceName = "MyProc" svc.lpServiceProc = Byte ptr(SvcMain()) DebugLog("Registriere Handler") Local success:Int = StartServiceCtrlDispatcher(svc) DebugLog("Success: " + success) Function SvcMain (argc:Int = Null, argv:String = "") Local svchandle:Int = RegisterServiceCtrlHandler("TestService", Byte ptr(svcCtrlHandler())) DebugLog("svchandle: " + svchandle) If svchandle = 0 Then DebugLog("Ctrl Service Handle konnte nicht registriert werden. Error: " + GetLastError()) End If End Function Function svcCtrlHandler(dwOpcode:Int = Null) DebugLog("svcCtrl") End Function Und sorry wegen der Code-Tags - jetzt weiß ich bescheid... |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
was funktioniert nicht? | ||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
andre72 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Local svchandle:Int = RegisterServiceCtrlHandler("TestService", Byte ptr(svcCtrlHandler())) - ergibt immer 0 und GetError liefert den dazu gehörigen Fehler Code, wozu ich aber so keine Infos gefunden habe.
Zwar gibt es diesen Fehler lt. Google bei diversen Diensten, aber Lösungsansätze habe ich nicht gefunden. |
||
andre72Betreff: Das ursprüngliche Beispiel in C |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hier dann mal der C Source den ich versuche in BM umzusetzen. Vielleicht kann ja einer damit was anfangen ...
Code: [AUSKLAPPEN] /* A skeleton for writing an NT/2K service */ /* Author :- Nishant S */ /* EMail :- nish@inapp.com */ #include <windows.h> #include <winsvc.h> void ServiceMain(DWORD argc, LPTSTR *argv); void ServiceCtrlHandler(DWORD nControlCode); BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint); BOOL StartServiceThread(); DWORD ServiceExecutionThread(LPDWORD param); HANDLE hServiceThread; void KillService(); char *strServiceName = "NishFirstService"; SERVICE_STATUS_HANDLE nServiceStatusHandle; HANDLE killServiceEvent; BOOL nServiceRunning; DWORD nServiceCurrentStatus; void main(int argc, char* argv[]) { SERVICE_TABLE_ENTRY servicetable[]= { {strServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL,NULL} }; BOOL success; success=StartServiceCtrlDispatcher(servicetable); if(!success) { //error occured } } void ServiceMain(DWORD argc, LPTSTR *argv) { BOOL success; nServiceStatusHandle=RegisterServiceCtrlHandler(strServiceName, (LPHANDLER_FUNCTION)ServiceCtrlHandler); if(!nServiceStatusHandle) { return; } success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000); if(!success) { return; } killServiceEvent=CreateEvent(0,TRUE,FALSE,0); if(killServiceEvent==NULL) { return; } success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000); if(!success) { return; } success=StartServiceThread(); if(!success) { return; } nServiceCurrentStatus=SERVICE_RUNNING; success=UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0); if(!success) { return; } WaitForSingleObject(killServiceEvent,INFINITE); CloseHandle(killServiceEvent); } BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { BOOL success; SERVICE_STATUS nServiceStatus; nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS; nServiceStatus.dwCurrentState=dwCurrentState; if(dwCurrentState==SERVICE_START_PENDING) { nServiceStatus.dwControlsAccepted=0; } else { nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP |SERVICE_ACCEPT_SHUTDOWN; } if(dwServiceSpecificExitCode==0) { nServiceStatus.dwWin32ExitCode=dwWin32ExitCode; } else { nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR; } nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode; nServiceStatus.dwCheckPoint=dwCheckPoint; nServiceStatus.dwWaitHint=dwWaitHint; success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus); if(!success) { KillService(); return success; } else return success; } BOOL StartServiceThread() { DWORD id; hServiceThread=CreateThread(0,0, (LPTHREAD_START_ROUTINE)ServiceExecutionThread, 0,0,&id); if(hServiceThread==0) { return false; } else { nServiceRunning=true; return true; } } DWORD ServiceExecutionThread(LPDWORD param) { while(nServiceRunning) { Beep(450,150); Sleep(4000); } return 0; } void KillService() { nServiceRunning=false; SetEvent(killServiceEvent); UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0); } void ServiceCtrlHandler(DWORD nControlCode) { BOOL success; switch(nControlCode) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: nServiceCurrentStatus=SERVICE_STOP_PENDING; success=UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000); KillService(); return; default: break; } UpdateServiceStatus(nServiceCurrentStatus,NO_ERROR,0,0,0); } |
||
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Die Funktion "RegisterServiceCtrlHandler" erwartet einen Pointer auf die Funktion svcCtrlHandler. Du gibst ihr aber einen Pointer auf den Rückgabewert von svcCtrlHandler.
So sollte es aussehen ( keine Garantie, ich hab's nicht getestet ): Code: [AUSKLAPPEN] Function RegisterServiceCtrlHandler:Int( lpServiceName:Byte ptr, lpHandlerProc( nControlCode:Int ) ) = "RegisterServiceCtrlHandlerA@8"
Bei der Funktionsdeklaration im Extern "win32" Block. Code: [AUSKLAPPEN] Local svchandle:Int = RegisterServiceCtrlHandler( "TestService", svcCtrlHandler )
In der Funktion SvcMain. Für den zweiten Parameter gibst du einfach den Namen der Funktion an. So, ich hoffe, das hilft dir weiter. ![]() |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
andre72 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Danke für die Info - habe es gerade einmal ausprobiert, aber der Fehler bleibt leider der Gleiche.
Der Service Handler wird nicht registiert ... |
||
ChristianK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich hab gerade ein paar Sachen ausprobiert. Es erscheint jetzt keine Fehlermeldung mehr, aber ob alles funktioniert, kann ich dir nicht sagen, da ich von Services keine Ahnung hab.
1. Du solltest den Parameter von "ServiceCreate" von String auf Byte Ptr ändern. 2. Wie oben beschrieben musst du Funktionszeiger verwenden: Code: [AUSKLAPPEN] svc.lpServiceProc = SvcMain
Ich bin mir nicht sicher, ob das so funktioniert, weil BlitzMax-Types nicht das gleiche sind wie struct in C. Vielleicht kannst du auch die passende Funktion in C schreiben und dann mit Import in dein BlitzMax-Projekt importieren. Das ist einfacher, als es zu konvertieren. |
||
AdvanceLcd
Intel Core 2 Duo 3.2 GHz, 4 GB RAM, GeForce 8800 GTX | MacBook Pro 15,4″ Intel Core 2 Duo 2.4 GHz, 2 GB RAM, GeForce 8600M GT |
andre72 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
svc.lpServiceProc = SvcMain hatte ich auch schon probiert. Tatsächlich kommen dann keine Fehler mehr, aber es liegt daran, dass die SvcMain gar nicht mehr aufgerufen wird.
Ich kann leider kein C - und BM und C zu mixen wäre eh eine Horrorvision ![]() |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nein wärs in keinster Weise.
Du kannst einfach eine C Funktion schreiben die du in BM aufrufst. Vorher extern deklarieren und die C file importieren, thats it. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
andre72 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja Dreamora, für jemanden der C kann mag das zutreffen.
C lesen ist ja nicht das Thema, aber ich habe bisher noch nicht einmal das berühmte "Hello World" compiliert ![]() |
||
andre72 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ok, weil ich in BM ja nicht weiter komme versuche ich es nun mal tatsächlich mit C.
Also, ich habe die Datei um #include <brl.mod/blitz.mod/blitz.h> ergänzt. Im BM Code habe ich nun Import "service.cpp" hinzugefügt. Leider sagt mir BM nun immer: "Built error: failed to compile c:\...\service.cpp". Ich habe es mal mit VC versucht, der kompiliert das ganze Problemlos (ohne blitz.h zu includen). Was mache ich falsch? |
||
#ReaperNewsposter |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hi andre72,
So wie ich es hier verstanden habe, geht es um Windows-Services, oder? Vor kurzem wollte ich sowas mit BMax auch mal machen, habe aber nichtmal die C-Funktionen dazu gefunden ![]() Aber vielleicht können wir ja zusammen arbeiten? Habe schon ein klein wenig Ahnung von C-Imports mit BMax, aber halt nur ein wenig.. ![]() Kannst dich ja mal über ICQ bei mir melden. Aber nur, wenn du lust hast ![]() ICQ: 334-064-990 MfG #Reaper |
||
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7 |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group