Frage

Ich schreibe zur Zeit mir ein wenig C # back up-Programm. Ich bin mit einem Standard-Windows-Formular für die Schnittstelle und cmd.exe als neuen Prozess nenne, und dann XCOPY aus diesem neuen Verfahren. Alles funktioniert großartig, mit Ausnahme dieser letzten Funktion, die ich in hinzufügen möchten, was die Fähigkeit ist, den Betrieb zu unterbrechen.

Von einer nativen Eingabeaufforderung kann ich dies tun sauber mit ctrl + c, sondern versuchen, wie ich könnte, ich kann diese Funktionalität nicht replizieren die WinForms und Prozess-Ansatz. Ich habe versucht, die standardinput Umleitung und die Verwendung dieser consolespecialkeys.ControlC an den Prozess zu schicken, habe ich versucht, auch 0x03 Senden und „/ x03“, die ich beide auf anderen Forum-Beiträge gelesen habe sind Hex-Code für ctrl + c . Nichts, was ich bin das Senden wird, obwohl registriert, und verlässt den Prozess tötet die Benutzeroberfläche, lässt aber die xcopy.exe im Hintergrund arbeiten. Töten xcopy.exe manuell führt er die Datei so dass es die Hälfte kopiert und beschädigt wurde Kopieren, nicht etwas, das die ctrl + c in einer Eingabeaufforderung geschieht mit.

Fehle ich etwas blendend offensichtlich? Ich bin neu-ish zu C #, also werde ich meine Hände halten und gebe zu, das ist sehr wahrscheinlich, mich langsam zu sein, oder Missverständnis, wie der Prozess mit cmd.exe funktioniert. da Prozesse Standardeingabeumleitung unterstützen jedoch, so scheint es wie etwas, das sollte funktionieren ... zumindest für mich. Ich habe die Grundzüge meines Codes unten setzen, falls es hilft festzustellen, wo ich vermasselt.

string XCopyArguments = "\"" + dir.FullName + "\" \"" + destination + "\" /D /S /I /E";  
Process XCopyProcess = new Process();  
ProcessStartInfo XCopyStartInfo = new ProcessStartInfo(); 
XCopyStartInfo.FileName = "CMD.exe ";  
XCopyStartInfo.RedirectStandardError = true;
XCopyStartInfo.RedirectStandardOutput = true;
XCopyStartInfo.RedirectStandardInput = true;
XCopyStartInfo.UseShellExecute = false;
XCopyStartInfo.CreateNoWindow = true;
XCopyStartInfo.Arguments = " /D /c XCOPY " + XCopyArguments;
XCopyProcess.EnableRaisingEvents = true;
XCopyProcess.StartInfo = XCopyStartInfo;
XCopyProcess.Start();                
XCopyProcess.WaitForExit(15000);
int ExitCode = XCopyProcess.ExitCode;
if (ExitCode > 0 & !XCopyProcess.HasExited)
{
XCopyProcess.Kill();
}
XCopyProcess.Dispose();

Vielen Dank im Voraus für jede Hilfe jedermann bieten kann.

War es hilfreich?

Lösung

Ich will nicht ein besserwisser sein, aber ich glaube, Sie viel besser dran wäre das Kopieren in Ihrem Programm zu tun. Mit Dateien, Verzeichnisse und die anderen Klassen im System.IO-Namespace, es ist wirklich einfach, und lässt Sie in die volle Kontrolle Fortschritte berichten, abbrechen Operationen etc.

Andere Tipps

Ja, einfacher macht den Betrieb in .NET wäre. ABER, ich brauche auch ctrl-c ein Verfahren zum Senden und ich habe nicht diese Option.

So können wir bitte eine Antwort auf diese Frage bekommen?

EDIT: Muss ich eine Kopie zu schreiben, eine Antwort zu bekommen? Und nein, @ j0rd4n die Frage nicht beantworten.

Wie die anderen gesagt, es gibt bessere Möglichkeiten, dass bestimmte Aufgabe zu erfüllen. Sie jedoch, dass Ihre Frage nicht beantworten. Ich verwende eine ähnliche Technik, was Sie hier gezeigt haben verschiedene Aufgaben für die Automatisierung und finde es sehr nützlich. Manchmal gehen die Dinge sehr schlecht, obwohl und Sie wollen, dass der Prozess aus der Klemme zu helfen, bevor die Dinge noch schlimmer. ; P

Hier ist das Problem mit Ihrem Beispiel:

XCopyStartInfo.CreateNoWindow = true;

es auf false gesetzt, und es wird dann verarbeiten XCopyProcess.CloseMainWindow () und XCopyProcess.Close (). Viel sauberer als kill ().

Es würde weniger Codezeilen nur Schleife über die Unterverzeichnisse und Dateien benötigen und kopieren Sie sie eins nach dem anderen und dann würden Sie nicht über controling einen anderen Prozess zu kümmern ...

Leider ist es in VB.NET.

Declare Function GenerateConsoleCtrlEvent Lib "kernel32" ( _
                    ByVal dwCtrlEvent As Integer, _
                    ByVal dwProcessGroupId As Integer _
                    ) As Integer

Private Const CTRL_C_EVENT As Integer = 0

Private Sub SendCtrlC()
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0)

    ' send a Ctrl-C to this process
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, currentpid)

    ' send a Ctrl-C to the cmd process
    GenerateConsoleCtrlEvent(CTRL_C_EVENT, cmdpid)
End Sub

Ich habe gesendet erfolgreich eine CTRL-C-Kombination zu einem cmd.exe Prozess mit SW_HIDE erstellt - d. H, eineine versteckten cmd.exe Fenstern

Die Technik zu verwenden EnumWindows war, den Prozess zu identifizieren und bekommt es Fenstergriff (es hat noch einen Griff Nachrichten zu verarbeiten, auch wenn es nicht sichtbar ist).

Als nächstes habe ich eine Postmessage ctrl-c Kombination mit dem Verfahren zu stellen. Dies hatte die gleiche Wirkung, als wenn ein Benutzer ‚ctrl-c‘ getroffen hatte, während das Fenster aktiv war.

Dieses von C # zu tun, würden Sie wahrscheinlich besuchen http://pinvoke.net/ - lebensrettend wenn es um die Win32-API-Funktion Prototypen in C # zu schreiben.

Sie müssen manuell den Prozess beenden, wenn Sie das Kopieren auf diese Weise behandelt werden sollen. In Ihrem Code oben, rufen Sie XCopyProcess.WaitForExit (...). Dies ist ein blockierender Aufruf, so dass die Eltern C # Prozess an diesem Punkt anhalten wird, bis das Kind Prozess oder das Zeitintervall abgelaufen ist beendet.

Was Sie tun können, ist statt der Blockierung, können Sie in einer Schleife schlafen routinemäßig überprüft, ob der Benutzer den Prozess über C # UI zu töten angefordert hat. Wenn Sie dieses Ereignis erhalten, töten Sie explizit den Prozess. Andernfalls Sie für ein weiteres Intervall warten, bis der Vorgang beendet ist.

EDIT: ich mit den anderen Kommentaren einverstanden, though. Kopieren Sie direkt aus dem .NET-Framework statt xcopy verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top