Service arbeitet unter Vista nicht



  • Hi, ich programmiere nicht unter MSVC. Ich verwende hauptsächlich den Intel-
    Compiler. Ich bin froh ein einfaches Demo zur Service-Programmierung gefunden
    zu haben. Mit HTML-Debugging (oder wie auch immer dies funktionieren soll) kann
    ich leider überhaupt nichts anfangen. Die Einführungen oder Erläuterungen unter
    MSVC sind meiner Meinung nach die absolute Katastrophe (ich lenke und MSVC
    denkt!!!). Dummerweise läuft der Service, den ich fand, unter Vista nicht mehr.
    Vielleicht weiß jemand warum dem so ist.

    Die Datei aus dem dieser Code stammt heißt "NTSevice.zip". Es gibt leider zu
    viele Dateien mit diesem Namen.

    //Author: Anish C.V.
    //EMail : cv_anish@hotmail.com

    #include "stdafx.h"
    #include "Windows.h"
    #include "Winsvc.h"
    #include "time.h"

    SERVICE_STATUS m_ServiceStatus;
    SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
    BOOL bRunning=true;

    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
    void WINAPI ServiceCtrlHandler(DWORD Opcode);
    BOOL InstallService();
    BOOL DeleteService();

    int main(int argc, char* argv[])
    {
    if(argc>1)
    {
    if(strcmp(argv[1],"-i")==0)
    {
    if(InstallService())
    printf("\n\nService Installed Sucessfully\n");
    else
    printf("\n\nError Installing Service\n");
    }
    if(strcmp(argv[1],"-d")==0)
    {
    if(DeleteService())
    printf("\n\nService UnInstalled Sucessfully\n");
    else
    printf("\n\nError UnInstalling Service\n");
    }
    else
    {
    printf("\n\nUnknown Switch Usage\n\nFor Install use Srv1 -i\n\nFor UnInstall use Srv1 -d\n");
    }
    }
    else
    {
    SERVICE_TABLE_ENTRY DispatchTable[]={{"Service1",ServiceMain},{NULL,NULL}};
    StartServiceCtrlDispatcher(DispatchTable);
    }
    return 0;
    }

    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
    {

    DWORD status;
    DWORD specificError;

    m_ServiceStatus.dwServiceType = SERVICE_WIN32;
    m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    m_ServiceStatus.dwWin32ExitCode = 0;
    m_ServiceStatus.dwServiceSpecificExitCode = 0;
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;

    m_ServiceStatusHandle = RegisterServiceCtrlHandler("Service1",ServiceCtrlHandler);
    if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
    {
    return;
    }

    m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;
    if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus))
    {

    }

    bRunning=true;
    while(bRunning)
    {
    Sleep(3000);
    //Place Your Code for processing here....
    }

    return;
    }

    void WINAPI ServiceCtrlHandler(DWORD Opcode)
    {
    switch(Opcode)
    {
    case SERVICE_CONTROL_PAUSE:
    m_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
    break;

    case SERVICE_CONTROL_CONTINUE:
    m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    break;

    case SERVICE_CONTROL_STOP:
    m_ServiceStatus.dwWin32ExitCode = 0;
    m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    m_ServiceStatus.dwCheckPoint = 0;
    m_ServiceStatus.dwWaitHint = 0;

    SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);

    bRunning=false;

    break;

    case SERVICE_CONTROL_INTERROGATE:
    break;
    }
    return;
    }

    BOOL InstallService()
    {

    char strDir[1024];
    HANDLE schSCManager,schService;

    GetCurrentDirectory(1024,strDir);
    strcat(strDir,"\\Srv1.exe");

    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    if (schSCManager == NULL)
    return false;

    LPCTSTR lpszBinaryPathName=strDir;

    schService = CreateService(schSCManager,"Service1","The Display Name Needed", // service name to display
    SERVICE_ALL_ACCESS, // desired access
    SERVICE_WIN32_OWN_PROCESS, // service type
    SERVICE_DEMAND_START, // start type
    SERVICE_ERROR_NORMAL, // error control type
    lpszBinaryPathName, // service's binary
    NULL, // no load ordering group
    NULL, // no tag identifier
    NULL, // no dependencies
    NULL, // LocalSystem account
    NULL); // no password

    if (schService == NULL)
    return false;

    CloseServiceHandle(schService);

    return true;
    }

    BOOL DeleteService()
    {
    HANDLE schSCManager;
    SC_HANDLE hService;

    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

    if (schSCManager == NULL)
    return false;

    hService=OpenService(schSCManager,"Service1",SERVICE_ALL_ACCESS);

    if (hService == NULL)
    return false;

    if(DeleteService(hService)==0)
    return false;

    if(CloseServiceHandle(hService)==0)
    return false;
    else
    return true;
    }

    Zusätzliche Textdatei:

    How to Create a Windows NT/ Windows 2000 Service

    A Windows service is an EXE specially designed to communicate with the SCM (Service Control Manager) of Windows NT/2000. The Service Control Manager (SCM) maintains a database of installed services and driver services, and provides a unified and secure means of controlling them. SCM is started at system boot and it is a remote procedure call (RPC) server. As a developer to try a simple service, we can divide the program in to four parts.

    1. Main program of Win 32 / Console Application.
    2. A so called ServiceMain(), main program of Service. Entry point of a service.
    3. A Service Control Handler, a function to communicate with SCM.
    4. A Service Installer/ Uninstaller, To register an EXE as a Service.

    Firstly let us take a look at the Main program of the Console application (It can also be a WinMain()).

    #include "Winsvc.h" //Header file for Services.

    main()
    {
    SERVICE_TABLE_ENTRY Table[]={{"Service1",ServiceMain},{NULL,NULL}};
    StartServiceCtrlDispatcher(Table);
    }

    The only thing done by the main() is to fill a SERVICE_TABLE_ENTRY array. The position [0][0] contains the name of the Service (Any string you like). Position [0][1] contains the name of the Service Main function, I specified in the list earlier. It actually is a function pointer to the Service main function. The name can be any thing. Now we start the first step to a service by calling StartServiceCtrlDispatcher() with the SERVICE_TABLE_ENTRY array. Note that the function signature should be of the form. The [1][0] and [1][1] positions are NULL, just to say the end of the array. (Not a must). We can add more entries to the list if we have more than one service running from the same EXE.

    The declaration of a typical ServiceMain()

    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)

    Now Let us analyze our ServiceMain function.

    The main steps of this function are

    1. Fill the SERVICE_STATUS structure with appropriate values to communicate with the SCM.
    2. Register the Service Control Handler Function said earlier in the list.
    3. Call the actual processing functions.

    For proceeding we need two global variables here.

    SERVICE_STATUS m_ServiceStatus;
    SERVICE_STATUS_HANDLE m_ServiceStatusHandle;

    The ServiceMain() can accept command line arguments just as any c++ main() function. The first parameter contains the number of arguments being passed to the service. There will always be at least one argument. The second parameter is a pointer to an array of string pointers. The first item in the array always points to the service name. The SERVICE_STATUS data structure is used to fill the current state of the Service and notify it to the SCM. We use an API function SetServiceStatus() for the purpose. The data members of SERVICE_STATUS to look for are

    dwServiceType = SERVICE_WIN32;
    dwCurrentState = SERVICE_START_PENDING; //Means Trying To Start(Initially)
    dwControlsAccepted = SERVICE_ACCEPT_STOP; //Accepts Stop/Start only in Service control program. Usually in the control Panel (NT) / Administrative tools (2000). We can also set our service to accept PAUSE and CONTINUE functionality also.

    In the beginning of the ServiceMain() we should set the dwCurrentState of SERVICE_STATUS to SERVICE_START_PENDING. This signals the SCM that the service is starting. If any error occurs in the way we should notify the SCM by passing SERVICE_STOPPED. By default the SCM will look for an activity from the service and if it fails to show any progress with in 2 minutes SCM kills that service.

    The API function RegisterServiceCtrlHandler() is used to set the Service Control Handler Function of the Service with the SCM. The function takes two parameters as earlier, one service name (String) and the pointer to the Service Control Handler Function. That function should with the signature.

    Once we get till here we now set dwCurrentState as SERVICE_RUNNING to notify that the service has started to function. The next step is to call the actual processing steps.

    Now Let us analyze our Service Control Handler function

    The Service Control Handler function is used by the SCM to communicate to the Service program about a user action on the service like a start, stop, pause or continue. It basically contains a switch statement to deal with each case. Here we will call appropriate steps to clean up and terminate the process. This function receives an opcode which can have values like SERVICE_CONTROL_PAUSE,SERVICE_CONTROL_CONTINUE,SERVICE_CONTROL_STOP,SERVICE_CONTROL_INTERROGATE etc. We have to write appropriate steps on each.

    Now Service Installer/ Uninstaller

    For Installing a service we need to make some entries in the system registry. Windows has some API's to do these steps, instead of using the registry functions. They are CreateService() and DeleteService(). For both these functions we need to open the SCM database with appropriate rights. I prefer SC_MANAGER_ALL_ACCESS. For installing a service first open the SCM by OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS). Then invoke the CreateService() with appropriate Binary file path of our service. Here also we have to give the name of our service. We need this name if we want to delete a particular service. In deleting a service we need to open the specific service first by its name and then invoke the DeleteService() on it. That's all what we need. Take a look at the code given with it for more details.

    Thank You

    Anish C.V.

    Dieses Demo ist schön einfach und verständlich. Ich würde nur ungern darauf
    verzichten wollen. Der Autor ist leider nicht mehr erreichbar. Wer kann helfen?

    PS: Warum auch einfach, wenn's kompliziert geht.

    THX.



  • Also so wirst du hier nur wenig hilfe bekommen 😉
    1. editier bitte dein Post und füge Code Tags ein so kann doch kein mensch den Quellcode ordentlich lesen.
    2. Was funktioniert nicht? Hast du den Fehler auf ein minimum an Zeilen begrenzt (wenn ja dann poste nur diese Zeilen) Was hast du zur Fehleranalyse gemacht? usw. usf.

    Es bringt nix ein Quellcode und langen Text hinzuklatschen und zu Fragen was ist falsch 😉 also ich habe mir das ganze nicht durchgelesen!
    Ein bisschen mehr eigeninitiatvie bitte 🙂

    [edit] Ich weis nicht ob der Autor das gut findet das du seine email adresse in einem öffentlichen Forum veröffentlichst ⚠ [/edit]

    MfG schirrmie


  • Mod

    BTW: Unter www.codeproject.com gibt es einiges für Services zu finden!

    PS: Anscheinend vermischt Du MSVC und Windows API! Was hat eine Einfühtung in MSVC mit Services zu tun. Services werden in Einführungen von MSVC sicher nicht auftauchen.



  • Ich bin neu hier und weiß zugegebenermassen nicht, was Code-Tags sind. Ich
    bitte um Entschuldigung. Der Knackpunkt liegt darin, daß man Services nicht
    debuggen kann! MSVC hat diesbezüglich andere (zu komplizierte) Möglichkeiten.
    Ich habe sie nie verstanden. Es hat sich schlicht und einfach in den Services
    von Vista etwas geändert und vielleicht weiß jemand was. Es ist nicht unbedingt
    ein Fehler im Source-Code. Die E-Mail-Adresse des Autor ist tot. Dort hatte
    ich natürlich zuerst angefragt. Dieser Dienst läuft unter Vista nicht und ich
    kann ihn nicht debuggen. Ansonsten bitte ich um ein Demo welches unter Vista
    läuft. Bitte eines das nachprogrammierbar ist.



  • Ich hab die Datei nochmal gefunden:
    http://codeguru.earthweb.com/cpp/w-p/system/ntservices/article.php/c5701/
    Dort ist der Quellcode nebst Exe.



  • Ist es ein interaktiver Dienst?


  • Mod

    Echtzeit schrieb:

    Ich bin neu hier und weiß zugegebenermassen nicht, was Code-Tags sind. Ich
    bitte um Entschuldigung. Der Knackpunkt liegt darin, daß man Services nicht
    debuggen kann! MSVC hat diesbezüglich andere (zu komplizierte) Möglichkeiten.
    Ich habe sie nie verstanden. Es hat sich schlicht und einfach in den Services
    von Vista etwas geändert und vielleicht weiß jemand was. Es ist nicht unbedingt
    ein Fehler im Source-Code. Die E-Mail-Adresse des Autor ist tot. Dort hatte
    ich natürlich zuerst angefragt. Dieser Dienst läuft unter Vista nicht und ich
    kann ihn nicht debuggen. Ansonsten bitte ich um ein Demo welches unter Vista
    läuft. Bitte eines das nachprogrammierbar ist.

    Man kann auch auf einfache Weise Service sunter Vista debuggen. Das ist nicht anders als unter W2K oder XP. Man muss in jedem Fall VS als Admin starten. Dann kannst Du Dich an den entsprechenden Prozess attachen.

    Wenn DU den Source Code hast, kanst Du dem doch genau auf den Grund gehen. Zudem erlauben es viele Services auch einfach als Konsolen Program gestartet wu werden. Dann ist das Debuggen ein Kinderspiel.
    Da Du den Sourcecode hast sollte das ja kein Hindernis sein.


Anmelden zum Antworten