Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo,

wie kann ich einen Service schreiben? Also eigentlich ein kleines Programm, dass komplett im Hintergrund läuft. Es soll von dem Programm nichts sichtbar sein, also keine Oberfläche. Wenn man den Prozess im Taskmanager sieht, macht das allerdings nichts.

Ein kleines Beispiel würde mir schon sehr helfen.

Das wichtigeste ist halt, dass man keine Oberfläche sieht, also auch keine Dosbox oder so.

Achja, es soll wirklich so laufen, also bitte nicht mit irgendwelchen Hilfsprogrammen wie AppToService oder so. Die helfen mir nichts.

Geschrieben

Dazu brauchst du im Prinzip keinen Dienst. Eine einfache Windowsanwendung, die kein Fenster erstellt, ist nur im Taskmanager zu sehen. Das Problem daran ist nur: Solange du keine andere Möglichkeit einbaust, kann so eine Anwendung auch nur über den Taskmanager beendet werden, und beim Herunterfahren kommt die bekannte Meldung "Anwendung reagiert nicht".

Mit einem Dienst geht das besser. Darüber hinaus kann ein Dienst auch laufen, wenn kein Benutzer angemeldet ist. Allerdings sind Dienste ein wenig komplizierter.

Siehe dazu MSDN Library:

http://msdn.microsoft.com/library/en-us/dllproc/base/services.asp

Geschrieben

Achso, hm.

Ja, das mit keinem Fenster ist in MFC nicht so einfach. Mit direkter WinAPI ginge das vielleicht, hab ich noch nicht probiert.

Das Programm soll eigentlich eh nur laufen, wenn jemand angemeldet ist, aber die "Programm reagiert nicht"-Meldung ist dann doch störend.

Ich schau mal deinem Link nach.

Danke für die schnelle Antwort.

Geschrieben
Original geschrieben von FinalFantasy

Achso, hm.

Ja, das mit keinem Fenster ist in MFC nicht so einfach. Mit direkter WinAPI ginge das vielleicht, hab ich noch nicht probiert.

Das Programm soll eigentlich eh nur laufen, wenn jemand angemeldet ist, aber die "Programm reagiert nicht"-Meldung ist dann doch störend.

Ich schau mal deinem Link nach.

Danke für die schnelle Antwort.

Am Rande: Ist kein Problem ne MFC Anwendung ohne Fenster zu schreiben.

Geschrieben

Ok, stimmt. Aber da krieg ich wirklich ne "Anwendung reagiert nicht" Fehlermeldung beim Runterfahren, und das stört schon. Ausserdem kann ich so nicht in den EventLog schreiben, oder?

Hat nicht zufällig jemand ein Gerüsst für nen Service? Da braucht ja nichts ausprogrammiert sein drin.

Hab den Beitrag ind der MSDN auch gelesen, das Beispiel kompiliert bei mir sogar, allerdings wird der Service nicht gestartet, wenn ich das Ausführe.

Geschrieben
Original geschrieben von FinalFantasy

Ausserdem kann ich so nicht in den EventLog schreiben, oder?

Warum solltest du das nicht können?

Hab den Beitrag ind der MSDN auch gelesen, das Beispiel kompiliert bei mir sogar, allerdings wird der Service nicht gestartet, wenn ich das Ausführe.
Einen Service startet man auch nicht so. Dienste werden vom Dienstmanager gestartetet und beendet. Wenn ich mich richtig an das MSDN-Beispiel erinnere, musste man es mit einem bestimmten Parameter starten, damit der Dienst beim Dienstmanager eingetragen wird. Der übernimmt den Rest.
Geschrieben

Hier ist das Beispiel:

 
#include <windows.h>
#include <stdio.h>

SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;

VOID SvcDebugOut(LPSTR String, DWORD Status);
VOID WINAPI MyServiceStart (DWORD argc, LPTSTR *argv);
VOID WINAPI MyServiceCtrlHandler (DWORD opcode);
DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv, DWORD *specificError);

void main( )
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ "MyService", MyServiceStart },
{ NULL, NULL }
};

if (!StartServiceCtrlDispatcher( DispatchTable))
{
SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error = %d\n", GetLastError());
}
}

VOID SvcDebugOut(LPSTR String, DWORD Status)
{
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
}
}


void WINAPI MyServiceStart (DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;

MyServiceStatus.dwServiceType = SERVICE_WIN32;
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(
"MyService",
MyServiceCtrlHandler);

if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler failed %d\n", GetLastError());
return;
}

// Initialization code goes here.
status = MyServiceInitialization(argc,argv, &specificError);

// Handle error condition
if (status != NO_ERROR)
{
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
MyServiceStatus.dwWin32ExitCode = status;
MyServiceStatus.dwServiceSpecificExitCode = specificError;

SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
return;
}

// Initialization complete - report running status.
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error%ld\n",status);
}

// This is where the service does its work.
SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0);

return;
}


VOID WINAPI MyServiceCtrlHandler (DWORD Opcode)
{
DWORD status;

switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.
MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;

if (!SetServiceStatus (MyServiceStatusHandle,
&MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status);
}

SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0);
return;

case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;

default:
SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n",
Opcode);
}

// Send current status.
if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld\n",status);
}
return;
}


DWORD MyServiceInitialization(DWORD argc, LPTSTR *argv,
DWORD *specificError)
{
argv;
argc;
specificError;
return(0);
}

[/PHP]

wie man sieht, übernimmt die Main-Funktion nichtmal Argumente. Was für ein Argument solltes dass dann sein? Muss ich das vielleicht als ein bestimmtes Projekt anlegen?

Oder irgendwo das Programm eintragen?? (Services unter Wind2k-Administrative Tools....)

Geschrieben

@Final Fantasy

Ich habe noch nicht mit C++/MFC gearbeitet, aber schon mit Delphi einen kleinen Dienst geschrieben. Damit der Dienst in der Systemsteuerung/Dienste erscheint, musste man da in der Eingabeaufforderung das programm mit /install aufrufen (z.B. "Dienst.exe/install") . Danach konnte man den Dienst entweder in der Eingabeaufforderung mit "net start Dienst" oder in der Systemsteuerung/dienste starten. Müsste ja mit C++/MFC genauso sein.

Geschrieben

@FinalFantasy:

Was du da hast, ist der reine Dienst, ohne Installationsfunktionalität. Ich hatte da wohl ein anderes Beispiel in Erinnerung.

Du musst diesen Dienst noch registrieren, damit du ihn starten kannst. Wie das geht, findest du hier.

Geschrieben

Ah, das war genau der Punkt, der mir gefehlt hat. Danke schonmal, soweit läufts jetzt.

Jetzt muss ich noch rausfinden, wie ich EventLog-Einträge schreibe, aber ich schau erstmal, ob ich das selber rausbringe.

Danke schonmal.

Geschrieben

Ok, für alles was ich bis jetzt als EventLog gefunden hab, muss man eine Ressource anlegen, diese seperat compilieren, und dann erst immer laden....

Gibts nicht ne Möglichkeit, da einfach nur einen String reinzuschreiben??

Eine Messagebox kann man auch nicht anzeigen, aus einem Service raus, oder? Weil der Bezug zu nem Fenster/Desktop fehlt. Naja, irgendwie muss es ja gehen...

hm.....

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...