Was passiert?
-
Hi,
ich habe eine Singleton Klasse deren Dekonstruktor ich aufrufen muss, das Problem liegt jedoch darin das der Dekonstruktor nicht aufgerufen wird, wenn ich z.B. das Konsolenfenster mit einem X schließe. Dies hängt wohl mit einer Endlosschleife zusammen. Wie kann ich nun trotzdem allen Speicher aufräumen und den Dtor der Singleton Klasse aufrufen? Ich bin verzweifelt und brauche eure Hilfe!Vielen Dank
Gruß
// Singleton.cpp ... Ctor Dtor ... // Blub.cpp void Foo() { Endlosschleife } ... ???
-
wenn du das konsolenfenster an dem X schließt, wird meines wissens das laufende programm abgebrochen.
vgl die meldung, die erscheint, wenn man edit.exe an dem X zu macht.
-
piXelshooter schrieb:
wenn du das konsolenfenster an dem X schließt, wird meines wissens das laufende programm abgebrochen.
vgl die meldung, die erscheint, wenn man edit.exe an dem X zu macht.
So ein Schwachsinn, das will er doch nicht wissen. Erreich erstmal das 16. Lebensjahr
-
Du wirst wohl oder Übel einen Handler installieren müssen der das im Notfall für dich übernimmt (wundert mich aber, dass das nicht automatisch passiert).
Schau dir mal SetConsoleCtrlHandler() in der MSDN an.
MfG SideWinder
-
naja, dass nicht abgespeichrt wird beim consolenprogrammieren, liegt daran, das Die Konsole auf einem nicht multitasking fähigem System aufbaut, und somit keine abfangmöglichkeiten für von aussenkommende Befehle, wie "Fenster wird geschlossen, bitte mach zu ende" hat. Folglich kann windows das Programm nur abwürgen. Sobald du aber weg von der Konsole bist, dann kannst du es abfangen, wenn jemand versucht das fenster zu schließen. Allerdings kann man dann immernoch den Prozess des sauberen beendens umgehen, wenn man das Programm mit dem Taskmanager abwürgt. Mit den handles übergibst du sozusagen den Prozess des sauberen beendens an ein andern Prozess, da ich allerdings ausser in Java noch nie mit sowas gearbeitet habe kann ich nicht sagen ob es funktioniert
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum DOS und Win32-Konsole verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Ich habe zum Testen, dass ganze mal auf eine Win32-Anwendung übertragen:
#include <windows.h> #include <stdio.h> class X { public: X() { MessageBox( NULL, "Ctor", "!", NULL ); } ~X() { MessageBox( NULL, "Dtor", "!", NULL ); } }; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { X *Temp = new X; while( true ) // Eine Endlosschleife... Sleep(1); delete Temp; // Ich brauche den Dtor!!! return 0; }
Ich schätze, dass verdeutlich das Problem, denn die letzte MessageBox wird nicht angezeigt.
-
hast du mal versucht die WM_DESTROY abzufangen? also in der win32
-
#include <windows.h> class Test { public: Test() { MessageBox( NULL, "Test Ctor", "Debug", NULL ); } ~Test() { MessageBox( NULL, "Test Dtor", "Debug", NULL ); } }; LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); Test TEST; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { // [...] return msg.wParam; } // Die Hauptnachrichtenschleife LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CLOSE: case WM_QUIT: case WM_DESTROY: MessageBox( hwnd, "DEBUG", "DEBUG", NULL ); PostQuitMessage (0); return 0; break; } return DefWindowProc (hwnd, message, wParam, lParam); }
Ledier wird auch hierkein Dtor aufgerufen...
-
Um konkreter zu werden:
- Das Programm wird gestartet
- Das Programm soll, wenn Windows wieder heruntergefahren wird, wieder korrekt/sauber beendet werden: Es sollen ALLE Dekonstruktoren korrekt aufgerufen werden!Welche Möglichkeit bleibt mir da? Das ganze soll als Server fungieren und daher auch Logs schreiben, es wäre also schade, wenn die Log-Klasse und andere Klassen mangels fehlenden Dekonstruktor aufrufen ihre Arbeit nicht richtig machen würden.
Daher die Frage: Wie realsiert man sowas in Windows? Das Programm brauch vorerst nur im Hintergrund laufen und kein eigenständiges Dialog... Wichtig ist das ich meine Endlosschleife, die für einen Austausch von Daten zuständig ist ohne Probleme wieder einbauen kann. Ich hoffe mein Problem wird langsam ersichtlich und jemand findet eine Idee, die mir wirklich weiterhilft.
Viele Grüße
Wasnun
-
Wasnun schrieb:
Wie realsiert man sowas in Windows?
Als Service
Beginner's introductory guide to writing, installing, starting, stopping NT services
greetz, Swordfish
-
Swordfish schrieb:
Wasnun schrieb:
Wie realsiert man sowas in Windows?
Als Service
Beginner's introductory guide to writing, installing, starting, stopping NT services
greetz, Swordfish
Vielen Dank
Ich habe nun folgendes geschrieben:
SERVICE_TABLE_ENTRY ServiceTable[] = { { ServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, { NULL, NULL } }; if ( !StartServiceCtrlDispatcher( ServiceTable ) ) { char Temp[1024 * 4]; sprintf( Temp, "%d", (LPCSTR) GetLastError ); // Liefert jedoch: 2089943857. Warum!? MessageBox( NULL, Temp, "LOL", NULL ); return 1; }
Was bedeutet diese Fehlermeldung ich finde zu ihr leider nicht genügend Informationen. Und wie kann ich das ganze bitte beheben? Würde mich über eure Hilfe sehr freuen.
Viele Grüße
-
Erstens: Deine Ausgabe liefert dir nur die Adresse der GetLastError()-Funktion (oder hast du die Klammern nur beim Abtippen vergessen?)
Zweitens: Schau dir mal FormatMessage() an - das kann aus einer Fehlernummer eine lesbare Meldung erzeugen.
-
Also viel mehr helfen tut mir das nicht
Ich lache mich tot... Omgggggggggggggggggg... Haben die alle Humor lol lol
Der Dienstprozess konnte keine Verbindung zum Dienstcontroller herstellen
Top!!! Ne, danke soweit war ich dann doch schon L O L L OL
Ihre Tastatur wurde nicht gefunden, bitte drücken sie F1 für weitere Hilfe HAHA
-
Hi !
Wasnun schrieb:
..
Ledier wird auch hierkein Dtor aufgerufen...
...Ja, kein Wunder, keine Fensterklasse registriert und die Hauptnachrichtenschleife fehlt, das braucht Windoofie nun mal.
Oder hast du die hier ->// [...]
versteckt, in deiner WinMain ?
Was die Konsolenanwendung betrifft,
hattu nicht gucki macht:SideWinder schrieb:
Du wirst wohl oder Übel einen Handler installieren müssen der das im Notfall für dich übernimmt (wundert mich aber, dass das nicht automatisch passiert).
Schau dir mal SetConsoleCtrlHandler() in der MSDN an.
MfG SideWinder?
Check this out:
#include <windows.h> #include <stdio.h> BOOL WINAPI CtrlHandler (DWORD dwEvent) { switch (dwEvent) { case CTRL_C_EVENT: printf("CTRL_C_EVENT\n"); return 1; break; case CTRL_BREAK_EVENT: printf("CTRL_BREAK_EVENT\n"); return 1; break; case CTRL_LOGOFF_EVENT: printf(" CTRL_LOGOFF_EVENT\n"); return 1; break; // Windows schickt Shutdown Nachricht ans Fenster, vor dem Runterfahren. case CTRL_SHUTDOWN_EVENT: { puts("JJajaaaaa...Shutdown in 15 sekunden..."); Sleep(15000); ExitProcess(0); } return 1; // Benutzer klickt Fenster zu, oder beendet im Taskmanager case CTRL_CLOSE_EVENT: puts("Good Bye!"); // ExitProcess(0); return 1; default: puts("Kenn ich nich, mach ich nich."); break; // Handled all known events } return 1; } int main() { SetConsoleCtrlHandler (CtrlHandler, 1); while(1){}; return 0; }
Gruhuuußßß p.
-
Hi,
danke für deine AntwortInzwischen habe ich meine Anwendung auf Win32 umgestellt, jedoch läuft folgender Code nicht:
#include <windows.h> #include <stdio.h> char *ServiceName = "Son komischer Test"; HANDLE KillServiceEvent, ServiceThread; DWORD CurrentServiceStatus; bool ServiceRunning; SERVICE_STATUS_HANDLE ServiceStatusHandle; void ServiceMain( DWORD Argc, LPTSTR *Argv ); bool StartServiceThread(); DWORD ServiceExecutionThread( LPDWORD Param ); void KillService(); void ServiceCtrlHandler( DWORD nControlCode ); bool UpdateServiceStatus( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint ); int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { SERVICE_TABLE_ENTRY ServiceTable[] = { { ServiceName, (LPSERVICE_MAIN_FUNCTION) ServiceMain }, { NULL, NULL } }; if ( !StartServiceCtrlDispatcher( ServiceTable ) ) // HIER HAPERTS!!!!!!!!!!!!! WARUM? { DWORD eNum; TCHAR sysMsg[256]; TCHAR* p; eNum = GetLastError( ); FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, eNum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language sysMsg, 256, NULL ); p = sysMsg; while( ( *p > 31 ) || ( *p == 9 ) ) ++p; do { *p-- = 0; } while( ( p >= sysMsg ) && ( ( *p == '.' ) || ( *p < 33 ) ) ); MessageBox( NULL, sysMsg, "", NULL ); return 1; } return 0; } void ServiceMain( DWORD Argc, LPTSTR *Argv ) { ServiceStatusHandle = RegisterServiceCtrlHandler( ServiceName, (LPHANDLER_FUNCTION) ServiceCtrlHandler ); if ( !ServiceStatusHandle ) return; if ( !UpdateServiceStatus( SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000 ) ) return; KillServiceEvent = CreateEvent(0, true, false, 0 ); if ( !KillServiceEvent ) return; if ( !UpdateServiceStatus( SERVICE_START_PENDING, NO_ERROR, 0, 2, 1000 ) ) return; if ( !StartServiceThread() ) return; CurrentServiceStatus = SERVICE_RUNNING; if ( !UpdateServiceStatus( CurrentServiceStatus, NO_ERROR, 0, 0, 0 ) ) return; WaitForSingleObject( KillServiceEvent, INFINITE ); CloseHandle( KillServiceEvent ); } bool StartServiceThread() { DWORD ThreadId; ServiceThread = CreateThread( 0, 0, (LPTHREAD_START_ROUTINE) ServiceExecutionThread, 0, 0, &ThreadId ); if( !ServiceThread ) { return false; } else { ServiceRunning = true; return true; } } DWORD ServiceExecutionThread( LPDWORD Param ) { while( ServiceRunning ) { MessageBox( NULL, "Test-Service", "Service-Test", NULL ); Sleep( 4000 ); } return 0; } void KillService() { ServiceRunning = false; SetEvent( KillServiceEvent ); UpdateServiceStatus( SERVICE_STOPPED, NO_ERROR, 0, 0, 0 ); } void ServiceCtrlHandler( DWORD nControlCode ) { switch( nControlCode ) { case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_STOP: CurrentServiceStatus = SERVICE_STOP_PENDING; UpdateServiceStatus( CurrentServiceStatus, NO_ERROR, 0, 1, 3000 ); KillService(); return; default: break; } UpdateServiceStatus( CurrentServiceStatus, NO_ERROR, 0, 0, 0 ); } bool UpdateServiceStatus( DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint ) { SERVICE_STATUS ServiceStatus; ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ServiceStatus.dwCurrentState = dwCurrentState; if( dwCurrentState == SERVICE_START_PENDING ) { ServiceStatus.dwControlsAccepted = 0; } else { ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; } if( !dwServiceSpecificExitCode ) { ServiceStatus.dwWin32ExitCode = dwWin32ExitCode; } else { ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; } ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode; ServiceStatus.dwCheckPoint = dwCheckPoint; ServiceStatus.dwWaitHint = dwWaitHint; if ( !SetServiceStatus( ServiceStatusHandle, &ServiceStatus ) ) { KillService(); return false; } return true; }
Der Dienstprozess konnte keine Verbindung zum Dienstcontroller herstellen
-
Wasnun schrieb:
Der Dienstprozess konnte keine Verbindung zum Dienstcontroller herstellen
Die Fehlermeldung bekomme ich auch.
Im Gegensatz zu deiner ServiceMain-Funktion steht in der MSDN das sie als
VOID WINAPI
deklariert werden soll, was jedoch das Problem nicht behebt.Desweiteren kenne ich mich mit dieser Dienstgeschichte nicht aus und mich da jetzt reinzufuchsen ist mir zu aufwendig.
Dieser Link könnte dir weiterhelfen.
http://www.codeproject.com/system/serviceskeleton.aspMal am Rande, du willst doch nicht im Ernst einen Destruktor über einen Dienst aufrufen oder ?
Gruß, p.
-
Nein, er will sein ganzes Programm hoffentlich als Dienst laufen haben, das ist hier optimal.
Soll es doch eine Konsolenanwendung sein, sollte mein Vorschlag auf Seite 1 eigentlich funktionieren...
MfG SideWinder
-
SideWinder schrieb:
Nein, er will sein ganzes Programm hoffentlich als Dienst laufen haben, das ist hier optimal.
Soll es doch eine Konsolenanwendung sein, sollte mein Vorschlag auf Seite 1 eigentlich funktionieren...
MfG SideWinder
Hi,
also ich hatte erst an eine Konsolenanwendung gedacht, allerdings kommt die aufgrund des Fensters, dass nicht benötigt wird nicht in Frage. Wie man sieht ist mein Problem noch immer nicht gelöst... Hat nicht zufällig jemand ein vollständigen Code der mein Problem lösen könnte? Das Programm soll in eine Log-Datei schreiben, dieses wird über den Dtor erledigt. Die Endlosschleife ist zum ständigen Datenaustausch aufjedenfall notwendig!
-
http://www.codeproject.com/cpp/loggerservice.asp
MfG SideWinder