DUDA Ruta archivos en ejecución[SOLUCIONADO]

Iniciado por Yaldabaot, 5 Febrero 2014, 18:20 PM

0 Miembros y 1 Visitante están viendo este tema.

Yaldabaot

Buenas,

He estado buscando en internet y lo que encuentro no me sustenta mucho, ¿alguno de ustedes sabe como obtener la ruta de un archivo en ejecución, pero que NO esté dentro del mismo folder que viene el debug del visual studio y que no sea la misma aplicación del programa que uno está creando?.

En pocas palabras, necesito obtener la ruta de un archivo que se está ejecutando, pero que no sea la misma aplicación que uno está programando, es en C#.

He estado utilizando
este código

Código (csharp) [Seleccionar]


string logsDirectory = Path.Combine(Environment.CurrentDirectory, trozo2);



Pero lo que obtengo es la ruta donde está proyecto y es lo que NO necesito.

Nunca me contestan -_-

Eleкtro

#1
Cita de: Yaldabaot en  5 Febrero 2014, 18:20 PMnecesito obtener la ruta de un archivo que se está ejecutando

Supongo que por "un archivo que se está ejecutando" te referirás a un proceso en ejecución, de lo contrario explíca mejor.


Te hice un ejemplo (en VB.NET) usando LINQ.

PD:  La razón de porque devuelvo un Array es porque puede haber varias instancias abiertas de un programa multi-instancia con el mismo nombre pero desde distintos directorios (Ej: C:\Proceso.exe, C:\Carpeta\Proceso.exe )

Código (vbnet) [Seleccionar]
Public Class Form1

   Private Shadows Sub Load() Handles MyBase.Load

       Dim ProcessPaths As String() = GetProcessPath("svchost.exe")

       For Each Path As String In ProcessPaths
           MsgBox(Path )
       Next

   End Sub

   ' Get Process Path
   ' ( By Elektro )
   '
   ' Usage Examples:
   ' MsgBox(GetProcessPath("notepad.exe").First)
   '
   ''' <summary>
   ''' Gets the absolute path of a running process.
   ''' </summary>
   ''' <param name="ProcessName">Indicates the name of the process.</param>
   ''' <returns>System.String[][].</returns>
   Public Function GetProcessPath(ByVal ProcessName As String) As String()

       If ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) Then
           ProcessName = ProcessName.Remove(ProcessName.Length - 4)
       End If

       Return (From p As Process In Process.GetProcesses
               Where p.ProcessName.Equals(ProcessName, StringComparison.OrdinalIgnoreCase)
               Select p.MainModule.FileName).ToArray

   End Function

End Class


Conversión instantanea a C#:

Código (csharp) [Seleccionar]

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Form1
{


private new void Load()
{
string[] Processes = GetProcessPath("svchost.exe");

foreach (string path in Processes) {
Interaction.MsgBox(path);
}

}

// Get Process Path
// ( By Elektro )
//
// Usage Examples:
// MsgBox(GetProcessPath("notepad.exe").First)
//
/// <summary>
/// Gets the absolute path of a running process.
/// </summary>
/// <param name="ProcessName">Indicates the name of the process.</param>
/// <returns>System.String[][].</returns>
public string[] GetProcessPath(string ProcessName)
{

if (ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) {
ProcessName = ProcessName.Remove(ProcessName.Length - 4);
}

return (from p in Diagnostics.Process.GetProcesseswhere p.ProcessName.Equals(ProcessName, StringComparison.OrdinalIgnoreCase)p.MainModule.FileName).ToArray;

}
public Form1()
{
Load += Load;
}

}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: @telerik
//Facebook: facebook.com/telerik
//=======================================================


Saludos








Yaldabaot

Voy a implementarlo y comentarte como me va, MUCHAS GRACIAS.
Nunca me contestan -_-

Yaldabaot

#3
Disculpa Elektro, no he podido implementarlo, me da una serie de errores.

Código (csharp) [Seleccionar]


return (from p in Diagnostics.Process.GetProcesseswhere p.ProcessName.Equals(ProcessName, StringComparison.OrdinalIgnoreCase)p.MainModule.FileName).ToArray;



Y estos son los using que he estado usando

Código (csharp) [Seleccionar]



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Printing;
using System.Configuration;
using System.Collections;
using System.Collections.Specialized;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Diagnostics;
using Microsoft.VisualBasic;



Errores tales como que no reconoce p, tambien con puntos y comas, no se si no estare poniendo alguna referencia.

Nunca me contestan -_-

Yaldabaot

Ya lo arreglé, muchas gracias por tu tiempo y paciencia Elektro.

Código (csharp) [Seleccionar]


public string[] GetProcessPath(string ProcessName)
        {

            if (ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
            {
                ProcessName = ProcessName.Remove(ProcessName.Length - 4);
            }
           

            return (from p in System.Diagnostics.Process.GetProcesses() where p.ProcessName.Equals(ProcessName, StringComparison.OrdinalIgnoreCase) select p.MainModule.FileName).ToArray();

            }



Nunca me contestan -_-

Eleкtro

si, parece que el conversor online se comío las clausulas ' Where' y 'Select' xD, no me di cuenta y tampoco testeé el código en C#.

Me alegro de que lo hayas solucionado.

saludos








Yaldabaot

Elektro, ¿ Hay alguna forma de hacerlo pero con un archivo abierto y no un proceso?.

Es decir yo tengo por ejemplo un txt sin guardar, ¿ Existe una forma de sacarle la ruta con sólo su nombre, tengo un evento que saca el nombre y me retorna por ejemplo Untitled Notepad, hay alguna forma?

He estado tratando de hacerlo con filewarcher, pero quedo igual porque necesito la ruta.
Nunca me contestan -_-

Eleкtro

Cita de: Yaldabaot en  6 Febrero 2014, 23:52 PMElektro, ¿ Hay alguna forma de hacerlo pero con un archivo abierto y no un proceso?.

No estoy muy seguro así que no puedo asegurar nada, pero dudo que exista una manera eficiente.

Si abres un archivo .TXT con un editor de texto y este editor de texto mantiene ocupado el archivo (en modo de lectura o escritura) segúramente puedas encontrar un Handle que haga referencia a ese archivo, de lo contario...pues no lo creo, ya que el archivo ya se cerró por el programa.

Y si abres un archivo con un programa puedes encontrar la referencia a ese archivo "abierto" usando WMI para buscar los parámetros commandline de los procesos en ejecución, por ejemplo, si Notepad fuese el editor predefinido en tu sistema y haces doble click en un archivo de texto entonces se iniciará el Notepad con estos parámetros:
Notepad.exe "Archivo abierto"
...y usando WMI podrás encontrar los parámetros de ese proceso para encontrar el archivo abierto.
Pero si desde esa mimsa instancia del programa abres otro(s) archivo(s) entonces óbviamente buscar los parámetros de la aplicación no te va a servir de nada porque el programa ya está iniciado y el nuevo archivo lo has abierto desde el programa.

Y si lo que quieres es monitorear la ejecución de un archivo, en tiempo real, pues... lo tienes dificil, un 'FileSystemWatcher' solo te va a informar de los cambios una vez se hayan realizado, no antes, ni mientras. Necesitarías escribir un driver (un 'filesystem filter driver') para capturar todas las operaciones de escritura que necesites, lo cual no es nada facil...

Aunque como ya digo, no estoy muy seguro de si habrá otra forma.
Saludos.








Yaldabaot

Gracias por las sugerencias, se te agradece mucho. O sino voy a buscar otra manera. Saludos.
Nunca me contestan -_-

Eleкtro

#9
Como te dije antes, una forma (la más eficiente) sería listando los handles, encontré la utilidad commandline 'Handle' de SysInternals que te facilitaría la tarea de listar los Handles de los archivos que están abiertos por otros programas http://technet.microsoft.com/en-us/sysinternals/bb896655

Pero, como también dije, esto no va a funcionar con archivos de texto porque no se mantienen en modo lectura/escritura así que reálmente no están abiertos, depende del tipo de editor... (Lo probé con el notepad y el sublime text).

PD: Si te comento el uso de una aplicación de terceros donde lo único que debas hacer es parsear el output es porque de lo contraría deberías desarrollar un driver...

Saludos!