Frage

Ich habe ein Update-Programm, das völlig unabhängig von meiner Hauptanwendung ist. Ich betreibe das update.exe die app.exe zu aktualisieren. Um zu überprüfen, ob die Datei in Gebrauch ist, es in einer anderen Datei verschieben und einen Fehler fangen, wenn er in Gebrauch ist. Wenn keine Probleme occurr benenne ich es zurück. Zumindest war das mein Plan ...

  

Hauptprogramm: app.exe
  Update-Programm: update.exe

Dieses Programm wird über das Netzwerk ohne laufende Dienste verwendet. So werden die Benutzer wahrsten Sinne des Wortes die exe über das Netzwerk auf thier Maschine ausgeführt wird.

Ich brauche die app.exe zu aktualisieren, wenn die update.exe ausgeführt wird. Um zu überprüfen, ob die app.exe noch in Gebrauch war ich folgend in einem Versuch wurde Einwickeln / catch zu sehen, ob es fehlgeschlagen:

  

IO.File.Move (upddir & "\ app.exe", upddir & "\ app.exe.tst")
  IO.File.Move (upddir & "\ app.exe.tst", upddir & "\ app.exe")

Das Komische ist, auch wenn die app.exe läuft, kann die Bewegung es ohne Fehler an den app.exe.tst umbenennen. Ich kann sogar ohne Fehler in der Anwendung fortsetzen.

Ich dachte, ich aus meinem Kopf war, so hatte ich eine andere Programmierer Blick auf diese und er bestätigt, was ich oben gesagt.

So haben wir versucht, diese in einer Try-Catch gewickelt:

  

Dim ReadFile- A New Filestream (upddir & "\ app.exe", FileMode.Open, FileAccess.Read, FileShare.NONE)
  readfile.Dispose ()

habe ich die Dateifreigabe wie keine, das, zumindest dachte ich, es würde zeigen, dass es jemand in der Datei war.

Es ging noch ohne Fehler.

Wer weiß, warum ich eine Datei in Gebrauch umbenennen? Außerdem gibt es einen besseren Weg, dies zu tun, als das, was ich jetzt mache?

Danke! Eroc

War es hilfreich?

Lösung

Sie können die folgende tun, um zu überprüfen, ob die Anwendung anderen Fällen hat ausgeführt wird:

Process.GetProcessesByName("app.exe", "Machine1").Length > 0

Welche ist eine geeignetere Möglichkeit zu überprüfen, ob die App ausgeführt wird.

Hier finden Sie aktuelle File.Move MSDN-Dokumentation. Es wird ausführlich auf, was Ausnahmen geworfen werden. Sie sind berechtigt, eine exe auch umbenennen, wenn er in Gebrauch in Vista ist.

Andere Tipps

Der gleiche Code unter Verwendung von "using":)

Public Function FileInUse(ByVal sFile As String) As Boolean
 Dim thisFileInUse As Boolean = False
 If System.IO.File.Exists(sFile) Then
     Try
       Using f As New IO.FileStream(sFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
                ' thisFileInUse = False
       End Using
     Catch
       thisFileInUse = True
     End Try
 End If
 Return thisFileInUse
End Function

Was könnten Sie tun, ist die Zielanwendung mit einem Hausmeister exe ersetzen.

Dieser Hausmeister dann laicht die Zielanwendung, sondern schafft auch eine gesperrte Datei in einem freigegebenen Speicherort. Die Sperre wird freigegeben und die Datei gelöscht wird, wenn der App beendet wird.

Dann, bevor Sie die app.exe aktualisieren Sie prüfen, gibt es keine gesperrten Dateien in dem freigegebenen Speicherort, wenn Dateien gesperrt werden dann die app.exe verwendet wird.

Der Hausmeister Programm eine fensterlose Anwendung sein könnte, wird die folgende Konsole App macht ziemlich genau, was es tun muß,

class Program
{
    static string lockFileName;
    static System.IO.StreamWriter lockFileWrtier;
    static void Main(string[] args)
    {
        lockFileName = "AppLock_" + System.IO.Path.GetRandomFileName();

        lockFileWrtier = new System.IO.StreamWriter(lockFileName);

        System.Diagnostics.Process p = new Process();
        p.StartInfo.FileName = "cmd.exe";
        p.EnableRaisingEvents = true;
        p.Exited += new EventHandler(p_Exited);

        p.Start();

        Console.WriteLine("Press any key to stop");
        Console.ReadKey();
    }

    static void p_Exited(object sender, EventArgs e)
    {
        lockFileWrtier.Dispose();
        System.IO.File.Delete(lockFileName);

        Console.WriteLine("Process has exited");
    }
}

Der Updater sucht dann für alle „AppLock_ *“ Dateien und versucht, sie mit einem Schreibsperre zu öffnen, wenn es nicht eine Schreibsperre auf einem von ihnen bekommen, die exe in Gebrauch ist.

Hope, das hilft.

Das ist, was ich am Ende tun. Die Netzwerk-Scan hat nicht funktioniert auf einem Peer-to-Peer-Netzwerk. Es hat nicht die anderen Computer beheben überhaupt.

Wie auch immer, hier ist es:

  

Private Sub CheckFileIfFileIsInUse (ByVal thefilename As String)
        versuchen Sie
            'Auf dem Vista-O können Sie eine Datei umbenennen, die in Gebrauch ist
            "Die‚in Verwendung‘von der Original-Datei folgt die neuen Dateinamen

      Dim testfile As String = thefilename & ".tst"<br />

      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

      ' so we have to rename it to something else<br />
      IO.File.Move(thefilename, testfile)<br />

      ' copy it back to the original file name in case something <br />breaks 
      ' this just keeps them in working order if it does<br />
      IO.File.Copy(testfile, thefilename)<br />

      ' then we try to delete the original file that could be in use <br />
      ' which will return an 'in use' error at this point<br />
      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

  Catch ex As Exception<br />
      'throw it to the originating method<br />
      Throw<br />
  End Try<br />
     

End Sub

Hope dies hilft, die nächste Person.

Public Function FileInUse(ByVal sFile As String) As Boolean
    If System.IO.File.Exists(sFile) Then
        Try
            Dim F As Short = FreeFile()
            FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)
            FileClose(F)
        Catch
            Return True
        End Try
    End If
End Function
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top