Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

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.

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

  • Autor

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.

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.

  • Autor

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.

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.
  • Autor

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....)

@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.

  • Autor

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.

  • Autor

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.....

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.