• Domingo 22 de Diciembre de 2024, 19:36

Autor Tema:  Re: Como Saber si un fichero esta abierto...  (Leído 6153 veces)

javirues

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« en: Miércoles 26 de Noviembre de 2003, 13:43 »
0
Hola amigos:
  Mi problema es el siguiente: en un momento de la plicacion el usuario podra abrir un fichero y modificarlo o no, pero debo conseguir que la plicacion espere a que el fichero se cierre para continuar, el problema es que no se como ejecurta y que la plicacion este en modo espera, shell no espera a que termione la ejecucion y no se me ocurre como hacerlo, ¿no existe una ejecucion en modo atendido?.
Gracias por adelantado

Brroz

  • Miembro de PLATA
  • *****
  • Mensajes: 1058
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #1 en: Miércoles 26 de Noviembre de 2003, 14:37 »
0
Hola javirues.

Para ejecutar un proceso de forma síncrona, utiliza algo asín:

Private Const STILL_ACTIVE = &H103
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long
Private Declare Function GetExitCodeProcess Lib "kernel32" (ByVal hProcess As Long, lpExitCode As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Public Sub SincMiProceso(ByVal ExeFile As String)

    On Error GoTo Err_Sinc
   
    Dim lngPid As Long, lngRc As Long
    lngPid = OpenProcess(PROCESS_QUERY_INFORMATION, False, Shell(ExeFile, vbNormalFocus))
    Do
        GetExitCodeProcess lngPid, lngRc
        Sleep 100
        DoEvents
    Loop While lngRc = STILL_ACTIVE
   
    Exit Sub
   
Err_Sinc:
    MsgBox "Fallo sincronizando pgm '" & ExeFile & "'." & String(2, vbCrLf) _
    & "(" & Err.Number & ") " & Err.Description, vbCritical, "Sincronizar"

End Sub

También podrías hacer un 'Open' del archivo y supervisar el error que se producirá si el fichero está abierto.

Espero que te sirva.
Abur.

javirues

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #2 en: Miércoles 26 de Noviembre de 2003, 16:11 »
0
Gracias Brroz pero no me termina de funcionar, pq lo que esta buscando es el process id de word(en este caso) y si tengo dos documentos distintos, como comparten el mismo pid, hasta que no se cierran los dos no devuelve el control.Un word se puede ejecutar desde la aplicacion(este hay que controlarlo) y el otro podria estar abierto pq sí.
De todas formas seguire investigando por esta via, muchas gracias por tomarte la molestia...

Brroz

  • Miembro de PLATA
  • *****
  • Mensajes: 1058
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #3 en: Miércoles 26 de Noviembre de 2003, 17:28 »
0
Efectivamente, el ejemplo anterior sirve para sincronizar un proceso lanzado por nosotros. Para lo que tú quieres tal vez te sirva esto:

Private Const SYNCHRONIZE = &H100000
Private Const INFINITE = -1&
Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
End Type
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal Hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Sub SincProceso(ByVal TituloVentana As String)

    On Error GoTo Err_Sinc
   
    Dim pid As PROCESS_INFORMATION
    Dim lngRc As Long
    lngRc = FindWindow(vbNullString, TituloVentana)
    lngRc = GetWindowThreadProcessId(lngRc, pid.hProcess)
    lngRc = OpenProcess(SYNCHRONIZE, False, pid.hProcess)
    If lngRc <> 0 Then
        lngRc = WaitForSingleObject(lngRc, INFINITE)
        Exit Sub
    End If

Err_Sinc:
    MsgBox "Fallo sincronizando ventana '" & TituloVentana & "'." & String(2, vbCrLf) _
    & "(" & Err.Number & ") " & Err.Description, vbCritical, "Sincronizar"

End Sub

A ver si esto te va mejor. 'TituloVentana', evidentemente es el título de la ventana que queremos controlar cuando se cierra...

Suerte.

javirues

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #4 en: Jueves 27 de Noviembre de 2003, 13:04 »
0
Perdona Brozz, pero despues de dos dias contodo este mogollon creo que cada vez voy mas para atras, no encuentro la conbinacion perfecta para solucionar este tema.La maldita aplicacion esta quieren que ejecute un fichero word ( no se si hacerlo con CreateProcess o con ShellExecute), pero en cualquier caso, la plicacion debe quedar parada en ese momento hasta que el fichero se cierre.
He conbinado esto de varias maneras, pero en casi todos los casos he encontrado errores cuando tengo otro word abierto o lo quiero abrir mientras el de la plicacion se esta viendo(lo abro por fuera o desde el mismo word abierto), esto se debe a que usan el mismo proceso. He probado ahora con el WaitForSingleObject  con INFINITE pero la aplicacion no para y si para me cuelga todo el Word y no puedo abrir otro.Se que esto es un poco de locos pero ya no se que hacer me duele el cabezon de tanto darle, ¿se te ocurre algo?
Gracias y perdona por darte tanto el coñazo.

Brroz

  • Miembro de PLATA
  • *****
  • Mensajes: 1058
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #5 en: Jueves 27 de Noviembre de 2003, 15:08 »
0
Hola javirues.

Aparte de algún detalle del código que supongo que abrás localizado, te recomiendo que tengas en cuenta una cosa muy importante: FindWindow sólo devolverá un handle para la ventana si el título de la ventana que especificas Coincide 100% con el título de la ventana que buscas. Por ejemplo, si abres el Word con un documento en blanco, el título debería ser Microsoft Word - Documento1, cuando abres un documento, el título será del estilo Microsoft Word - Nombre.doc.

Para tener controlado esto, lo mejor sería que previamente guardes el documento que quieras abrir.

Si abres una instancia de word con un nuevo documento y al usuario se le ocurre guardarlo, la sincronización fallará al cambiar el título de la ventana.
Para solucionar estos casos, guarda previamente el documento en blanco para conocer el nombre que tendrá la ventana.

No se si me habré explicado muy bien... A ver si arreglas.

Chao.

Brroz

  • Miembro de PLATA
  • *****
  • Mensajes: 1058
    • Ver Perfil
Como Saber si un fichero esta abierto...
« Respuesta #6 en: Jueves 27 de Noviembre de 2003, 15:13 »
0
Una cosa que se me quedaba atrás:

Para hacer lo que te comentaba de guardar el documento con un nombre (o para abrirlo) podrías seguir uno de estos dos caminos:

1- Tener un documento en blanco y abrirlo con 'ShellExecute' (puedes tener un modelo en algún sitio y cuando llega el momento lo copias con el nombre que tu quieras).

2- Usar la automatización de word.

Suerte.

jorge.adell

  • Nuevo Miembro
  • *
  • Mensajes: 9
    • Ver Perfil
Re: Como Saber si un fichero esta abierto...
« Respuesta #7 en: Miércoles 7 de Enero de 2004, 07:25 »
0
Yo tuve que hacer esto ya y lo que hago es abrir el archivo que posiblemente otra aplicacion tenga abierta  y lo hago con la opcion lock read write y si da error es porque esta tomada por otra aplicacion.
Si no funciona contanos porque.