obtener - ruta absoluta c#
C#: ¿Cómo obtener la ruta completa del proceso en ejecución? (12)
Solución para procesos de 32 bits Y de 64 bits
(con solo System.Diagnostics)
Usé la solución de Russell Gantman y la reescribí como un método de extensión que puede usar así:
var process = Process.GetProcessesByName("explorer").First();
string path = process.GetMainModuleFileName();
// C:/Windows/explorer.exe
Con esta implementación:
internal static class Extensions {
[DllImport("Kernel32.dll")]
private static extern uint 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) != 0 ?
fileNameBuilder.ToString() :
null;
}
}
Tengo una aplicación que está cambiando algunas configuraciones de otra aplicación (es una aplicación C # simple que se ejecuta haciendo doble clic (no se requiere configuración)).
Después de cambiar la configuración, necesito reiniciar la otra aplicación para que refleje la configuración modificada.
Entonces, para hacer, tengo que matar el proceso de ejecución y comenzar el proceso de nuevo, pero el problema es que después de matarlo no puedo encontrar el proceso. (La razón es que el sistema no sabe dónde está el archivo exe ...)
¿Hay alguna forma de averiguar la ruta del proceso o exe en ejecución, si se está ejecutando?
No quiero dar la ruta de forma manual, es decir, si se está ejecutando, obtenga la ruta, elimine el proceso y vuelva a comenzar otra cosa ... Me ocuparé más adelante
Al combinar las respuestas de Sanjeevakumar Hiremath y Jeff Mercado, puede solucionar el problema al recuperar el icono de un proceso de 64 bits en un proceso de 32 bits.
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 "";
}
}
}
Esto puede ser un poco lento y no funciona en todos los procesos que carecen de un icono "válido".
Aquí hay una solución confiable que funciona con aplicaciones de 32 bits y 64 bits .
Agrega estas referencias:
usando System.Diagnostics;
usando System.Management;
Agregue este método a su proyecto:
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;
}
Ahora úsalo así:
int RootProcessId = Process.GetCurrentProcess().Id;
GetProcessPath(RootProcessId);
Tenga en cuenta que si conoce la identificación del proceso, este método devolverá el ExecutePath correspondiente.
Extra, para aquellos interesados:
Process.GetProcesses()
... le dará una selección de todos los procesos actualmente en ejecución, y ...
Process.GetCurrentProcess()
... le dará el proceso actual, junto con su información, por ejemplo, Id, etc. y también control limitado, por ejemplo, matar, etc. *
La clase Process
tiene un miembro StartInfo
que debes verificar:
Llegué a este hilo mientras buscaba el directorio actual de un proceso de ejecución. En .net 1.1, Microsoft presentó:
Directory.GetCurrentDirectory();
Parece que funciona bien (pero no devuelve el nombre del proceso en sí).
Lo que puedes hacer es usar WMI para obtener las rutas. Esto le permitirá obtener la ruta independientemente de que sea una aplicación de 32 bits o de 64 bits. Aquí hay un ejemplo que demuestra cómo puede obtenerlo:
// 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
}
}
Tenga en cuenta que deberá hacer referencia al ensamblado System.Management.dll
y usar el espacio de nombres System.Management
.
Para obtener más información sobre qué otra información puede obtener de estos procesos, como la línea de comando utilizada para iniciar el programa ( CommandLine
), consulte la clase Win32_Process y WMI .NET para obtener más información.
Puede usar pInvoke y una llamada nativa como la siguiente. Esto no parece tener la limitación de 32/64 bit (al menos en mi prueba)
Aquí está el código
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;
}
Supongo que ya tiene el proceso objeto del proceso en ejecución (por ejemplo, por GetProcessesByName ()). A continuación, puede obtener el nombre del archivo ejecutable mediante el uso de
Process p;
string filename = p.MainModule.FileName;
Tratar:
using System.Diagnostics;
ProcessModuleCollection modules = Process.GetCurrentProcess().Modules;
string processpathfilename;
string processmodulename;
if (modules.Count > 0) {
processpathfilename = modules[0].FileName;
processmodulename= modules[0].ModuleName;
} else {
throw new ExecutionEngineException("Something critical occurred with the running process.");
}
using System.Diagnostics;
var process = Process.GetCurrentProcess(); // Or whatever method you are using
string fullPath = process.MainModule.FileName;
//fullPath has the path to exe.
Hay una pega con esta API, si está ejecutando este código en la aplicación de 32 bits, no podrá acceder a las rutas de las aplicaciones de 64 bits, por lo que tendría que compilar y ejecutar su aplicación como aplicación de 64 bits. (Propiedades del proyecto -> Construir -> Objetivo de la plataforma -> x64)
private void Test_Click(object sender, System.EventArgs e){
string path;
path = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
Console.WriiteLine( path );
}
using System;
using System.Diagnostics;
class Program
{
public static void printAllprocesses()
{
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
try
{
String fileName = process.MainModule.FileName;
String processName = process.ProcessName;
Console.WriteLine("processName : {0}, fileName : {1}", processName, fileName);
}catch(Exception e)
{
/* You will get access denied exception for system processes, We are skiping the system processes here */
}
}
}
static void Main()
{
printAllprocesses();
}
}