开发者

Check if a specific exe file is running

I want to know how i can che开发者_开发问答ck a program in a specific location if it is running. For example there are two locations for test.exe in c:\loc1\test.exe and c:\loc2\test.exe. I only wanted to know if c:\loc1\test.exe is running and not all instances of test.exe.


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


This is my improved function :

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

and use it as :

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


try this... I use it to determine at startup if another process is already running with the same name as the exe I'm trying to start, and then just bring that one to foreground, (and to focus) if it is already running... You could modify it to take a process name and test for that specific name... This will tell you if there is a process running with a certain name, but not where that process was loaded from ...

If there is a process running with the specified name, then if that process had an exposed accessible method that returns where it was loaded from, you could call that method on the running process, otherwise, I don't know..

But just out of curiosity, why do you care, unless they're different? And if they're different in some way, code to use that difference (whatever it is) to detect which is loaded. But if they're the same how can it matter which on-disk image was used to load it?

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


You should iterate over all existing processes and then check their MainModule property for the file name you are looking for. Something like this

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


This function may help:

using System.Diagnostics;

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

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


Something like this. GetMainModuleFileName helps to access x64 process from 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) {

    var processes = Process.GetProcessesByName(processName);

    foreach(var process in processes) {

        var name = GetMainModuleFileName(process);
        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;
}


You could use a named mutex, that's named off of the directory structure the program is running in.


System.Reflection.Assembly.GetEntryAssembly()

This will bring for you a lot of info about the entry assembly, such as:

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

This will tell the location of the running assembly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜