- PR -

プロセスが握っているディレクトリの強制排除

投稿者投稿内容
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2009-02-19 18:36
こんにちは。

現在、C#のプログラムで、ディレクトリのバックアップをしているのですが、そのディレクトリは同じプログラム内ですが、別Threadが握っています。

これを無視して、このディレクトリを削除する事は可能でしょうか?
危ない事は分かっているのですが・・、できればしたいです。
ほったて
ベテラン
会議室デビュー日: 2007/11/10
投稿数: 68
投稿日時: 2009-02-19 19:42
sysinternals の handle というツールでプロセスのファイルハンドルを
強制的に切ることが出来るみたいです。

http://technet.microsoft.com/en-us/sysinternals/default.aspx
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2009-02-19 20:24
ありがとうございます。

他にツールをインストールしなければいけないんでしょうか?

//フォルダの存在チェック(無ければ作成する)
if (System.IO.File.Exists("C:/tmp" + "/back") == false){
System.IO.Directory.CreateDirectory("C:/tmp" + "/back");
}

//出力先PDFファイル名作成
_outputfile = "C:/tmp" + "/back" + "/test.pdf";

//PDFファイル移動
File.Move(realfile, _outputfile);


PDF作成時のソースを見ていたのですが、プロセスの開放できそうな感じがしないのですが、どこかまちがっているでしょうか?
このフォルダにタッチしているのはここだけなので、何とかクリアしたいのですが・・。
いとっと
常連さん
会議室デビュー日: 2005/06/10
投稿数: 33
投稿日時: 2009-02-19 20:46
引用:

PDF作成時のソースを見ていたのですが、プロセスの開放できそうな感じがしないのですが、どこかまちがっているでしょうか?
このフォルダにタッチしているのはここだけなので、何とかクリアしたいのですが・・。



何に困ってらっしゃるのかいまいち分からないのですが、何かエラーが出るのでしょうか?
File.MoveやCreateDirectoryでエラーが出るならそのエラーを書いた方がよいと思います。

また、現象の再現が可能なミニマムコードを書くとよりよいアドバイスがつくと思います。
提示していただいたコードでは何が問題なのかがちょっと分かりませんでした。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2009-02-19 21:09
ありがとうございます。




バックアップの処理で、元ディレクトリを最後に削除しているのですが、
string work_dir = "C:\\test";
foreach (string fName in System.IO.Directory.GetDirectories(work_dir)) {
foreach (string fileName in System.IO.Directory.GetFiles(fName)) {
string bk = pdfback_dir + fName.Substring(fName.LastIndexOf("\\"));
if (System.IO.Directory.Exists(bk) == false) {
System.IO.Directory.CreateDirectory(bk);
}
bk = bk + "\\" + System.IO.Path.GetFileName(fileName);
if (System.IO.File.Exists(bk) == true){
System.IO.File.Delete(bk);
}
System.IO.File.Copy(fileName, bk);
System.IO.File.Delete(fileName);
}
System.IO.Directory.Delete(fName, true); ←ここで、以下のエラーが出てます。
}

System.IO.IOException: パス 'C:\test\test' へのアクセスが拒否されました。

のような、エラーが出力されます。

そこで、フォルダを握ってるプロセスがあるとすれば、上記の箇所でした。

お分かりになりましたら、よろしくお願いします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2009-02-19 21:11 ]
いとっと
常連さん
会議室デビュー日: 2005/06/10
投稿数: 33
投稿日時: 2009-02-20 00:41
引用:

未記入さんの書き込み (2009-02-19 21:09) より:


System.IO.IOException: パス 'C:testtest' へのアクセスが拒否されました。

のような、エラーが出力されます。
そこで、フォルダを握ってるプロセスがあるとすれば、上記の箇所でした。
お分かりになりましたら、よろしくお願いします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2009-02-19 21:11 ]



ためしにいただいたコードをメソッドにしてテストしてみましたが、特にエラーは出ませんでした。
正しくコピーもされています。

コード:
static void CopyAndDelete(string fromDir, string toDir) {
    foreach (string fName in System.IO.Directory.GetDirectories(fromDir)) {
        foreach (string fileName in System.IO.Directory.GetFiles(fName)) {
            string bk = toDir + fName.Substring(fName.LastIndexOf("\\\\\\\\"));
            if (System.IO.Directory.Exists(bk) == false) {
                System.IO.Directory.CreateDirectory(bk);
            }
            bk = bk + "\\\\\\\\" + System.IO.Path.GetFileName(fileName);
            if (System.IO.File.Exists(bk) == true) {
                System.IO.File.Delete(bk);
            }
            System.IO.File.Copy(fileName, bk);
            System.IO.File.Delete(fileName);
        }
        System.IO.Directory.Delete(fName, true); //←ここで、以下のエラーが出てます。
    }
}



ちなみにこのコードだとフォルダの下にフォルダがあるケースには対応が
出来ていないのでその点は直すべきだと思いますが、今回出ているアクセス拒否の
エラーとはまた別の話ですし、何か他の要因があるのではないでしょうか?

該当のフォルダをエクスプローラで開いたままだとか、中にあるファイルを
開いたままにしていたり、Process.Startなどで起動したりしていないでしょうか。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2009-02-20 07:26
ワーキング ディレクトリが移動しているとか。

とりあえず、テンポラリは、GetTempName だったかな?それ用のメソッドがあります。Vista 以降、ドライブ ルートに書き込みができるかわからないし、第一必ず C ドライブがあるとも限りません。
未記入
大ベテラン
会議室デビュー日: 2008/07/11
投稿数: 182
投稿日時: 2009-02-20 10:24
ご確認いただいてありがとうございます。

書き忘れておりましたが、環境はWinXP-SP2 & Windows2003Server(本番機)です。

実際、コピーのバックアップはうまく行っていますが、そーすからもお分かりになると思いますが、全部コピーし終わったら、そのディレクトリを削除しようとしています。

そこで、これはプログラムの仕様ですが、この削除しようとしているディレクトリにタッチする可能性があるのは、PDF生成時(バックアップする物)このディレクトリを生成する処理部と、このバックアップ処理部の2箇所です。

また、題目でこのように質問しましたのも、この2つの処理部はThread上で動作しており、それぞれ違うThread上で動いてる為、このような現象が起こるのではないかと推測しています。

ただ、不思議なのはエクスプローラから、このアプリが起動中でも手動で削除できてしまうんですよね・・。

>Jittaさん
C#はほとんど初心者なのですが、ワーキングディレクトリとはどのような事を指しているのでしょうか?.netが内部的に一時ディレクトリを使っていると言う事でしょうか?また、削除するのに属性をチェックしないといけないのでしょうか?

getTempPathでこのように取れたのですが・・。
C:\Documents and Settings\LocalService\Local Settings\Temp\

カレントディレクトリなど、Javaでは意識した事ないんですが・・(UNIX系はありますけど)。
MS製品の仕様と言うことでしょうか?

基礎が分かっておらず申し訳ありません。教えていただけないでしょうか?

********************************************************************
ちなみに属性変更をしても、同じようにアクセスを拒否されました。
カレントディレクトリも移動させたのですが、だめでした。

??



[ メッセージ編集済み 編集者: 未記入 編集日時 2009-02-20 14:28 ]

スキルアップ/キャリアアップ(JOB@IT)