58

C# を使用して、別のプロセスによってロックされているファイルを削除する方法を探しています。このメソッドは、ファイルをロックしているプロセスを見つけて (おそらくハンドルを追跡することによって、C# でこれを行う方法がわかりませんが)、そのプロセスを閉じてから、 を使用してファイルの削除を完了する必要があると思いますFile.Delete()

4

8 に答える 8

37

他のプロセスを強制終了することは、健全なことではありません。アンインストールなどのシナリオが含まれる場合は、MoveFileExAPI 関数を使用して、次回の再起動時にファイルを削除するようにマークすることができます。

別のプロセスで使用されているファイルを本当に削除する必要があると思われる場合は、解決策を検討する前に実際の問題を再検討することをお勧めします。

于 2008-08-04T06:01:52.873 に答える
16

代表的な方法は以下の通りです。あなたはC#でこれをやりたいと言ったので、ここに行きます...

  1. ファイルがロックされているプロセスがわからない場合は、各プロセスのハンドル リストを調べ、各ハンドルにクエリを実行して、ロックされたファイルを識別するかどうかを判断する必要があります。C# でこれを行うには、必要なネイティブ API を呼び出すために、P/Invoke または中間の C++/CLI が必要になる可能性があります。
  2. ファイルがロックされているプロセスを特定したら、そのプロセスに小さなネイティブ DLL を安全に挿入する必要があります (マネージ DLL を挿入することもできますが、開始する必要があるため、これは面倒です。または .NET ランタイムにアタッチします)。
  3. そのブートストラップ DLL は、CloseHandle などを使用してハンドルを閉じます。

基本的に、「ロックされた」ファイルのロックを解除する方法は、問題のあるプロセスのアドレス空間に DLL ファイルを挿入し、自分で閉じることです。これは、ネイティブ コードまたはマネージド コードを使用して行うことができます。いずれにせよ、少量のネイティブ コードまたは少なくとも P/Invoke が必要になります。

便利なリンク:

幸運を!

于 2008-08-04T06:15:30.363 に答える
8

プログラムで実行したい場合。よくわかりません...そして、私はそれに対して本当にお勧めします. 自分のマシンでトラブルシューティングを行っているだけの場合は、SysInternals Process Explorerが役に立ちます。

それを実行し、ハンドルの検索コマンド (検索メニューまたはハンドル メニューのいずれかにあると思います) を使用し、ファイルの名前を検索します。ハンドルが見つかったら、それらを強制的に閉じることができます。

その後、ファイルなどを削除できます。

これを行うと、ハンドルを所有するプログラムが奇妙な動作をする可能性があることに注意してください。これは、ことわざの下から敷物を引き出したばかりなので、独自の誤ったコードをデバッグしている場合、またはビジュアルスタジオ/ Windowsエクスプローラー何年も前にファイルを閉じるように言ったにもかかわらず、がらくたでファイルハンドルを解放していません...ため息:-)

于 2008-08-04T06:12:11.447 に答える
5

このプログラムHandleを使用して、ファイルをロックしているプロセスを見つけることができます。これはコマンドライン ツールなので、その出力を使用していると思います。プログラムでそれを見つけることについてはわかりません。

ファイルの削除を待つことができる場合は、コンピューターの次回の起動時にファイルを削除するように指定できます。

  1. 開始するREGEDT32 (W2K)REGEDIT (WXP)、次の場所に移動します。

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager
    
  2. W2K と WXP

    • W2K:
      Edit
      Add Value...
      データ型:REG_MULTI_SZ
      値の名前:PendingFileRenameOperations
      OK

    • WXP:新しい複数文字列値の
      編集


      enter
      PendingFileRenameOperations

  3. データ領域で、"\??\" + filenameto be deleted と入力します。LFN は、引用符で囲まずに入力できます。を削除するC:\Long Directory Name\Long File Name.exeには、次のデータを入力します。

    \??\C:\Long Directory Name\Long File Name.exe
    

    を押しOKます。

  4. 「宛先ファイル名」はヌル (ゼロ) 文字列です。次のように入力します。

    • W2K:
      Edit
      Binary
      select Data Format: Hex
      16 進文字列の末尾をクリックし、
      0000 (4 つのゼロ) を入力します。
      OK

    • WXP:
      値を右クリックし、
      [Modify Binary Data] を選択します。16
      進文字列の末尾をクリックします。0000
      (4 つのゼロ) を入力します。
      OK

  5. 閉じREGEDT32/REGEDITて再起動し、ファイルを削除します。

(後世のために、ランダムなフォーラムから恥知らずに盗まれました。)

于 2008-08-04T05:59:53.000 に答える
4

Orion Edwards のアドバイスを使用して、Sysinternals Process Explorerをダウンロードしました。これにより、削除に苦労していたファイルが実際には、Excel.Applications私が思っていたオブジェクトによって保持されているのではなく、私の C# コード送信メール コードが作成したという事実によって保持されていることがわかりました。このファイルへのハンドルを開いたままにした Attachment オブジェクト。

これを見て、Attachment オブジェクトの dispose メソッドを呼び出すと、ハンドルが解放されました。

Sysinternals エクスプローラーを使用すると、これを Visual Studio 2005 デバッガーと組み合わせて使用​​することがわかりました。

このツールを強くお勧めします!

于 2009-03-04T13:43:43.283 に答える
3

これは有望に見えます。ファイルハンドルを強制終了する方法...

http://www.timstall.com/2009/02/killing-file-handles-but-not-process.html

于 2009-02-25T17:41:47.297 に答える
3

ああ、私が何年も前に採用した 1 つの大きなハックは、Windows ではファイルを削除できないが、ファイルを移動できるということです。

コードの疑似ソート:

mv %WINDIR%\System32\mfc42.dll %WINDIR\System32\mfc42.dll.old
Install new mfc42.dll
Tell user to save work and restart applications

アプリケーションを再起動すると (マシンを再起動する必要はありませんでした)、新しい が読み込まれ、mfc42.dllすべて問題ありませんでした。それは、システム全体が次に再起動したときに古いものを削除することと相まって、PendingFileOperationsかなりうまくいきました.

于 2008-08-04T06:14:42.690 に答える