RegisterServiceCtrlHandler funktioniert nicht

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

andre72

Betreff: RegisterServiceCtrlHandler funktioniert nicht

BeitragFr, Sep 28, 2007 0:26
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Sep 28, 2007 1:01
Antworten mit Zitat
Benutzer-Profile anzeigen
was funktioniert nicht?
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen.
 

andre72

BeitragFr, Sep 28, 2007 13:50
Antworten mit Zitat
Benutzer-Profile anzeigen
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.
 

andre72

Betreff: Das ursprüngliche Beispiel in C

BeitragMo, Okt 01, 2007 10:42
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 01, 2007 11:12
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Smile
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

BeitragMo, Okt 01, 2007 11:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für die Info - habe es gerade einmal ausprobiert, aber der Fehler bleibt leider der Gleiche.
Der Service Handler wird nicht registiert ...
 

ChristianK

BeitragMo, Okt 01, 2007 11:58
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 01, 2007 12:20
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Confused
 

Dreamora

BeitragMo, Okt 01, 2007 13:59
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 01, 2007 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile
 

andre72

BeitragMi, Okt 03, 2007 13:34
Antworten mit Zitat
Benutzer-Profile anzeigen
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?
 

#Reaper

Newsposter

BeitragMi, Okt 03, 2007 14:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Embarassed
Aber vielleicht können wir ja zusammen arbeiten? Habe schon ein klein wenig Ahnung von C-Imports mit BMax, aber halt nur ein wenig.. Wink

Kannst dich ja mal über ICQ bei mir melden. Aber nur, wenn du lust hast Wink
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

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group