Service wird als console programm ausgeführt



  • Hi,

    ich habe einen Service geschrieben.
    es gibt ein
    service.exe install
    Wenn das getan ist wird der Service unter dem Tool "Services" angezeigt.

    Bei gleichem Quelltext, Compiler und Windows Version kann ich den Service zu Hause starten und stoppen wie ich möchte und er läuft einwandfrei.

    An dem PC hier bekomme ich von der Funktion:

    ui32_RetVal = StartServiceCtrlDispatcher( DispatchTable );
        if(0x00000000 == ui32_RetVal)
        {
            ui32_RetVal = GetLastError();
            if(ERROR_FAILED_SERVICE_CONTROLLER_CONNECT == ui32_RetVal)
            {
                wsprintf((LPSTR)ui8_DebugString,"StartServiceCtrlDispatcher ERROR_FAILED_SERVICE_CONTROLLER_CONNECT");
            }else if (ERROR_INVALID_DATA == ui32_RetVal )
    .....
    

    den Fehlercode

    ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
    

    zurück.

    Windows meint dazu:

    This error is returned if the program is being run as a console application rather than as a service. If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned.

    Also habe ich mal ein

    DebugBreak();
    

    eingebaut welches aufgeführt wird, wenn ich mit dem Tool "Services"
    meinen service.exe starte.
    Ich erhalte eine Console mit dem Namen "taskeng.exe" welcher dann meldet
    service.exe has stopped working.

    Ich schließe jetzt, dass mein service.exe von dem tool "Services" nicht als
    service sondern als console programm ausgeführt wird.

    Jetzt zur Frage:
    Gibt es eine möglichkeit Windows7 so zu konfigurieren, dass das tool "Services"
    ein Service als Console Programm ausführt ??
    Ist das ein berechtigungsproblem ??

    Der Eintrag in

    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\service\Type = 0x10

    Was ein eigener Prozess sein sollte.

    Ich wäre für Hilfe sehr dankbar, ich sitz an der Sache jetzt schon zwei Tage dran.

    Gruß



  • Okay, also ich habe gerade gesehen, dass ich service.exe
    als Windows Task eingetragen hatte.

    Wenn ich die Aufgabe raus nehme, fürt "Services" meine service.exe
    garnicht mehr aus. Nicht eine Zeile....

    Woran kann denn das liegen ??



  • Wird der Dienst denn als gestartet angezeigt?



  • Hi MFK,

    nein leider nicht.
    Ich benutze DebugView für Fehlerausgaben.
    Es wird nichtmal Main aufgerufen.

    OutputDebugString("_tmain -Start (ODS)");
    

    Die Ausgabe ist lediglich:

    [5064] FMAPO: DllGetClassObject
    [5064] FMAPO: Debug function is disable

    Ich glaube aber nicht dass die Ausgabe was zu bedeuten hat...

    Was mich eben extrem wundert ist, das auf meine PC der selbe Service wunderbar startet und stopp.....



  • Steht denn was im Ereignissprotokoll? Wie ist den der Starttyp des Services?

    mfg Martin



  • Hi Martin,

    Danke für die Antwort...

    Der Starttyp ist
    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\service\Type = 0x10
    Also das ist ein eigener W32 prozess...

    Wie schon gesagt, auf meinem heimrechner läuft er problemlos...
    Ich gluabe nicht dass es am Quelltext liegt...

    Eher an der Windows konfiguration...



  • NasenBaer_2013 schrieb:

    Eher an der Windows konfiguration...

    Eher an dem wie du das Service auf dem anderen PC registriert hast.
    Hätte Windows nämlich ein grundsätzliches Problem damit Services zu starten, dann würde so-gut-wie gar nichts mehr funktionieren.

    Versuch' mal dein Service einfach mit sc.exe zu registrieren.



  • Guten Morgen Hustbaer,

    danke für den Tipp,
    aber daran liegt es nicht.

    Ich habe den Service mal mit sc create .... installiert.
    Die Registryeinträge sind die Selben.
    Das Verhalten beim Starten ist äquivalent.

    Ich denke das setzt nocheinmal ein Gewicht auf Windowskonfiguration....
    Zumal er ja auf meinem Windowsrechner (ziemlich frisch installiert)
    einwandfrei läuft.

    Gruß



  • Ich habe einmal einen Service implementiert. So wird er bei mir angemeldet:

    void TcronconfDlgClient::InstallService()
    {
    	// INSERT>> Your code here.
    	SC_HANDLE		serviceManager;
    	SC_HANDLE		jobService;
    	char			appPath[1024];
    	char			password[64];
    	char			username[64];
    	char			tmpBuff[64];
    	char			*bsPos;
    	char			*lastBackSlash;
    
    	serviceManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
    	if( serviceManager )
    	{
    		GetModuleFileName( NULL, appPath, sizeof( appPath ) - 1 );
    		lastBackSlash = strrchr( appPath, '\\' );
    		if( lastBackSlash )
    			lastBackSlash++;
    
    		// stop the dispatcher
    		jobService = OpenService( serviceManager, SERVICE_NAME, SERVICE_ALL_ACCESS );
    		if( !jobService )
    		{
    			// create the service
    			if( lastBackSlash )
    				strcpy( lastBackSlash, "CRONTAB.EXE " );
    
    			// service not yet created
    
    			GetDlgItemText( IDC_PASS_EDIT, password, sizeof( password ) -1 );
    			GetDlgItemText( IDC_USER_EDIT, username, sizeof( username ) -1 );
    			if( *username )
    			{
    				bsPos = strchr( username, '\\' );
    				if( !bsPos )
    				{
    					strcpy( tmpBuff, username );
    					strcpy( username, ".\\" );
    					strcat( username, tmpBuff );
    				}
    			}
    
    			jobService = CreateService(
    							serviceManager,
    							SERVICE_NAME,
    							SERVICE_NAME,
    							SERVICE_ALL_ACCESS,
    							SERVICE_WIN32_OWN_PROCESS,
    							SERVICE_AUTO_START,
    							SERVICE_ERROR_NORMAL,
    							appPath,
    							NULL, NULL, NULL,
    							*username ? username : NULL,
    							*username ? password  : NULL );
    		}
    
    		if( jobService )
    			CloseServiceHandle( jobService );
    		else
    			MessageBox( "Unable to create job service", "Error", MB_OK|MB_ICONERROR );
    
    		CloseServiceHandle( serviceManager );
    	}
    	else
    		MessageBox( "Unable to open service manager", "FATAL", 0 );
    
    	checkService();
    }
    

    Dafür benötigt der Benutzer natürlich Adminrechte.

    Im Service sieht das dann so aus:

    #ifdef RUN_AS_SERVICE
    static void WINAPI MyServiceCtrlHandler ( DWORD Opcode )
    {
    	switch( Opcode )
    	{
    	case SERVICE_CONTROL_PAUSE:
    		servicePaused = 1;
    		MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
    		break;
    
    	case SERVICE_CONTROL_CONTINUE:
    		servicePaused = 0;
    		MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
    		break;
    
    	case SERVICE_CONTROL_STOP:
    		serviceStopped = 1;
    		MyServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
    		MyServiceStatus.dwWin32ExitCode = 0;
    		MyServiceStatus.dwCheckPoint    = 0;
    		MyServiceStatus.dwWaitHint      = 0;
    		break;
    
    	case SERVICE_CONTROL_INTERROGATE:
    		break;
    	 }
    
    	SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus);
    	return;
    }
    
    static void WINAPI ServiceMain( DWORD , LPSTR * )
    {
    	// for a service we only register the control handler no log window
    	MyServiceStatus.dwServiceType        = SERVICE_WIN32_OWN_PROCESS;
    	MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING;
    	MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
    	MyServiceStatus.dwWin32ExitCode      = 0;
    	MyServiceStatus.dwServiceSpecificExitCode = 0;
    	MyServiceStatus.dwCheckPoint         = 0;
    	MyServiceStatus.dwWaitHint           = 0;
    
    	MyServiceStatusHandle = RegisterServiceCtrlHandler(
    							SERVICE_NAME,
    							MyServiceCtrlHandler);
    
    	MyServiceStatus.dwCurrentState       = SERVICE_RUNNING;
    	MyServiceStatus.dwCheckPoint         = 0;
    	MyServiceStatus.dwWaitHint           = 0;
    
    	SetServiceStatus( MyServiceStatusHandle, &MyServiceStatus );
    
    	StartServiceThread();
    
    	MyServiceStatus.dwCurrentState       = SERVICE_STOPPED;
    	MyServiceStatus.dwCheckPoint         = 0;
    	MyServiceStatus.dwWaitHint           = 0;
    
    	SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
    }
    #endif
    
    int main( int , char ** )
    {
    #ifdef RUN_AS_SERVICE
    	SERVICE_TABLE_ENTRY   DispatchTable[] =
    	{
    		{ SERVICE_NAME,	ServiceMain		},
    		{ NULL,			NULL			}
    	};
    
    	StartServiceCtrlDispatcher( DispatchTable );
    #else
    	StartServiceThread();
    #endif
    	return 0;
    }
    

    Der Service wurde bei mir als Win32-Console-Anwendung übersetzt.

    Früher gab es auch, wenn ich mich recht erinnere, tatsächlich eine Option, mit der das konfiguriert werden konnte. Irgendwas mit interaktiv oder so ähnlich. Wie ist denn beim Reiter Anmelden der Schalter "Datenaustausch mit dem Desktop zulassen" gesetzt?

    Vielleicht hilft Dir das.

    mfg Martin



  • @NasenBaer_2013
    Mach mal ein kleines Test-Programm, das nur den StartServiceCtrlDispatcher Aufruf enthält und dessen Returnwert rausloggt. Kein Code zum Installieren oder sonstwas.
    Und dann installier' das mal mit sc.exe YourName create type= own binPath= x:\your\path\to\the.exe DisplayName= YourDisplayName und probier es zu starten.

    Und natürlich musst du das Service wo ablegen wo der Service-Account die nötigen Berechtigungen hat - was bei LocalSystem (Default) aber normalerweise kein Problem sein sollte.

    Wenn es damit geht, dann bau dieses kleine Programm Schritt für Schritt in das um was du jetzt hast, und probier nach jedem Schritt ob es noch funktioniert.



  • Guten Abend mgaeckler und hustbaer,

    vielen Dank für eure Mühe...

    Na ja ich habe jetzt zurück bekommen, dass
    services explizit abgeschalten wurden wenn ich den aussagen glauben darf.

    Ich werds nochmal versuchen,
    aber das schaut gleich aus wie bei mir auch...

    Sorry dass ihr euch die Mühe gemacht habt...


Anmelden zum Antworten