Я хочу знать, как я могу проверить программу в определенном месте, если она запущена. Например, существует два места для файла test.exe: c:\loc1\test.exe и c:\loc2\test.exe. Я только хотел знать, запущен ли c:\loc1\test.exe, а не все экземпляры test.exe.
Проверьте, запущен ли конкретный exe-файл
Ответы (8)
Это моя улучшенная функция:
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");
System.ComponentModel.Win32Exception: 'Access is denied.'
- person DxTx; 30.05.2020
попробуйте это... Я использую его, чтобы определить при запуске, запущен ли уже другой процесс с тем же именем, что и исполняемый файл, который я пытаюсь запустить, а затем просто выведите его на передний план (и сфокусируйте), если он уже работает... Вы можете изменить его, чтобы взять имя процесса и проверить это конкретное имя... Это скажет вам, есть ли процесс, работающий с определенным именем, но не откуда этот процесс был загружен...
Если есть процесс, работающий с указанным именем, то, если у этого процесса есть открытый доступный метод, который возвращает место, откуда он был загружен, вы можете вызвать этот метод в запущенном процессе, иначе я не знаю.
Но просто из любопытства, какое тебе дело, если они не разные? И если они каким-то образом отличаются, используйте код для использования этой разницы (какой бы она ни была) для определения того, что загружено. Но если они одинаковые, какая разница, какой образ на диске использовался для его загрузки?
[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;
}
Вы должны перебрать все существующие процессы, а затем проверить их свойство 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...
}
}
A 32 bit processes cannot acess modules of a 64 bit process
и в итоге использовал решение из http://stackoverflow.com/questions/5497064/c-how-to-get-the-full-path-of-running-процесс/5497319#5497319.
- person Adrian C.; 07.10.2016
Эта функция может помочь:
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
Что-то вроде этого. 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;
}
Вы можете использовать именованный мьютекс, который называется вне структуры каталогов, в которой работает программа.
System.Reflection.Assembly.GetEntryAssembly()
Это принесет вам много информации о входной сборке, например:
System.Reflection.Assembly.GetEntryAssembly().CodeBase;
Это подскажет расположение ходовой сборки.
..StartsWith(new FileInfo(Application.ExecutablePath).DirectoryName)
, это не сработает. Это связано с тем, что DirectoryName возвращает путь с буквой диска в нижнем регистре, например c:. Таким образом, рекомендуется изменить его как ..FileName.ToLower()
и ..StartsWith(@path.ToLower())
.
- person Robin Rye; 10.07.2012
.StartsWith(path, StringComparison.InvariantCultureIgnoreCase)
), так как оно не требует изменения строк.
- person Ben; 08.05.2013