C#을 사용하여 프로세스가 이미 실행 중인지 어떻게 알 수 있나요?

StackOverflow https://stackoverflow.com/questions/51148

  •  09-06-2019
  •  | 
  •  

문제

때때로 외부 exe를 시작해야 하는 C# winforms 응용 프로그램이 있지만 이미 실행 중인 경우 다른 프로세스를 시작하지 않고 해당 프로세스로 전환하고 싶습니다.

그렇다면 C#에서는 아래 예에서 어떻게 이를 수행할 수 있습니까?

using System.Diagnostics;

...

Process foo = new Process();

foo.StartInfo.FileName = @"C:\bar\foo.exe";
foo.StartInfo.Arguments = "Username Password";

bool isRunning = //TODO: Check to see if process foo.exe is already running


if (isRunning)
{
   //TODO: Switch to foo.exe process
}
else
{
   foo.Start(); 
}
도움이 되었습니까?

해결책

이렇게 하면 됩니다.

프로세스 확인

//Namespaces we need to use
using System.Diagnostics;

public bool IsProcessOpen(string name)
{
    //here we're going to get a list of all running processes on
    //the computer
    foreach (Process clsProcess in Process.GetProcesses()) {
        //now we're going to see if any of the running processes
        //match the currently running processes. Be sure to not
        //add the .exe to the name you provide, i.e: NOTEPAD,
        //not NOTEPAD.EXE or false is always returned even if
        //notepad is running.
        //Remember, if you have the process running more than once, 
        //say IE open 4 times the loop thr way it is now will close all 4,
        //if you want it to just close the first one it finds
        //then add a return; after the Kill
        if (clsProcess.ProcessName.Contains(name))
        {
            //if the process is found to be running then we
            //return a true
            return true;
        }
    }
    //otherwise we return a false
    return false;
}


다른 팁

LINQ도 사용할 수 있습니다.

var processExists = Process.GetProcesses().Any(p => p.ProcessName.Contains("<your process name>"));

VB 런타임에서 AppActivate 기능을 사용하여 기존 프로세스를 활성화했습니다.Microsoft.VisualBasic dll을 C# 프로젝트로 가져와야 합니다.

using System;
using System.Diagnostics;
using Microsoft.VisualBasic;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            Process[] proc = Process.GetProcessesByName("notepad");
            Interaction.AppActivate(proc[0].MainWindowTitle);
        }
    }
}

다음을 사용하여 간단히 프로세스를 열거할 수 있습니다. 프로세스.Get프로세스 방법.

Mutex가 콘솔 애플리케이션처럼 작동하지 않는다는 것을 알았습니다.따라서 WMI를 사용하여 작업 관리자 창을 통해 볼 수 있는 프로세스를 쿼리하면 문제가 해결됩니다.

다음과 같이 사용하십시오.

static bool isStillRunning() {
   string processName = Process.GetCurrentProcess().MainModule.ModuleName;
   ManagementObjectSearcher mos = new ManagementObjectSearcher();
   mos.Query.QueryString = @"SELECT * FROM Win32_Process WHERE Name = '" + processName + @"'";
   if (mos.Get().Count > 1)
   {
        return true;
    }
    else
        return false;
}

메모:Intellisense 유형을 활성화하려면 어셈블리 참조 "System.Management"를 추가하세요.

귀하의 문제에 대한 완전한 답을 얻으려면 응용 프로그램에서 foo.exe 인스턴스가 이미 실행 중이라고 판단할 때 어떤 일이 발생하는지, 즉 '//TODO:'가 수행되는 작업을 이해해야 한다고 생각합니다.foo.exe 프로세스로 전환'이 실제로 의미하는 것은 무엇입니까?

이전 프로젝트에서는 프로세스의 다중 실행을 방지해야 했기 때문에 해당 프로세스의 init 섹션에 명명된 뮤텍스를 생성하는 일부 코드를 추가했습니다.이 뮤텍스트는 나머지 프로세스를 계속하기 전에 생성 및 획득되었습니다.프로세스가 뮤텍스를 생성하고 획득할 수 있으면 해당 프로세스가 가장 먼저 실행됩니다.다른 프로세스가 이미 뮤텍스를 제어하는 ​​경우 실패한 프로세스는 첫 번째 프로세스가 아니므로 즉시 종료됩니다.

특정 하드웨어 인터페이스에 대한 종속성으로 인해 두 번째 인스턴스가 실행되는 것을 방지하려고 했습니다.해당 "전환" 줄에 필요한 사항에 따라 프로세스 ID 또는 핸들과 같은 보다 구체적인 솔루션이 필요할 수 있습니다.

또한 시작하려는 프로세스에 대한 소스 코드 액세스 권한도 있었습니다.코드를 수정할 수 없다면 뮤텍스를 추가하는 것은 분명히 선택 사항이 아닙니다.

명심해야 할 두 가지 사항:

  1. 예제에는 명령 줄에 암호를 배치하는 것이 포함되었습니다.비밀의 명확한 텍스트 표현은 보안 취약성 일 수 있습니다.

  2. 프로세스를 열거 할 때, 당신이 실제로 열거하고 싶은 프로세스를 스스로에게 물어보십시오.모든 사용자 또는 현재 사용자?현재 사용자가 두 번 (두 개의 데스크탑) 로그인하면 어떻게됩니까?

Mnebuerquo는 다음과 같이 썼습니다.

또한 시작하려는 프로세스에 소스 코드에 액세스 할 수있었습니다.코드를 수정할 수없는 경우 뮤텍스를 추가하는 것은 분명히 옵션이 아닙니다.

실행하려는 프로세스에 대한 소스 코드 액세스 권한이 없습니다.

이미 실행 중임을 확인한 후 프로세스로 전환하기 위해 MainWindowHandle 프로세스를 사용했습니다.

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 public static extern bool SetForegroundWindow(IntPtr hWnd);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top