it-swarm.com.de

So kopieren Sie eine Datei, während Sie von einem anderen Prozess verwendet wird

Ist es möglich, eine Datei zu kopieren, die zur gleichen Zeit von einem anderen Prozess verwendet wird?

Ich frage, weil beim Versuch, die Datei mit folgendem Code zu kopieren, eine Ausnahme ausgelöst wird:

 System.IO.File.Copy(s, destFile, true);

Die hervorgehobene Ausnahme ist:

Der Prozess kann nicht auf die Datei 'D:\temp\1000000045.Zip' zugreifen, da er von einem anderen Prozess verwendet wird.

Ich möchte keine neue Datei erstellen, ich möchte sie nur kopieren oder löschen. Ist das möglich?

28
Vir

Ein Beispiel (Anmerkung: Ich habe gerade zwei Google-Ergebnisse kombiniert, möglicherweise müssen kleinere Fehler behoben werden;))

Der wichtige Teil ist der FileShare.ReadWrite beim Öffnen von FileStream.

Ich verwende einen ähnlichen Code, um Excel-Dokumente zu öffnen und zu lesen, während Excel noch geöffnet ist und die Datei blockiert.

  using(var inputFile = new FileStream(
         "oldFile.txt", 
         FileMode.Open, 
         FileAccess.Read, 
         FileShare.ReadWrite))
     {
        using (var outputFile = new FileStream("newFile.txt", FileMode.Create))
        { 
            var buffer = new byte[0x10000];
            int bytes;

            while ((bytes = inputFile.Read(buffer, 0, buffer.Length)) > 0) 
            {
                outputFile.Write(buffer, 0, bytes);
            }
        }
    }
33
Zebi

Um eine Kopie einer Datei zu erstellen, die von einem anderen Prozess unter Windows gelesen und/oder schreibgeschützt ist, ist die einfachste (und wahrscheinlich einzige) Lösung die Verwendung des Volume Shadow Copy Service (VSS).

Der Volume Shadow Copy-Dienst ist komplex und kann nur schwer mit verwaltetem Code aufgerufen werden. Glücklicherweise haben einige gute Chaps dafür eine .NET-Klassenbibliothek erstellt. Schauen Sie sich das Alpha-VSS-Projekt auf CodePlex an: http://alphavss.codeplex.com .

EDIT

Wie bei vielen Projekten auf CodePlex wurde auch Alpha VSS zu GitHub migriert. Das Projekt ist jetzt hier: https://github.com/alphaleonis/AlphaVSS

9
STLDev

Sie sollten herausfinden, welcher Prozess die Datei blockiert. Wenn dieser Prozess nicht Ihnen gehört, haben Sie keine Möglichkeit, das Problem zu lösen. Natürlich können Sie einige Hacks anwenden und die Dateisperre manuell freigeben, aber höchstwahrscheinlich führt dieser Ansatz zu unerwarteten Folgen. Wenn es sich um einen Prozess handelt, versuchen Sie, die Datei zu entsperren, oder sperren Sie sie mit Freigabezugriff.

[BEARBEITEN]
Der einfachste Weg, den Blocker-Prozess herauszufinden, wäre die Verwendung von Process Explorer . Starten Sie ihn und geben Sie den Dateinamen in das Dialogfeld Find->Find Handle or DLL... ein. In den Suchergebnissen können Sie sehen, welcher Prozess Ihre Datei blockiert. Sie können diesen Job auch in C # ausführen, um dies zu überprüfen: Welcher Prozess sperrt eine Datei? . Ebenfalls 

3
Anton Semenov

Nein, das kannst du nicht. Einige Programme sperren die Datei nicht zum Lesen, aber wenn dies der Fall ist, können Sie die Datei nicht aufrufen, ohne das andere Programm zu beenden.

0
GolezTrol

Nun, eine andere Option besteht darin, die gesperrte Datei mithilfe der Klasse Process irgendwo zu kopieren und CMD aufzurufen, um den Befehl "Kopieren" zu verwenden. In den meisten Fällen kann der Befehl "Kopieren" eine Kopie der Datei erstellen, auch wenn sie von einem anderen Prozess verwendet wird, wobei das Problem C # File.Copy umgangen wird.

Beispiel:

try
{
File.Copy(somefile)
}
catch (IOException e)
{
 if (e.Message.Contains("in use"))
                        {

                            Process.StartInfo.UseShellExecute = false;
                            Process.StartInfo.RedirectStandardOutput = true;                           
                            Process.StartInfo.FileName = "cmd.exe";
                            Process.StartInfo.Arguments = "/C copy \"" + yourlockedfile + "\" \"" + destination + "\"";
                            Process.Start();                            
                            Console.WriteLine(Process.StandardOutput.ReadToEnd());
                            Proess.WaitForExit();
                            Process.Close();                          
                        }
}

the try/catch should be added on top of your current try/catch to handle the file in use exception to allow your code to continue... 
0
MickeyM