다른 응용 프로그램의 일부 설정을 변경하는 응용 프로그램이 있습니다 (두 번 클릭하여 실행되는 간단한 C # 응용 프로그램 (설정 필요 없음)).
설정을 변경 한 후 변경된 설정을 반영하도록 다른 응용 프로그램을 다시 시작해야합니다.
그러려면 실행중인 프로세스를 종료하고 프로세스를 다시 시작해야하지만 문제는 종료 후 프로세스를 찾을 수 없다는 것입니다. (이유는 시스템이 exe 파일이 어디에 있는지 모릅니다 ..)
실행중인 경우 실행중인 프로세스 또는 exe의 경로를 찾을 수있는 방법이 있습니까?
수동으로 경로를 지정하고 싶지 않습니다. 즉 실행중인 경우 경로를 가져오고 프로세스를 종료 한 다음 다시 시작합니다. 그렇지 않으면 나중에 처리합니다.
답변
using System.Diagnostics;
var process = Process.GetCurrentProcess(); // Or whatever method you are using
string fullPath = process.MainModule.FileName;
//fullPath has the path to exe.
이 API에는 한 가지 문제가 있습니다. 32 비트 애플리케이션에서이 코드를 실행하는 경우 64 비트 애플리케이션 경로에 액세스 할 수 없으므로 64 비트 애플리케이션으로 앱을 컴파일하고 실행해야합니다 ( 프로젝트 속성 → 빌드 → 플랫폼 대상 → x64).
답변
할 수있는 일은 WMI를 사용하여 경로를 가져 오는 것입니다. 이렇게하면 32 비트 또는 64 비트 응용 프로그램에 관계없이 경로를 얻을 수 있습니다. 다음은이를 얻을 수있는 방법을 보여주는 예입니다.
// include the namespace
using System.Management;
var wmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process";
using (var searcher = new ManagementObjectSearcher(wmiQueryString))
using (var results = searcher.Get())
{
var query = from p in Process.GetProcesses()
join mo in results.Cast<ManagementObject>()
on p.Id equals (int)(uint)mo["ProcessId"]
select new
{
Process = p,
Path = (string)mo["ExecutablePath"],
CommandLine = (string)mo["CommandLine"],
};
foreach (var item in query)
{
// Do what you want with the Process, Path, and CommandLine
}
}
System.Management.dll
어셈블리 를 참조 하고 System.Management
네임 스페이스를 사용해야합니다 .
프로그램을 시작하는 데 사용되는 명령 줄 ( CommandLine
) 과 같이 이러한 프로세스에서 얻을 수있는 다른 정보에 대한 자세한 내용은 Win32_Process 클래스 및 WMI .NET 을 참조하십시오.
답변
실행중인 프로세스의 프로세스 개체 (예 : GetProcessesByName ())가 이미있는 것 같습니다. 그런 다음 다음을 사용하여 실행 파일 이름을 가져올 수 있습니다.
Process p;
string filename = p.MainModule.FileName;
답변
다음을위한 솔루션 :
- 32 비트 및 64 비트 프로세스 모두
- System.Diagnostics 만 (System.Management 없음)
Russell Gantman 의 솔루션을 사용하고 다음과 같이 사용할 수있는 확장 방법으로 다시 작성했습니다.
var process = Process.GetProcessesByName("explorer").First();
string path = process.GetMainModuleFileName();
// C:\Windows\explorer.exe
이 구현으로 :
internal static class Extensions {
[DllImport("Kernel32.dll")]
private static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] uint dwFlags, [Out] StringBuilder lpExeName, [In, Out] ref uint lpdwSize);
public static string GetMainModuleFileName(this Process process, int buffer = 1024) {
var fileNameBuilder = new StringBuilder(buffer);
uint bufferLength = (uint)fileNameBuilder.Capacity + 1;
return QueryFullProcessImageName(process.Handle, 0, fileNameBuilder, ref bufferLength) ?
fileNameBuilder.ToString() :
null;
}
}
답변
Sanjeevakumar Hiremath와 Jeff Mercado의 답변을 결합하여 32 비트 프로세스의 64 비트 프로세스에서 아이콘을 검색 할 때 실제로 문제를 해결할 수 있습니다.
using System;
using System.Management;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int processID = 6680; // Change for the process you would like to use
Process process = Process.GetProcessById(processID);
string path = ProcessExecutablePath(process);
}
static private string ProcessExecutablePath(Process process)
{
try
{
return process.MainModule.FileName;
}
catch
{
string query = "SELECT ExecutablePath, ProcessID FROM Win32_Process";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
foreach (ManagementObject item in searcher.Get())
{
object id = item["ProcessID"];
object path = item["ExecutablePath"];
if (path != null && id.ToString() == process.Id.ToString())
{
return path.ToString();
}
}
}
return "";
}
}
}
이것은 약간 느릴 수 있으며 “유효한”아이콘이없는 모든 프로세스에서 작동하지 않습니다.
답변
다음은 32 비트 및 64 비트 애플리케이션 모두에서 작동하는 신뢰할 수있는 솔루션입니다 .
다음 참조를 추가하십시오.
System.Diagnostics 사용;
System.Management 사용;
이 방법을 프로젝트에 추가하십시오.
public static string GetProcessPath(int processId)
{
string MethodResult = "";
try
{
string Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId;
using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query))
{
using (ManagementObjectCollection moc = mos.Get())
{
string ExecutablePath = (from mo in moc.Cast<ManagementObject>() select mo["ExecutablePath"]).First().ToString();
MethodResult = ExecutablePath;
}
}
}
catch //(Exception ex)
{
//ex.HandleException();
}
return MethodResult;
}
이제 다음과 같이 사용하십시오.
int RootProcessId = Process.GetCurrentProcess().Id;
GetProcessPath(RootProcessId);
프로세스의 ID를 알고있는 경우이 메서드는 해당 ExecutePath를 반환합니다.
추가 사항 :
Process.GetProcesses()
… 현재 실행중인 모든 프로세스의 배열을 제공합니다.
Process.GetCurrentProcess()
… 현재 프로세스, 정보 (예 : Id 등) 및 제한된 제어 (예 : Kill 등)를 제공합니다. *
답변
pInvoke 및 다음과 같은 기본 호출을 사용할 수 있습니다. 이것은 32/64 비트 제한이없는 것 같습니다 (적어도 내 테스트에서는)
다음은 코드입니다.
using System.Runtime.InteropServices;
[DllImport("Kernel32.dll")]
static extern uint QueryFullProcessImageName(IntPtr hProcess, uint flags, StringBuilder text, out uint size);
//Get the path to a process
//proc = the process desired
private string GetPathToApp (Process proc)
{
string pathToExe = string.Empty;
if (null != proc)
{
uint nChars = 256;
StringBuilder Buff = new StringBuilder((int)nChars);
uint success = QueryFullProcessImageName(proc.Handle, 0, Buff, out nChars);
if (0 != success)
{
pathToExe = Buff.ToString();
}
else
{
int error = Marshal.GetLastWin32Error();
pathToExe = ("Error = " + error + " when calling GetProcessImageFileName");
}
}
return pathToExe;
}