문제

저는 현재 작은 C# 백업 프로그램을 작성 중입니다.나는 인터페이스에 대해 표준 Windows 양식을 사용하고 있으며 cmd.exe를 새 프로세스로 호출한 다음 이 새 프로세스 내에서 XCOPY를 사용하고 있습니다.제가 추가하고 싶은 마지막 기능인 작업을 중단시키는 기능을 제외하면 모든 것이 훌륭하게 작동합니다.

기본 명령 프롬프트에서는 ctrl+c를 사용하여 이 작업을 깔끔하게 수행할 수 있지만, 가능한 한 winforms 및 프로세스 접근 방식을 사용하여 이 기능을 복제할 수는 없습니다.표준 입력을 리디렉션하고 이를 사용하여 consolespecialkeys.ControlC를 프로세스에 보내려고 했습니다. 또한 0x03 및 "/x03"을 보내려고 했습니다. 둘 다 다른 포럼 게시물에서 읽은 적이 있는데 ctrl+c에 대한 16진수 코드입니다. .내가 보내는 내용은 등록되지 않았으며 프로세스를 종료하면 사용자 인터페이스가 종료되지만 xcopy.exe는 백그라운드에서 작동합니다.xcopy.exe를 수동으로 종료하면 복사 중이던 파일이 절반만 복사되고 손상된 채로 남게 됩니다. 이는 명령 프롬프트에서 Ctrl+C를 사용하여 발생하는 일이 아닙니다.

눈이 멀 정도로 분명한 것을 놓치고 있습니까?저는 C#을 처음 접하는 사람이므로 손을 잡고 이것이 느리거나 cmd.exe에서 프로세스가 작동하는 방식을 오해하고 있을 가능성이 높다는 것을 인정하겠습니다.그러나 프로세스는 표준 입력 리디렉션을 지원하므로 작동해야 하는 것처럼 보입니다...적어도 나에게는.내가 엉망인 부분을 식별하는 데 도움이 될 경우를 대비하여 아래에 내 코드의 기본 개요를 넣었습니다.

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();

누구든지 제공할 수 있는 도움에 미리 감사드립니다.

도움이 되었습니까?

해결책

나는 Besserwisser가되고 싶지 않지만 프로그램 내에서 복사하는 것이 훨씬 나아질 것이라고 생각합니다. System.io 네임 스페이스의 파일, 디렉토리 및 기타 클래스를 사용하면 정말 간단하며 진행 상황을보고, 작업 취소 등을 완전히 제어 할 수 있습니다.

다른 팁

예, .NET에서 작업을 수행하는 것이 더 쉬울 것입니다. 그러나 CTRL-C를 프로세스로 보내야하며 해당 옵션이 없습니다.

그래서이 질문에 대한 답을 얻을 수 있습니까?

편집하다: 답을 얻으려면 중복을 게시해야합니까? 그리고 @j0rd4n은 질문에 대답하지 않았습니다.

다른 사람들이 말했듯이, 그 특정 작업을 수행하는 더 좋은 방법이 있습니다. 그러나 그것은 당신의 질문에 대답하지 않습니다. 다양한 작업을 자동화하기 위해 여기에 보여준 것과 비슷한 기술을 사용하고 매우 유용합니다. 때로는 상황이 매우 나빠지고 상황이 악화되기 전에 프로세스가 구제되기를 원합니다. ;피

예제의 문제는 다음과 같습니다.

xcopystartinfo.createnowindow = true;

그것을 false로 설정하면 xcopyprocess.closemainwindow () 및 xcopyprocess.close ()를 처리합니다. kill ()을 사용하는 것보다 훨씬 깨끗합니다.

하위 디렉토리와 파일을 반복하고 하나씩 복사하려면 코드 줄이 적을 필요가 있습니다. 그러면 다른 프로세스 제어에 대해 걱정할 필요가 없습니다 ...

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

SW_HIDE로 생성된 cmd.exe 프로세스, 즉 숨겨진 cmd.exe 창에 CTRL-C 조합을 성공적으로 보냈습니다.

이 기술은 EnumWindows를 사용하여 프로세스를 식별하고 창 핸들을 가져오는 것이었습니다(표시되지 않더라도 메시지를 처리하는 핸들은 여전히 ​​있음).

다음으로 PostMessage를 사용하여 Ctrl-C 조합을 프로세스에 게시했습니다.이는 창이 활성화된 동안 사용자가 'ctrl-c'를 누른 것과 같은 효과를 가졌습니다.

C#에서 이 작업을 수행하려면 아마도 다음을 방문하고 싶을 것입니다. http://pinvoke.net/ - C#으로 Win32 API 함수 프로토타입을 작성할 때 생명의 은인이 됩니다.

이 방법으로 복사를 처리하려면 프로세스를 수동으로 죽여야합니다. 위의 코드에서 xcopyprocess.waitforexit (...)를 호출합니다. 이것은 차단 호출이므로 아동 C# 프로세스가 아동 프로세스가 완료되거나 Time-InterVal이 경과 할 때까지 해당 시점에서 중단됩니다.

당신이 할 수있는 일은 차단하는 대신, 사용자가 C# UI를 통해 프로세스를 죽 이도록 요청했는지 여부를 정기적으로 확인하는 루프에서 잠을 잘 수 있습니다. 이 행사를 받으면 과정을 명시 적으로 죽입니다. 그렇지 않으면 프로세스가 완료 될 때까지 다른 간격을 기다립니다.

편집하다: 그래도 다른 의견에 동의합니다. Xcopy를 사용하는 대신 .NET 프레임 워크에서 직접 복사하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top