elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  System.Diagnostics.Process y Office 2010
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: System.Diagnostics.Process y Office 2010  (Leído 7,313 veces)
YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
System.Diagnostics.Process y Office 2010
« en: 2 Noviembre 2012, 13:22 pm »

Hola a todos.
Tengo un problema al lanzar un proceso con System.Diagnostics.Process.Start cuando la aplicación que se lanza es una de Office 2010.
Mi aplicación necesita esperar a que la aplicación que se lanza termine (no sé qué aplicación se lanzará, se usará la configurada en el SO para la extensión) y cuando se lanza un documento de Office, si no hay ninguna instancia de esa misma aplicación abierta (Word, Excel, etc.), no hay problema, pero en el caso de que ya haya abierto cualquier otro documento, el método Start no me devuelve la referencia al proceso creado para que pueda esperar a que se termine.
El código que uso es, más o menos, el siguiente (lo he simplificado para que sólo esté la parte que lanza el proceso).
Código:
Sub startDoc(doc as String)
   Dim app As New Process
   Try
      app = System.Diagnostics.Process.Start(doc)
   Catch ex As Exception
   End Try
   If Not app Is Nothing Then
      app.WaitForExit()
   end If
End Sub


En línea

Keyen Night


Desconectado Desconectado

Mensajes: 496


Nothing


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #1 en: 2 Noviembre 2012, 18:09 pm »

Con Process.Start llama al programa por defecto para la extensión a menos que le indiques otro. No entiendo muy bien el problema, pero también puedes revisar el programa que esta configurado por defecto para la extensión del documento, y buscar el proceso que se haya iniciado con el nombre del documento como parámetro de inicio, ese entonces sera el proceso que quieres esperar.


« Última modificación: 2 Noviembre 2012, 18:19 pm por Keyen Night » En línea

La Fé Mueve Montañas...
                                    ...De Dinero

La programación es más que un trabajo es más que un hobby es una pasión...
YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #2 en: 2 Noviembre 2012, 18:59 pm »

Con Process.Start llama al programa por defecto para la extensión a menos que le indiques otro. No entiendo muy bien el problema, pero también puedes revisar el programa que esta configurado por defecto para la extensión del documento, y buscar el proceso que se haya iniciado con el nombre del documento como parámetro de inicio, ese entonces sera el proceso que quieres esperar.
Te explico:
En mi aplicación mando abrir una hoja de cálculo y se abre correctamente y tengo el control del proceso con lo que me retorna el método start, pero si ahora que ya tengo un excel abierto, abro otro, app es Nothing y pierdo el control de este segundo documento. Esto no sólo me ocurre con Excel, es con cualquier programa de Office 2010.
El problema es que al abrir otro documento, MsOffice al ver que ya tiene abierto un Excel (en este caso) no abre otro recurso y aprovecha el proceso que ya está abierto, provocando que yo no pueda controlar este segundo proceso.
En línea

Novlucker
Ninja y
Colaborador
***
Desconectado Desconectado

Mensajes: 10.683

Yo que tu lo pienso dos veces


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #3 en: 2 Noviembre 2012, 19:44 pm »

Por lo que veo Office abre N archivos en un mismo proceso.


Deberías de listar los handle de todos los procesos para ver cual de ellos es el que tiene el/los archivos que has abierto. Para esto necesitas hacer uso de NtQuerySystemInformation, por lo que implica algo de código no manejado.

Otra alternativa es utilizar handle.exe de Sysinternals para listar esta info, algo de este estilo;

Código
  1. static void Main(string[] args)
  2. {
  3.    ProcessStartInfo info = new ProcessStartInfo();
  4.    info.WindowStyle = ProcessWindowStyle.Hidden;
  5.    info.FileName = @"D:\handle.exe";
  6.    info.Arguments = "xls"; //aquí va la ruta del archivo para la búsqueda
  7.    info.UseShellExecute = false;
  8.    info.RedirectStandardOutput = true;
  9.  
  10.    Process p = new Process() { StartInfo = info };
  11.    p.Start();
  12.  
  13.    List<string> lines = new List<string>();
  14.    while (!p.StandardOutput.EndOfStream)
  15.        lines.Add(p.StandardOutput.ReadLine());
  16.  
  17.    //con la lista puedes hacer lo que quieras, en este caso lo muestro por pantalla
  18.    lines.Skip(5).ToList().ForEach(h => Console.WriteLine(h));
  19.    Console.ReadKey();
  20. }

Saludos



En línea

Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD
"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein
YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #4 en: 6 Noviembre 2012, 17:23 pm »


Otra alternativa es utilizar handle.exe de Sysinternals para listar esta info, algo de este estilo;

Gracias, Novlucker, con el programa handle.exe he solucionado mi problema, después de abrir un documento, lo busco en los procesos y obtengo el id del proceso que lo tiene y a partir de ahí es fácil, creo un Process con ese id y a esperar que termine (WaitForExit).
Sólo he visto una pega y es en la licencia de Sysinternals que creo que dice que no se puede distribuir el programa ni usarlo en otro (todo lo que yo hago).
¿Sabes si es así o estoy equivocado?
Muchas gracias de nuevo por tu ayuda.
En línea

Novlucker
Ninja y
Colaborador
***
Desconectado Desconectado

Mensajes: 10.683

Yo que tu lo pienso dos veces


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #5 en: 6 Noviembre 2012, 17:57 pm »

http://technet.microsoft.com/en-us/sysinternals/bb847944.aspx :¬¬
Tal vez habría que manejar otra alternativa y pasar al código no manejado :-\ .El último code puede ser tu respuesta, no lo he probado pero ... http://stackoverflow.com/questions/860656/how-does-one-figure-out-what-process-locked-a-file-using-c

Saludos
En línea

Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD
"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein
YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #6 en: 6 Noviembre 2012, 18:01 pm »

Voy a ello. En cuanto tenga algún resultado lo posteo aquí.
Muchas gracias.
En línea

YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #7 en: 7 Noviembre 2012, 11:25 am »

Tal vez habría que manejar otra alternativa y pasar al código no manejado :-\ .El último code puede ser tu respuesta, no lo he probado pero ... http://stackoverflow.com/questions/860656/how-does-one-figure-out-what-process-locked-a-file-using-c
Bueno, vamos a ver.
He cogido el DetectOpenFiles.cs del foro este y he estudiado un poco el namespace y creía que iba a ser más fácil de lo que me está resultando.
En el código hay una clase DetectOpenFiles que tiene un método GetProcessesUsingFile así que en un proyecto de consola con el DetectOpenFiles.cs agregado escribí lo siguiente:
Código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Crmc.Core.BuildTasks;

namespace DOF
{
    class Program
    {
        static void Main(string[] args)
        {
            List<System.Diagnostics.Process> p;

            p = DetectOpenFiles.GetProcessesUsingFile("xls");

            p.ToList().ForEach(h => Console.WriteLine(h.Id.ToString()));

            Console.WriteLine("Pulsa una tecla para cerrar.");
            Console.ReadKey();   
        }
    }
}
Lo ejecuto teniendo documentos de Excel(xls) abiertos y no me devuelve nada y, de hecho, en la ventana de inmediato me muestra una excepción del tipo 'System.ObjectDisposedException'. :o
¿Podrías echarme una mano? Yo soy un poco neófito en C# y es muy probable que esté cometiendo algún error de base :-\.
En línea

Novlucker
Ninja y
Colaborador
***
Desconectado Desconectado

Mensajes: 10.683

Yo que tu lo pienso dos veces


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #8 en: 7 Noviembre 2012, 14:41 pm »

Googleando he dado con una mejor solución, que al menos a mi me ha funcionado :D
http://hintdesk.com/c-get-all-files-being-accessed-by-a-process-in-64-bits/

Lista la ruta de todos los archivos para un proceso, luego tu te encargas de filtrar. Al pie del post tienes para descargar la solución con el code :P

Saludos
« Última modificación: 7 Noviembre 2012, 14:47 pm por Novlucker » En línea

Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD
"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein
YoAlarico

Desconectado Desconectado

Mensajes: 6


Ver Perfil
Re: System.Diagnostics.Process y Office 2010
« Respuesta #9 en: 14 Noviembre 2012, 17:55 pm »

Tal vez habría que manejar otra alternativa y pasar al código no manejado :-\ .El último code puede ser tu respuesta, no lo he probado pero ... http://stackoverflow.com/questions/860656/how-does-one-figure-out-what-process-locked-a-file-using-c
Al final, retocando un poco este código he conseguido obtener el proceso que abre mi documento.
La función que devuelve la enumeración de procesos la he modificado para que no distinga mayúsculas y minúsculas, que ese era mi problema  :xD.
Código:
        public static List<Process> GetProcessesUsingFile(string fName)
        {
            List<Process> result = new List<Process>();
            foreach (var p in Process.GetProcesses())
            {
                try
                {
                    foreach (var file in DetectOpenFiles.GetOpenFilesEnumerator(p.Id))
                    {
                        if (file.ToUpper().Contains(fName.ToUpper()))
                            result.Add(p);
                        {
                        }
                    }
                    //if (DetectOpenFiles.GetOpenFilesEnumerator(p.Id).Contains(fName))
                    //{
                    //    result.Add(p);
                    //}
                }
                catch { }//some processes will fail
            }
            return result;
        }
Y además me he creado otra que devuelve la id del primer proceso (en mi caso sólo habrá un proceso con mi documento, o eso espero  :silbar:)
Código:
        public static int GetProcessIdUsingFile(string fName)
        {
            int result = 0;
            foreach (var p in GetProcessesUsingFile(fName))
            {
                if (p.Id != 0)
                {
                    result = p.Id;
                    break;
                   
                }
            }
            return result;
        }
Y a partir de ahí ya esta todo controlado, se crea el System.Diagnostics.Process con la id y a esperar que termine.  ;-)
Muchas gracias por tu ayuda, Novlucker, eres un fenómeno.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
OFFICE 2007 VS OFFICE 2010 « 1 2 3 »
Software
horacio_56 21 11,944 Último mensaje 9 Octubre 2010, 13:20 pm
por J-Hide
La adopción de Office 2010 está siendo 5 veces más rápida que la de Office 2007
Noticias
wolfbcn 1 3,378 Último mensaje 16 Junio 2011, 14:05 pm
por awesome13
Problema permisos con System.Diagnostics.Process
.NET (C#, VB.NET, ASP)
jonRM 2 3,337 Último mensaje 12 Marzo 2012, 20:38 pm
por BlackZeroX
The Memory Process File System - MemProcFS
Seguridad
r32 0 2,097 Último mensaje 8 Diciembre 2020, 07:50 am
por r32
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines