답변:
이것은 이름으로 수행하는 방법입니다.
Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
MessageBox.Show("nothing");
else
MessageBox.Show("run");
나중에 조작 할 수 있도록 모든 프로세스를 반복하여 ID를 얻을 수 있습니다.
Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
if/else
한 줄의 길이 인 C # 문은 블록 문을 나타 내기 위해 중괄호를 사용할 필요가 없습니다. 이것은 또한 진술 foreach
하고 진행 for
합니다. 코딩 스타일로 귀결됩니다.
for
. c # .net dev 년 동안 나는이 스타일을 본 적이 없다. 그들이 말하는 것처럼 "매일 새로운 것을 배우십시오". 게시물과 답장을 보내 주셔서 감사합니다 ..
이것이 리플렉터를 사용한 후 찾은 가장 간단한 방법입니다. 이를 위해 확장 방법을 만들었습니다.
public static class ProcessExtensions
{
public static bool IsRunning(this Process process)
{
if (process == null)
throw new ArgumentNullException("process");
try
{
Process.GetProcessById(process.Id);
}
catch (ArgumentException)
{
return false;
}
return true;
}
}
Process.GetProcessById(processId)
방법은 호출 ProcessManager.IsProcessRunning(processId)
방법과 발생 ArgumentException
과정이 존재하지 않는 경우에. 어떤 이유로 ProcessManager
수업은 내부에 있습니다 ...
동기식 솔루션 :
void DisplayProcessStatus(Process process)
{
process.Refresh(); // Important
if(process.HasExited)
{
Console.WriteLine("Exited.");
}
else
{
Console.WriteLine("Running.");
}
}
비동기 솔루션 :
void RegisterProcessExit(Process process)
{
// NOTE there will be a race condition with the caller here
// how to fix it is left as an exercise
process.Exited += process_Exited;
}
static void process_Exited(object sender, EventArgs e)
{
Console.WriteLine("Process has exited.");
}
reshefm은 꽤 좋은 대답을했습니다. 그러나 프로세스가 시작되지 않은 상황을 설명하지는 않습니다.
다음은 그가 게시 한 내용의 수정 된 버전입니다.
public static bool IsRunning(this Process process)
{
try {Process.GetProcessById(process.Id);}
catch (InvalidOperationException) { return false; }
catch (ArgumentException){return false;}
return true;
}
그의 ArgumentNullException은 실제로 null 참조 예외라고 가정하고 어쨌든 시스템에 의해 발생하기 때문에 프로세스가 시작되지 않았거나 close () 메소드를 사용하여 방법.
이 기능의 신뢰성에 달려 있습니다. 보유한 특정 프로세스 인스턴스가 여전히 실행 중이고 100 % 정확도로 사용 가능한지 알고 싶다면 운이 좋지 않습니다. 관리되는 프로세스 개체에는 프로세스를 식별하는 방법이 2 가지 밖에 없기 때문입니다.
첫 번째는 프로세스 ID입니다. 불행히도 프로세스 ID는 고유하지 않으며 재활용 할 수 있습니다. 일치하는 ID에 대한 프로세스 목록을 검색하면 동일한 ID를 가진 프로세스가 실행 중임을 나타내지 만 반드시 프로세스는 아닙니다.
두 번째 항목은 프로세스 핸들입니다. Id와 같은 문제가 있지만 작업하기가 더 어색합니다.
중간 수준의 안정성을 찾고 있다면 동일한 ID의 프로세스에 대한 현재 프로세스 목록을 확인하는 것으로 충분합니다.
Process.GetProcesses()
갈 길입니다. 그러나 프로세스 실행 방법 (예 : 제목 표시 줄의 유무에 관계없이 서비스 또는 일반 앱)에 따라 프로세스를 찾기 위해 하나 이상의 다른 기준을 사용해야 할 수도 있습니다.
어쩌면 (아마도) 질문을 잘못 읽고 있지만 Process 객체가 나타내는 프로세스가 정상적으로 종료되었는지를 나타내는 HasExited 속성을 찾고 있습니까?
참조하는 프로세스에 UI가있는 경우 응답 특성을 사용하여 UI가 현재 사용자 입력에 응답하는지 여부를 판별 할 수 있습니다.
EnableRaisingEvents를 설정하고 Exited 이벤트 (비동기 적으로 전송 됨)를 처리하거나 차단하려는 경우 WaitForExit ()를 호출 할 수도 있습니다.
원하는 프로세스에 대해 프로세스 인스턴스를 한 번 인스턴스화하고 해당 .NET 프로세스 오브젝트를 사용하여 프로세스를 계속 추적 할 수 있습니다 (추적중인 프로세스가 종료 된 경우에도 명시 적으로 해당 .NET 오브젝트에서 닫기를 호출 할 때까지 추적을 계속합니다) [이것은 프로세스 종료 시간, 일명 종료 시간 등을 제공 할 수 있도록하기위한 것입니다.])
인용 http://msdn.microsoft.com/en-us/library/fb4aw7b8.aspx :
연관된 프로세스가 종료되면 (즉, 정상 또는 비정상 종료를 통해 운영 체제에 의해 종료 될 때) 시스템은 프로세스에 대한 관리 정보를 저장하고 WaitForExit를 호출 한 구성 요소로 리턴합니다. 그런 다음 프로세스 컴포넌트는 종료 된 프로세스에 대한 핸들을 사용하여 ExitTime을 포함한 정보에 액세스 할 수 있습니다.
연관된 프로세스가 종료되었으므로 구성 요소의 Handle 특성이 더 이상 기존 프로세스 자원을 가리 키지 않습니다. 대신 핸들은 프로세스 자원에 대한 운영 체제 정보에 액세스하는 데만 사용할 수 있습니다. 시스템은 프로세스 구성 요소가 해제하지 않은 종료 된 프로세스에 대한 핸들을 인식하므로 프로세스 구성 요소가 자원을 구체적으로 해제 할 때까지 ExitTime 및 핸들 정보를 메모리에 유지합니다. 이러한 이유로 프로세스 인스턴스에 대해 Start를 호출 할 때마다 연관된 프로세스가 종료되고 더 이상 관리 정보가 필요하지 않으면 Close를 호출하십시오. Close는 종료 된 프로세스에 할당 된 메모리를 해제합니다.
Coincoin의 해결책을 시도했습니다 :
일부 파일을 처리하기 전에 파일을 임시 파일로 복사하여 엽니 다.
완료되면 응용 프로그램이 여전히 열려 있으면 응용 프로그램을 닫고 임시 파일을 삭제합니다.
Process 변수를 사용하고 나중에 확인하십시오.
private Process openApplication;
private void btnOpenFile_Click(object sender, EventArgs e) {
...
// copy current file to fileCache
...
// open fileCache with proper application
openApplication = System.Diagnostics.Process.Start( fileCache );
}
나중에 응용 프로그램을 닫습니다.
...
openApplication.Refresh();
// close application if it is still open
if ( !openApplication.HasExited() ) {
openApplication.Kill();
}
// delete temporary file
System.IO.File.Delete( fileCache );
그것은 (지금까지) 작동합니다
openApplication.HasExited()
HasExited는 함수가 아닙니다. 올바른 방법은입니다 openApplication.HasExited
.
프로세스 ID로 기존 프로세스를 확인하는 것과 관련하여 .Net 프레임 워크에서 지원되는 API에도 불구하고 이러한 기능은 매우 느립니다. Process.GetProcesses () 또는 Process.GetProcessById / Name ()을 실행하는 데 많은 CPU주기가 필요합니다.
ID로 실행중인 프로세스를 확인하는 훨씬 빠른 방법은 기본 API OpenProcess ()를 사용하는 것 입니다. 리턴 핸들이 0이면 프로세스가 존재하지 않습니다. 핸들이 0과 다른 경우 프로세스가 실행 중입니다. 허가로 인해이 방법이 항상 100 % 작동한다는 보장은 없습니다.
다른 것들이 부분적으로 다루는 것처럼, 이것과 관련된 많은 문제가 있습니다 :
다른 사람이 언급 한 속성이 내부에 있는지 여부에 관계없이 권한이 허용하는 경우 리플렉션을 통해 정보를 얻을 수 있습니다.
var x = obj.GetType().GetProperty("Name", BindingFlags.NonPublic | BindingFlags.Instance);
Snapshot에 대해 Win32 코드를 고정 하거나 속도가 느린 WMI 를 사용할 수 있습니다 .
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
또 다른 옵션은 OpenProcess입니다. / CloseProcess이지만, 이전과 동일하게 예외가 발생하는 것과 동일한 문제가 계속 발생합니다.
WMI-OnNewEvent.Properties [ "?"]의 경우 :
string process = "notepad";
if (Process.GetProcessesByName(process).Length == 0)
{
MessageBox.Show("Working");
}
else
{
MessageBox.Show("Not Working");
}
또한 매번 프로세스를 확인하기 위해 타이머를 사용할 수 있습니다
length == 0
표시되어야 함 Not Working
) 여전히 작업을 수행합니다.