Funktion nach main ausführen?



  • Deine Frage und der Code haben nichts miteinander zu tun.

    Die Antwort auf deine Frage ist mit atexit
    http://en.cppreference.com/w/cpp/utility/program/atexit



  • LordJaxom schrieb:

    Hatten wir die Diskussion nicht kürzlich erst? 🙂

    Naja, nicht direkt, mein aktuelles Problem ist auf jedenfall neu:

    LordJaxom schrieb:

    Wenn main beendet ist, ist das Programm beendet. Komplett. Alle Deine Threads werden zerstört. Ergo: Gar nicht. Die Lösung: Joine Deine Threads vor Programmende.

    Möchtest Du, dass Dein Programm zur Konsole zurückkehrt und im Hintergrund weiterläuft? Dann benutze keine Threads, sondern starte einen Hintergrundprozess.

    Ich möchte nicht mehr benötigte Dateien wegräumen nachdem das Program fertig ist. Das geht leider erst danach, weil die Anwendung (an der ich gerade rumbastel) die Dateien aus irgendeinem Grund geöffnet hat bis sie beendet ist.

    Deswegen würde ich nach dem Beenden gerne kurz warten bis die Dateien wieder "freigegeben" sind und diese dann löschen.

    Kann man einen Process auch mit einer "normalen" Funktion starten oder braucht man dafür unbedingt eine exe? Das würde ich dann nämlich gerne vermeiden...

    manni66 schrieb:

    Deine Frage und der Code haben nichts miteinander zu tun.

    Die Antwort auf deine Frage ist mit atexit
    http://en.cppreference.com/w/cpp/utility/program/atexit

    Hm habs grade probiert, das funktioniert leider auch nicht. Die Dateien werden erst freigegeben wenn die Funktion die mit atexit registriert wurde beendet wird...



  • happystudent schrieb:

    Ich möchte nicht mehr benötigte Dateien wegräumen nachdem das Program fertig ist. Das geht leider erst danach, weil die Anwendung (an der ich gerade rumbastel) die Dateien aus irgendeinem Grund geöffnet hat bis sie beendet ist.

    Deswegen würde ich nach dem Beenden gerne kurz warten bis die Dateien wieder "freigegeben" sind und diese dann löschen.

    Bedeutet "an der ich gerade rumbastel" , dass Du die Anwendung geschrieben hast oder jemand anderes hat die geschrieben und du fummelst da gerade drann rum?

    Denn fuer mich sieht es eher so aus als ob man, dass Dateien handling fixen sollte, um was fuer Dateien handelt es sich denn?



  • Dann solltest Du vielleicht eher das Problem lösen, dass die Dateien bis nach dem Ablauf von main geöffnet bleiben, als zu versuchen, irgendwelche dirty hacks zu implementieren, um das Problem zu umschiffen.

    Zumal Dir das auch nichts bringen wird. Wenn es so ist wie Du schilderst, werden die Dateien nach Programmende vom Betriebssystem abgeräumt, und das wird auch so bleiben wenn Du das Programmende noch ein bisschen hinauszögerst.



  • LordJaxom schrieb:

    Dann solltest Du vielleicht eher das Problem lösen, dass die Dateien bis nach dem Ablauf von main geöffnet bleiben, als zu versuchen, irgendwelche dirty hacks zu implementieren, um das Problem zu umschiffen.

    Zumal Dir das auch nichts bringen wird. Wenn es so ist wie Du schilderst, werden die Dateien nach Programmende vom Betriebssystem abgeräumt, und das wird auch so bleiben wenn Du das Programmende noch ein bisschen hinauszögerst.

    Ruvi schrieb:

    Bedeutet "an der ich gerade rumbastel" , dass Du die Anwendung geschrieben hast oder jemand anderes hat die geschrieben und du fummelst da gerade drann rum?

    Denn fuer mich sieht es eher so aus als ob man, dass Dateien handling fixen sollte, um was fuer Dateien handelt es sich denn?

    Also die Anwendung ist nicht von mir sondern Open Source verfügbar (auch schon ziemlich alt). Die Dateien sind verschlüsselte zip Archive.

    Ich will jetzt die Anwendung um ein paar kleine Funktionen erweitern. Das Dateien-Handling zu fixen wäre natürlich der beste Weg. Nur leider werde ich das zeitlich nicht schaffen, weil die Anwendung ziemlich groß ist und ich einfach nicht soviel Zeit investieren kann um das alles umzuschreiben.

    Deswegen hätte ich gerne einen "dirty hack", der das Problem schnell löst, wenn man so will.



  • Warum sollten die Dateien nach main freigegeben sein? Wenn jemand zu blöd ist close aufzurufen, werden die Dateien von Betriebssystem geschlossen, wenn der Prozess komplett beendet ist. Da kannst du nichts mehr ausführen, da ist main schon lange beendet.



  • Und du bist dir sicher, dass es nicht dein Fehler ist und du vergessen hast irgendwas freizugeben? Ist bei C-Libraries nichts ungewöhnliches:

    irgendnenmetadatastruct bla;
    libname_open(&bla, "whatever.zip");
    //irgendwann später
    libname_free(&bla);
    


  • Welches Programm? (Ist ja Open Source...)
    Welches Betriebssystem?



  • manni66 schrieb:

    Warum sollten die Dateien nach main freigegeben sein? Wenn jemand zu blöd ist close aufzurufen, werden die Dateien von Betriebssystem geschlossen, wenn der Prozess komplett beendet ist. Da kannst du nichts mehr ausführen, da ist main schon lange beendet.

    Deswegen suche ich ja auch nach einer Methode um Code nach main auszuführen, also wenn das Betriebssystem die Dateien geschlossen hat. Sprich wenn der main Prozess schon komplett beendet ist.

    tkausl schrieb:

    Und du bist dir sicher, dass es nicht dein Fehler ist und du vergessen hast irgendwas freizugeben? Ist bei C-Libraries nichts ungewöhnliches:

    Ja, bin mir sicher weil ich auch mit dem unmodifizierten, original-Code die Dateien nicht löschen kann (auch nicht manuell) sobald ich das Program starte.



  • mach mal ein einfaches Beispiel mit fstream::open() und fstream::close() an dem Du zeigst, das man nach file.close() nicht von einem anderen Prozess aus auf die Datei zugreifen kann.

    (So in der Art wie hier: http://www.cplusplus.com/reference/fstream/fstream/open/)



  • happystudent schrieb:

    Deswegen suche ich ja auch nach einer Methode um Code nach main auszuführen, also wenn das Betriebssystem die Dateien geschlossen hat. Sprich wenn der main Prozess schon komplett beendet ist.

    Du kannst keinen Code nach main ausführen, wenn der Prozess schon komplett beendet ist, weil der Prozess dann schon komplett beendet ist.

    Die einzige Möglichkeit wäre, den Aufruf des Programms in einem Shell-Script zu wrappen, welches danach die Dateien löscht.



  • Also nur mal um deine Ausgangs-Situation zu verstehen:

    Wenn man sich mal zusammen-reimt was du überhaupt machen musst.

    - Du hast eine open-Source lib
    - Die verwendet irgendwelche Datein
    - Die lib schließt die Datein nicht, sondern die werden erst nach main() von OS aufgeräumt
    - Jetzt willst du aber, nehme ich mal an, IN dem soure-code von der lib selber die Datein am Ende löschen lassen

    Das heißt du schreibst den Source der Lib selber um und willst erreichen, dass diese Lib, zusätzlich zu der Funktionalität, die sie wohl schon bietet, die Datein am Ende löscht.

    Da diese aber im Source-Code nie freigegeben werden und du auch nicht weißt, wie du sie freigeben sollst, hättest du gerne, dass du nach dem OS-Aufräumen irgendwie Code ausführen könntest?

    Ist das so richtig??
    Und was hält sich davon ab, die streams vorher zu .closen()?? Gibt es soviele Handles dazu und du kennst nur die Datei-Namen (schließlich kannst du die Datei ja anscheinend per Code löschen, theoreitsch) oder hä?



  • Es geht ihm glaube ich nicht darum, Dateien wieder freizugeben, sondern bestimmte Dateien zu löschen wenn das Programm "fertig" ist.



  • Das wäre aber völlig problemlos und ich verstehe sein Unmut gegenüber den hier bereits vorgeschlagenen Lösungen nicht.

    Die einzige Erklärung ist für mich, dass er will, dass diese Lib selber die Datein löscht.
    D.h er schreibt in deren Source-Code rum.

    Da kann er sie aber nicht löschen, ohne sie freizugeben. Es sei denn er kann irgendwie auf magische Art und Weise diese Lib code ausführen lassen, nachdem das OS das Aufräumen für ihn übernommen hat.



  • Mhmm schrieb:

    Also nur mal um deine Ausgangs-Situation zu verstehen:

    Genau, richtig verstanden. Die streams will bzw. kann ich davor nicht closen da das Projekt rießig ist und ich nicht die Zeit habe das im Detail alles zu verfolgen/verstehen. Das Ganze ist im Rahmen eines Praktikums und das Tool ist eigentlich nur Mittel zum Zweck (soll aber die beschriebene Funktionalität bekommen).

    sdfdsfsdfd schrieb:

    Es geht ihm glaube ich nicht darum, Dateien wieder freizugeben, sondern bestimmte Dateien zu löschen wenn das Programm "fertig" ist.

    Genau, wobei eben das Problem ist dass die Dateien noch von dem Program "blockiert" sind.

    Mhmm schrieb:

    Da kann er sie aber nicht löschen, ohne sie freizugeben. Es sei denn er kann irgendwie auf magische Art und Weise diese Lib code ausführen lassen, nachdem das OS das Aufräumen für ihn übernommen hat.

    Genau so eine Magie suche ich 😃

    asdfasdf schrieb:

    mach mal ein einfaches Beispiel mit fstream::open() und fstream::close() an dem Du zeigst, das man nach file.close() nicht von einem anderen Prozess aus auf die Datei zugreifen kann.

    Das Problem ist ja gerade dass file.close() nicht aufgerufen wird. Mit einem Prozess geht es ja:

    // file_deleter.exe
    
    #include <boost/filesystem.hpp>
    #include <boost/thread.hpp>
    
    int main(int argc, char* argv[])
    {
    	if (argc < 2)
    	{
    		return 0;
    	}
    	boost::this_thread::sleep_for(boost::chrono::milliseconds(3000)); // Warte bis Betriebssystem aufgeräumt hat
    	boost::filesystem::path dir_path(argv[1]);
    	boost::filesystem::remove_all(dir_path);
    }
    
    //app.exe
    
    #include <fstream>
    #include <string>
    #include <boost/filesystem.hpp>
    #include <windows.h>
    
    int main()
    {
    	std::string path = "Pfad zum Ordner der gelöscht werden soll";
    	std::ofstream file((path + "\\tmp.txt").c_str()); // Wird von main nicht geschlossen!
    	file << "bla";
    
    	std::string file_delete_exe = "Pfad zur file_deleter.exe";
    
    	STARTUPINFOA si;
        PROCESS_INFORMATION pi;
    
        ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );
    
        std::string cmd = file_delete_exe + " \"" + path + "\"";
        CreateProcessA(NULL, &cmd[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    }
    

    Das klappt auch so schon. Problem ist halt dass ich ne zusätzliche .exe brauche umd die Aufräum-Aktion durchzuführen.
    Besser wäre es, ich könnte dem Process einfach eine Funktion übergeben (ähnlich wie einem std::thread/boost::thread). Leider scheint es ja kein boost::process oder ähnliches zu geben, das die Sache vereinfachen würde ...



  • welche Open-Source Lib? Name? Link? - dann kann man da den Fehler einfach fixen und dann kannst du am Ende deiner main löschen was immer du willst



  • Gast3 schrieb:

    welche Open-Source Lib? Name? Link? - dann kann man da den Fehler einfach fixen und dann kannst du am Ende deiner main löschen was immer du willst

    Tut doch nichts zur Sache oder? Keiner wird sich die Zeit nehmen um so ein großes Projekt zu fixen (das verlange ich ja auch gar nicht), das man noch dazu nur mit bestimmter Hardware dann überhaupt testen kann.

    Frage ist einfach: Kann ich einen Prozess mit einer Funktion im eigenen Code starten oder brauche ich zwingend eine exe?

    Was mir vorschwebt wäre etwas der Art:

    #include <iostream>
    
    void foo()
    {
        std::cout << "hi from process\n";
    }
    
    int main()
    {
        process p(foo);
        p.start();
    }
    


  • Wenns nur darum geht nach Programm Ende eine Datei zu löschen, ruf das Programm doch mit einer Batch Datei auf und lösch die Dateien dort. Oder schreib einen proxy der die Dateien löscht nachdem das Programm beendet ist.



  • Das wurde bereits vorgeschlagen, scheint dem TE aber zu einfach zu sein. Er hätte es gerne kompliziert...


  • Mod

    Jedes gängige Betriebssystem bietet Funktionen an, mit denen man temporäre Dateien erzeugen kann, die bei Prozessende (oder beim Schließen) automatisch gelöscht werden. Schönerweise sind die verschiedenen Betriebssysteme sich sogar halbwegs einig, wie das vonstatten gehen soll:
    https://msdn.microsoft.com/en-us/library/x8x7sakw.aspx
    http://linux.die.net/man/3/tmpfile
    Unschön ist natürlich, dass man einen FILE* zurück bekommt. Das heißt, man muss sich einen streambuf schreiben, der intern einen FILE* kapselt. Boost hat, wenn ich mich recht erinnere, eine fertige Lösung.

    Unter Linux kann man eine Datei auch unlinken, noch während sie offen ist. Sie wird dann gelöscht, nachdem sie geschlossen wird (also z.B. nachdem dein Prozess beendet wurde). Windwos kennt sicherlich ähnliche Mechanismen.


Anmelden zum Antworten