Проверьте, работает ли определенный exe-файл - PullRequest
33 голосов
/ 16 ноября 2009

Я хочу знать, как я могу проверить программу в определенном месте, если она запущена. Например, есть два места для test.exe: c: \ loc1 \ test.exe и c: \ loc2 \ test.exe. Я только хотел узнать, запущен ли c: \ loc1 \ test.exe и не все ли экземпляры test.exe.

Ответы [ 8 ]

52 голосов
/ 16 ноября 2009
bool isRunning = Process.GetProcessesByName("test")
                .FirstOrDefault(p => p.MainModule.FileName.StartsWith(@"c:\loc1")) != default(Process);
6 голосов
/ 20 декабря 2015

Это моя улучшенная функция:

private bool ProgramIsRunning(string FullPath)
{
    string FilePath =  Path.GetDirectoryName(FullPath);
    string FileName = Path.GetFileNameWithoutExtension(FullPath).ToLower();
    bool isRunning = false;

    Process[] pList = Process.GetProcessesByName(FileName);

    foreach (Process p in pList) {
        if (p.MainModule.FileName.StartsWith(FilePath, StringComparison.InvariantCultureIgnoreCase))
        {
            isRunning = true;
            break;
        }
    }

    return isRunning;
}

и используйте его как:

ProgramIsRunning(@"c:\loc1\test.exe");
5 голосов
/ 16 ноября 2009

попробуйте это ... Я использую его, чтобы определить при запуске, запущен ли уже другой процесс с тем же именем, что и исполняемый файл, который я пытаюсь запустить, а затем просто перенести его на передний план (и сфокусировать), если он уже запущен ... Вы можете изменить его так, чтобы он брал имя процесса и проверял его на конкретное имя ... Это сообщит вам, если есть процесс, запущенный с определенным именем, но не из того места, откуда этот процесс был загружен. .

Если есть процесс, запущенный с указанным именем, то если у этого процесса есть открытый доступный метод, который возвращает, откуда он был загружен, вы можете вызвать этот метод в запущенном процессе, в противном случае, я не знаю ..

Но просто из любопытства, почему тебя это волнует, если они не разные? И если они каким-то образом отличаются, используйте код, чтобы использовать эту разницу (какой бы она ни была), чтобы определить, какая из них загружена. Но если они одинаковы, как может иметь значение, какой образ диска использовался для его загрузки?

    [DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
    [DllImport("user32.dll")]
    private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll")]
    private static extern bool IsIconic(IntPtr hWnd);

    private const int SW_HIDE = 0;
    private const int SW_SHOWNORMAL = 1;
    private const int SW_SHOWMINIMIZED = 2;
    private const int SW_SHOWMAXIMIZED = 3;
    private const int SW_SHOWNOACTIVATE = 4;
    private const int SW_RESTORE = 9;
    private const int SW_SHOWDEFAULT = 10;

 private static bool IsAlreadyRunning()
    {
        // get all processes by Current Process name
        Process[] processes = 
            Process.GetProcessesByName(
                Process.GetCurrentProcess().ProcessName);

        // if there is more than one process...
        if (processes.Length > 1) 
        {
            // if other process id is OUR process ID...
            // then the other process is at index 1
            // otherwise other process is at index 0
            int n = (processes[0].Id == Process.GetCurrentProcess().Id) ? 1 : 0;

            // get the window handle
            IntPtr hWnd = processes[n].MainWindowHandle;

            // if iconic, we need to restore the window
            if (IsIconic(hWnd)) ShowWindowAsync(hWnd, SW_RESTORE);

            // Bring it to the foreground
            SetForegroundWindow(hWnd);
            return true;
        }
        return false;
    }
4 голосов
/ 16 ноября 2009

Вы должны выполнить итерацию по всем существующим процессам, а затем проверить их свойство MainModule для имени файла, который вы ищете. Как то так

using System.Diagnostics;
using System.IO;

//...

string fileNameToFilter = Path.GetFullPath("c:\\loc1\\test.exe");

foreach (Process p in Process.GetProcesses())
{
   string fileName = Path.GetFullPath(p.MainModule.FileName);

   //cehck for equality (case insensitive)
   if (string.Compare(fileNameToFilter, fileName, true) == 0)
   {
      //matching...
   }
}
3 голосов
/ 16 ноября 2009

Эта функция может помочь:

using System.Diagnostics;

public bool IsProcessOpen(string name)
{
    foreach (Process clsProcess in Process.GetProcesses()) {
        if (clsProcess.ProcessName.Contains(name))
        {
            return true;
        }
    }
    return false;
} 

Источник: http://www.dreamincode.net/code/snippet1541.htm

0 голосов
/ 30 августа 2018

Как то так. GetMainModuleFileName помогает получить доступ к процессу x64 из x86.

  [DllImport("kernel32.dll")]
  public static extern bool QueryFullProcessImageName(IntPtr hprocess, int dwFlags, StringBuilder lpExeName, out int size);

  private bool CheckRunningProcess(string processName, string path) {

  Process[] processes = Process.GetProcessesByName(processName);
  foreach(Process p in processes) {
    var name = GetMainModuleFileName(p);
    if (name == null)
      continue;
    if (string.Equals(name, path, StringComparison.InvariantCultureIgnoreCase)) {
      return true;
    }
  }
  return false;
}

// Get x64 process module name from x86 process
private static string GetMainModuleFileName(Process process, int buffer = 1024) {

  var fileNameBuilder = new StringBuilder(buffer);
  int bufferLength = fileNameBuilder.Capacity + 1;
  return QueryFullProcessImageName(process.Handle, 0, fileNameBuilder, out bufferLength) ?
      fileNameBuilder.ToString() :
      null;
}
0 голосов
/ 16 ноября 2009

Вы можете использовать с именем mutex , который назван вне структуры каталогов, в которой работает программа.

0 голосов
/ 16 ноября 2009
System.Reflection.Assembly.GetEntryAssembly()

Это принесет вам много информации о сборке записи, например:

System.Reflection.Assembly.GetEntryAssembly().CodeBase;

Это скажет местоположение работающей сборки.

...