Pergunta

Quero saber como posso verificar um programa em um local específico, se ele estiver em execução. Por exemplo, existem dois locais para test.exe em c: loc1 test.exe e c: loc2 test.exe. Eu só queria saber se C: loc1 test.exe está em execução e nem todas as instâncias do test.exe.

Foi útil?

Solução

bool isRunning = Process.GetProcessesByName("test")
                .FirstOrDefault(p => p.MainModule.FileName.StartsWith(@"c:\loc1")) != default(Process);

Outras dicas

Esta é a minha função aprimorada:

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;
}

e use -o como:

ProgramIsRunning(@"c:\loc1\test.exe");

Tente isso ... eu uso para determinar na inicialização se outro processo já está sendo executado com o mesmo nome que o exe que estou tentando começar e, em seguida, traga esse para o primeiro plano (e focar) se já estiver Correndo ... você pode modificá -lo para obter um nome de processo e testar esse nome específico ... Isso dirá se há um processo em execução com um determinado nome, mas não de onde esse processo foi carregado de ...

Se houver um processo em execução com o nome especificado, se esse processo tivesse um método acessível exposto que retorne de onde foi carregado, você poderá chamar esse método no processo de execução; caso contrário, não sei ..

Mas por curiosidade, por que você se importa, a menos que sejam diferentes? E se eles forem diferentes de alguma forma, o código para usar essa diferença (seja qual for) para detectar o que é carregado. Mas se eles são iguais, como pode importar qual imagem no disco foi usada para carregá-la?

    [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;
    }

Você deve iterar em todos os processos existentes e verificar sua propriedade MainModule para obter o nome do arquivo que está procurando. Algo assim

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...
   }
}

Esta função pode ajudar:

using System.Diagnostics;

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

Fonte: http://www.dreamincode.net/code/snippet1541.htm

Algo assim. GetMainModuleFileName ajuda a acessar o processo X64 a partir de 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;
}

Você poderia usar um nomeado mutex, isso é nomeado da estrutura do diretório em que o programa está sendo executado.

System.Reflection.Assembly.GetEntryAssembly()

Isso trará muitas informações sobre a montagem de entrada, como:

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

Isso dirá o local da montagem em execução.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top