Pregunta

Tengo un programa de actualización que es completamente independiente de mi aplicación principal. Puedo ejecutar el Update.exe para actualizar el app.exe. Para comprobar para ver si el archivo está en uso, lo muevo a otro archivo y coger un error si está en uso. Si no hay problemas occurr puedo cambiar el nombre de nuevo. Al menos esa era mi plan ...

  

programa principal: app.exe
  Programa de actualización: update.exe

Este programa es utilizado por la red sin ningún tipo de servicios que se ejecutan. Así, los usuarios es, literalmente, corriendo el exe través de la red a emabrgo máquina.

Es necesario que actualice la app.exe cuando el update.exe se ha ejecutado. Para comprobar para ver si el app.exe todavía estaba en uso estaba envolviendo el siguiente en un try / catch para ver si fallaba:

  

IO.File.Move (upddir & "\ app.exe", upddir & "\ app.exe.tst")
  IO.File.Move (upddir & "\ app.exe.tst", upddir & "\ app.exe")

Lo curioso es que, incluso si el app.exe está funcionando, el movimiento puede cambiar el nombre a la app.exe.tst sin ningún error. Incluso puedo continuar en la aplicación sin ningún error.

pensé que estaba fuera de mi mente, así que tenía otra mirada programador en esto y verificado lo que he dicho anteriormente.

Por lo tanto, hemos intentado esto envuelto en un intento de captura:

  

readfile Dim como nuevo FileStream (upddir & "\ app.exe", FileMode.Open, FileAccess.Read, FileShare.NONE)
  readfile.Dispose ()

pongo el uso compartido de archivos, ya que ninguno de que, al menos, pensé que sería, muestran que había alguien en el archivo.

Todavía continuó sin ningún error.

Alguien sabe qué puedo cambiar el nombre de un archivo en uso? Además, hay una mejor manera de hacer esto que lo que estoy haciendo ahora?

Gracias! Eroc

¿Fue útil?

Solución

Se puede hacer lo siguiente para comprobar si la aplicación tiene otras instancias en ejecución:

Process.GetProcessesByName("app.exe", "Machine1").Length > 0

¿Qué es una forma más adecuada de comprobar si la aplicación se está ejecutando.

Tener un vistazo a File.Move documentación de MSDN. En él se detalla lo que se producen excepciones. Se le permite cambiar el nombre de un archivo EXE, incluso si está en uso en Vista.

Otros consejos

El mismo código utilizando el "uso":)

Public Function FileInUse(ByVal sFile As String) As Boolean
 Dim thisFileInUse As Boolean = False
 If System.IO.File.Exists(sFile) Then
     Try
       Using f As New IO.FileStream(sFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)
                ' thisFileInUse = False
       End Using
     Catch
       thisFileInUse = True
     End Try
 End If
 Return thisFileInUse
End Function

Lo que podría hacer es sustituir la aplicación de destino con un exe cuidador.

Este cuidador continuación, genera la aplicación de destino, sino que también crea un archivo bloqueado en una ubicación compartida. El bloqueo se libera y se elimina el archivo cuando se cierra la aplicación.

A continuación, antes de actualizar el app.exe, devolver a la salida ¿Hay algún archivo bloqueado en la ubicación compartida, si hay archivos bloqueados, la app.exe está en uso.

El programa cuidador podría ser una aplicación sin ventanas, la siguiente aplicación de consola hace bastante más de lo que tiene que hacer

class Program
{
    static string lockFileName;
    static System.IO.StreamWriter lockFileWrtier;
    static void Main(string[] args)
    {
        lockFileName = "AppLock_" + System.IO.Path.GetRandomFileName();

        lockFileWrtier = new System.IO.StreamWriter(lockFileName);

        System.Diagnostics.Process p = new Process();
        p.StartInfo.FileName = "cmd.exe";
        p.EnableRaisingEvents = true;
        p.Exited += new EventHandler(p_Exited);

        p.Start();

        Console.WriteLine("Press any key to stop");
        Console.ReadKey();
    }

    static void p_Exited(object sender, EventArgs e)
    {
        lockFileWrtier.Dispose();
        System.IO.File.Delete(lockFileName);

        Console.WriteLine("Process has exited");
    }
}

El proceso de actualización a continuación, busca todos los "AppLock_ *" archivos, e intenta abrirlos con un bloqueo de escritura, si no puede obtener un bloqueo de escritura en uno de ellos, el exe está en uso.

Espero que esto ayude.

Esto es lo que terminé haciendo. El análisis de la red no funcionaba en una red peer-to-peer. No resolver las otras computadoras en absoluto.

De todos modos, aquí está:

  

Private Sub CheckFileIfFileIsInUse (ByVal thefilename como secuencia)
        Trate
            'En el sistema operativo Vista se puede cambiar el nombre de un archivo que está en uso
            "La 'en uso' del archivo original sigue el nuevo nombre de archivo

      Dim testfile As String = thefilename & ".tst"<br />

      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

      ' so we have to rename it to something else<br />
      IO.File.Move(thefilename, testfile)<br />

      ' copy it back to the original file name in case something <br />breaks 
      ' this just keeps them in working order if it does<br />
      IO.File.Copy(testfile, thefilename)<br />

      ' then we try to delete the original file that could be in use <br />
      ' which will return an 'in use' error at this point<br />
      If IO.File.Exists(testfile) Then<br />
          IO.File.Delete(testfile)<br />
      End If<br />

  Catch ex As Exception<br />
      'throw it to the originating method<br />
      Throw<br />
  End Try<br />
     

End Sub

Espero que esto ayuda a la siguiente persona.

Public Function FileInUse(ByVal sFile As String) As Boolean
    If System.IO.File.Exists(sFile) Then
        Try
            Dim F As Short = FreeFile()
            FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)
            FileClose(F)
        Catch
            Return True
        End Try
    End If
End Function
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top