Zugriffsverletzung bei Dateizugriff



  • Nun habe ich doch noch eine Möglichkeit für'n exklusiven Dateizugriff gefunden.
    Nur leider kann ich die Exception dazu nicht handeln.

    Timer der alle 20ms die Datei schreibt

    void CZugriffTestDlg::OnTimer(UINT nIDEvent) 
    {
    	if (nIDEvent == 1)
    	{
    		KillTimer(1);
    
    		SchreibeDatei();
    
    		SetTimer(1, 20, NULL);
    	}
    
    	CDialog::OnTimer(nIDEvent);
    }
    

    Die eigentliche Schreibroutine

    bool CZugriffTestDlg::SchreibeDatei()
    {
    	CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive);
    	Inhalt = Inhalt + "Hallo\r\n";
    
    	try
        {
    		SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength());	
        }
        catch (CFileException &exception)
        {
    		AfxMessageBox("CATCH!!");
    		int *test  = &exception.m_cause;
    
    		//AfxMessageBox(e.m_cause);
            //if( e->m_cause == CFileException::fileNotFound )
        }
    
    	SchreibDatei.Close();
    
    	return true;
    }
    

    Mit der Schleife wird durch das ständige Aufrufen der Crash beider Schreibversuche provoziert ...

    void CZugriffTestDlg::OnOK() 
    {
    	SetTimer(1, 20, NULL);
    
    	while(SchreibeDatei())
    	{
    		Sleep(2);
    	}
    
    	//CDialog::OnOK();
    }
    

    eigentlich sollte es doch durch die Endlosschleife sowie das ständige 20ms Dateischreiben zur Zugriffsverletzung kommen.
    Warum komme ich nicht in die Catch-Routine rein????

    Gruß
    Blitzbirne


  • Mod

    Dein Fehler ist das Du eine Referenz fängst. Exceptions in der MFC werden als pointer geworfen.

    catch (CFileException *e) 
    {
    ...
    // Aufräumen nicht vergessen.
    e->Delete();
    


  • Super, vielen Dank!!
    Nun muß ich nur noch die Fehlermeldung des Systems unterdrücken.
    Wenn du da noch eine Idee hättest wäre ich dir sehr dankbar.
    Versuche es derweil schonmal selbst...


  • Mod

    Blitzbirne-C++ schrieb:

    Nun muß ich nur noch die Fehlermeldung des Systems unterdrücken.

    Was für eine Fehlermeldung?



  • Die Fehlermeldung welche das System in einer Messagebox ausgiebt:

    "Eine Zugriffsverletzung ist während des Zufriffs auf C:\zugriff.txt aufgetreten."

    Mein eigentliches Ziel ist es ja den Prozess, der momentan nicht zugreifen kann, in eine kleine Schleife zu schicken um direkt im Anschluß dann auf den File zuzugreifen.


  • Mod

    Wenn Du den ctach richtig setzt, gibt es keine MsgBox.
    Bitte poste noch mal Deinen Code.



  • Was ist denn ne CTACH? 😕

    void CZugriffTestDlg::OnTimer(UINT nIDEvent) 
    {
    	if (nIDEvent == 1)
    	{
    		KillTimer(1);
    
    		SchreibeDatei();
    
    		SetTimer(1, 20, NULL);
    	}
    
    	CDialog::OnTimer(nIDEvent);
    }
    
    bool CZugriffTestDlg::SchreibeDatei2()
    {
    	try
        {
    		CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive);
    		Inhalt = Inhalt + "Hallo\r\n";
    		SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength());
    		SchreibDatei.Close();
        }
        catch (CFileException *exception)
        {
    		if(exception->m_cause == CFileException::sharingViolation)
    
    		exception->Delete();
        }
    
    	return true;
    }
    
    void CZugriffTestDlg::OnOK() 
    {
    	SetTimer(1, 20, NULL);
    
    	while(SchreibeDatei2())
    	{
    		Sleep(2);
    	}
    
    	//CDialog::OnOK();
    }
    
    bool CZugriffTestDlg::SchreibeDatei()
    {    
    	try
        {
    		CFile SchreibDatei(Pfad, CFile::modeReadWrite | CFile::shareExclusive);
    		Inhalt = Inhalt + "Hallo2\r\n";
    		SchreibDatei.WriteHuge(Inhalt, Inhalt.GetLength());
    		SchreibDatei.Close();
        }
        catch (CFileException *exception)
        {
    		if(exception->m_cause == CFileException::sharingViolation)
    
    		exception->Delete();
        }
    	return true;
    }
    

  • Mod

    Den

    if(exception->m_cause == CFileException::sharingViolation)
    

    vergiss!

    Was bezweckst Du damit?

    Ich sehe keinen Code, der hier eine MessageBox auslöst!



  • Das System, sprich Windows, schmeisst die MessageBox.
    Mit meinem Code provoziere ich ja lediglich diese Zugriffsverletzung und teste mal dieses Try/Catch.
    Was halt jetzt stört ist der Umstand, dass mein Prozess sich komplett aufhängt sobald Windows diese Zugriffsverletzung registriert.
    Daher möchte ich dieses gar nicht erst entstehen oder zulassen.

    Meine richtige Applikation besteht aus ziemlich vielen Klassen, welche zu unterschiedlichen Zeiten auf Dateien zugreifen. In diesen Klassen läuft auch hin und wieder mal ein Timer mit, aus dehnen heraus auch auf Dateien zugegriffen wird.

    Leider muß ich noch eine besondere DLL einbinden (Fremdanbieter) auf die ich definitiv nicht verzichten kann. Vorab: diese DLL findet man nicht im Netz.
    Der Thread der durch den Fremdanteil gestartet wird verkraftet diese Fehlermeldungen nicht und reisst die ganze Applikation ins Jenseits.

    Da ich über die selbst entwickelten Teile ja vollste Kontrolle habe würde ich gerne die Zugriffe daraus gerne solange ausbremsen bis der FremdThread fertig ist.

    Hoffe es ist verständlich 🙂


  • Mod

    Du faängst aber mit diesem Code die Exception ab.
    Dieser Code den Du zeigst kann keine Fehlermeldung anzeigen!

    Undich kan mich nur wiederholen. Um zu wissen ob eine datei offen ist musst Du sie öffnen und auf den fehler reagieren.

    Dein Code den Du hier gezeigt hast, fängt die Exception ab und kann keinen Messagebox anzeigen!



  • Ich glaube wir reden da ein wenig aneinander vorbei ...

    Windows hat scheinbar ein Handle auf den Prozess über das Windows weiss welcher Fehler aufgetreten ist.
    Sobald nun eine Zugriffsverletzung auftritt, da mehrere Prozesse gleichzeitig auf eine Datei zugreifen, gibt mir Windows dies per MessageBox bekannt.
    Ich brauche also nicht expliziet eine MessageBox zu generieren.
    Nur genau in dem Moment reisst es meine Applikation ins Nirvana.

    Kann man die Message unterdrücken?
    WIe kann ich es hinkriegen, dass es nicht zu diesen Kollisionen kommen kann?

    Gruß
    Günni



  • Ich bevorzuge diese Variante:

    CFile file;
    CFileException exept;
    if(file.Open(...,&exept))
    {
    ...
    }
    else
    {
       char expbuf[256];
       exceptp.GetErrorMessage((LPTSTR)expbuf, 255);
    ...
    }
    

    Hast Du es damit schon probiert?



  • Noch nicht.
    Probiere es eben mal aus ...


  • Mod

    Blitzbirne-C++ schrieb:

    Ich glaube wir reden da ein wenig aneinander vorbei ...

    Windows hat scheinbar ein Handle auf den Prozess über das Windows weiss welcher Fehler aufgetreten ist. Sobald nun eine Zugriffsverletzung auftritt, da mehrere Prozesse gleichzeitig auf eine Datei zugreifen, gibt mir Windows dies per MessageBox bekannt.

    Solch einen Mechanismus gibt es in Windows nicht!
    Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!

    Ich brauche also nicht expliziet eine MessageBox zu generieren.
    Nur genau in dem Moment reisst es meine Applikation ins Nirvana.

    Kann man die Message unterdrücken?
    WIe kann ich es hinkriegen, dass es nicht zu diesen Kollisionen kommen kann?

    Mach einen Break im Debugger und schau Dir Dein Callstack an. Die Nachricht kommt von Dir!



  • Warum so kompliziert? Erzeuge vor dem Öffnen einer Datei eine Art Lock-Datei. Diese bleibt solange bestehen, wie die Datei verwendet wird. Wenn du jetzt mit dem anderen Thread zugreifen möchtest , überprüfst du voher , ob die Datei besteht, wenn ja warten, wenn nicht kanns losgehen. Hier mal son ein Freihand code (muss nciht korrekt sein)

    Öffnen

    int myfopen(char * filename, char* mode)
    {
       FILE *fp;
       bool check;
    
       if(fopen("Lock-Datei","rb") != 0)
          return 0; // Lockdatei vorhanden, abbrechen; Datei nicht freigeben
    
       fopen("Lock-Datei","w+"); // Lock Datei anlegen
       fp=fopen(filename,mode); // Datei öffnen, ist somit gesperrt für andere
    
       return fp;
    }
    
    void myfclose(FILE *fp)
    {
       flclose(fp);
       remove("Lock-Datei");
    }
    


  • Solch einen Mechanismus gibt es in Windows nicht!
    Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!

    Wie auch immer diese Exception den Weg als Messagebox auf meine Windowsoberfläche findet, so würde ich dies halt gerne unterdrücken.
    Wenn ich nur wüßte wie ...

    Mach einen Break im Debugger und schau Dir Dein Callstack an.

    Ich muß gestehen: Ich weiss nicht wirklich wie.

    Erzeuge vor dem Öffnen einer Datei eine Art Lock-Datei

    So in etwa habe ich es bisher versucht gehabt. Doch habe ich den Inhalt dieser Datei ausgewertet.
    Habe halt in diese Datei reingeschrieben ob gesperrt oder nicht.
    Das Resultat: Es kam oftmals beim Auswerten des Inhalts dieser Datei zur Zugriffsverletzung 😃
    Du öffnest sie ja gar nicht sondern überprüfst nur das Vorhandensein.
    Vielleicht funktioniert es ja so besser ...

    Habe evtl. schon eine funktionierende Form aus den gestriegen Infos gebaut. Teste es gerade aufs Extremste ...
    Lasse es euch wissen.
    Martin, wäre nett wenn du mir das mit dem Unterdrücken noch näher erklären könntest, da es mir die sauberste Lösung zu sein scheint.
    Kleines Codebeispiel würde mir als Noob 🤡 echt weiterhelfen.

    Bis hier schonmal ein Danke euch beiden ... 👍
    Ihr helft mir wirklich sehr.



  • Blitzbirne-C++ schrieb:

    Solch einen Mechanismus gibt es in Windows nicht!
    Der entsprechende Konstruktor den Du verwendest wirft eine Exceptin die man abfangen kann! Punkt!

    Wie auch immer diese Exception den Weg als Messagebox auf meine Windowsoberfläche findet, so würde ich dies halt gerne unterdrücken.
    Wenn ich nur wüßte wie ...

    Normalerweise erscheint diese MessageBox nur, wenn die Exception ihren Weg aus der Anwendung herausgefunden hat. Wenn du den relevanten Code in ein try-catch einschließt und dort die Exception verarbeitest, bekommt Windows gar nichts davon mit.

    Mach einen Break im Debugger und schau Dir Dein Callstack an.

    Ich muß gestehen: Ich weiss nicht wirklich wie.

    Bei uns im Magazin gibt es einen hilfreichen Artikel "Debuggen mit VC6" - den solltest du dir mal zu Gemüte führen.



  • NA meine Variante prüft doch nur die Existenz der Lock-Datei und schreibt sie nicht. Ist doch sone Art Auf Existensprüfung oder?



  • Hallo Leute,

    habe mir über's schöne lange WE nochmals Gedanken gemacht und baue mir gerade ein weiteres kleines Tool um die Zugriffsroutinen zu testen.
    Habe mich dafür entschieden diese ganzen Sperrdateien zu ersetzen gegen Sperrvariablen, welche aus dden verschiedenen Klassen zugängig sind.
    Sollte die elegantere Variante sein. MAl schauen wie ich das realisiert kriege.

    Was haltet ihr davon?

    Gruß
    Blitzbirne



  • mhh kommt daraus an, wenn das Prog alleine läuft müsste es gehen. Es kommen aber schon die Probleme wenn das Programm mehrfacha ufgerufen wird.


Anmelden zum Antworten