2

メイン アプリケーションから完全に独立した更新プログラムがあります。update.exe を実行して app.exe を更新します。ファイルが使用中かどうかを確認するために、別のファイルに移動し、使用中の場合はエラーをキャッチします。問題が発生しない場合は、名前を元に戻します。少なくともそれは私の計画でした...

メインプログラム:app.exe
更新プログラム:update.exe

このプログラムは、サービスを実行せずにネットワーク経由で使用されます。したがって、ユーザーは文字通り、自分のマシンでネットワーク経由で exe を実行しています。

update.exe が実行されたら、app.exe を更新する必要があります。app.exe がまだ使用されているかどうかを確認するために、次のコードを try/catch でラップして、失敗したかどうかを確認しました。

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

面白いことに、app.exe が実行されている場合でも、この移動によりエラーなしで app.exe.tst に名前を変更できます。エラーなしでアプリケーションを続行することもできます。

私は頭がおかしいと思ったので、別のプログラマーにこれを見てもらい、彼は私が上で言ったことを確認しました.

したがって、これを try catch でラップしてみました。

Dim readfile As New FileStream(upddir & "\app.exe", FileMode.Open, FileAccess.Read, FileShare.None)
readfile.Dispose()

私はファイル共有を none として置きました。少なくとも、ファイルに誰かがいたことを示すと思いました。

それはまだエラーなしで続行されました。

使用中のファイルの名前を変更できる理由を知っている人はいますか? また、私が今していることよりもこれを行うためのより良い方法はありますか?

ありがとう!エロク

4

5 に答える 5

7

「using」を使用した同じコード:)

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
于 2011-03-21T16:00:14.350 に答える
1

できることは、ターゲット アプリケーションを世話人 exe に置き換えることです。

次に、この世話人はターゲット アプリケーションを生成しますが、共有の場所にロックされたファイルも作成します。アプリが終了すると、ロックが解除され、ファイルが削除されます。

次に、app.exe を更新する前に、共有の場所にロックされたファイルがあるかどうかを確認します。ロックされたファイルがある場合、app.exe は使用されています。

世話人プログラムは、ウィンドウのないアプリケーションである可能性があります。次のコンソール アプリは、必要なことのほとんどを実行します。

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");
    }
}

その後、アップデーターはすべての「AppLock_*」ファイルを探し、書き込みロックを使用してそれらを開こうとします。それらのいずれかで書き込みロックを取得できない場合、exe は使用中です。

お役に立てれば。

于 2009-07-03T12:52:47.427 に答える
1

アプリケーションで他のインスタンスが実行されているかどうかを確認するには、次のようにします。

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

これは、アプリが実行されているかどうかを確認するより適切な方法です。

File.Move MSDN ドキュメントをご覧ください。スローされる例外について詳しく説明します。Vista で使用中であっても、exe の名前を変更することができます。

于 2009-07-03T12:01:06.333 に答える
0

これが私がやったことです。ネットワーク スキャンは、ピア ツー ピア ネットワークでは機能しませんでした。他のコンピューターはまったく解決しませんでした。

とにかく、ここにあります:

Private Sub CheckFileIfFileIsInUse(ByVal thefilename As String)
試してください
' Vista OS では、使用中のファイルの名前を変更できます
' 元のファイルの '使用中' は新しいファイル名の後に続きます

      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 />

サブ終了

これが次の人に役立つことを願っています。

于 2009-07-06T18:29:28.287 に答える