11

C# を使用して Visual Studio 2010 でこの Windows フォーム アプリケーションを作成しています。

フォームには [実行] ボタンがあり、ユーザーがボタンを押すと、プログラムはいくつかのファイルを生成し、Outputフォルダーに保存します (これは、を使用してプログラムによって作成されますDirectory.CreateDirectory()) 。

以前の実行からの出力ファイルを保存するアーカイブ フォルダーを作成したいと考えています。

各実行の最初に、既存のOutputフォルダーをフォルダーに移動してからArchive、新しいフォルダーを作成しようとしOutputます。以下は、ディレクトリを移動するために実行した関数です。

static void moveToArchive()
{
    if (!Directory.Exists("Archive")) Directory.CreateDirectory("Archive");
    string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
    try
    {
        Directory.Move("Output", "Archive\\" + timestamp);
    }
    catch(Exception e)
    {
        Console.WriteLine("Can not move folder: " + e.Message);
    }
}

私が遭遇した問題は私をとても混乱させます...

出力フォルダーをアーカイブに正常に移動できる場合もありますが、失敗する場合もあります。

例外をキャッチして得たエラーメッセージはAccess to path 'Output' is denied.

フォルダ内のすべてのファイルがOutput使用されていないことを確認しました。常にではなく、時々アクセスが拒否される方法がわかりません。

誰かが私に説明して、問題を解決する方法を教えてもらえますか?

- 編集 -

HansPassant のコメントの後、関数を少し変更して、現在のディレクトリを取得し、フル パスを使用しました。しかし、私はまだ同じ問題を抱えています。

関数は次のようになります。

static void moveToArchive()
{
    string currentDir = Environment.CurrentDirectory;
    Console.WriteLine("Current Directory = " + currentDir);
    if (!Directory.Exists(currentDir + "\\Archive")) Directory.CreateDirectory(currentDir + "\\Archive");
    string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
    try
    {
        Directory.Move(currentDir + "\\Output", currentDir + "\\Archive\\" + timestamp);
    }
    catch(Exception e)
    {
        Console.WriteLine("Can not move folder: " + e.Message);
    }
}

現在のディレクトリを印刷したところ、期待どおりでしたが、フルパスの使用にはまだ問題があります。Access to path 'C:\Users\Me\Desktop\FormApp\Output' is denied.

- 編集 -

みなさん、回答とコメントありがとうございます。

この部分を見逃している方もいらっしゃると思いますので、もう少し強調します。

Directory.Move() が機能する場合と失敗する場合があります。

関数が成功した場合、問題はありませんでした。Outputフォルダが移動されますArchive

関数が失敗すると、 Access to path deniedという例外メッセージが表示されました。

4

7 に答える 7

14

返信とヘルプをありがとうございました。私は問題が何であるかを理解しました。

完全に閉じていないファイルがあったためです。

生成されたファイルをチェックしていて、プログラムが読み取っていたファイルを見逃していました。

生成されたすべてのファイルは完全に閉じられました。StreamReader以前は開いていたのに閉じなかったファイルの 1 つです。私はコードを修正しましたが、現在は問題が発生していないので、それが問題だったと思います。

すべてのコメントと回答に感謝します。これは、問題を考えて理解するのに間違いなく役立ちます。

于 2013-09-23T18:52:06.437 に答える
4

http://windowsxp.mvps.org/processlock.htmを参照してください。

ファイルまたはフォルダーを移動または削除しようとすると、アクセス違反または使用中のファイル - エラーが表示されることがあります。ファイルを正常に削除するには、ファイルをロックしたプロセスを特定する必要があります。最初にプロセスを終了してから、特定のファイルを削除する必要があります。どのプロセスがファイルをロックしたかを知るには、この記事で説明した方法のいずれかを使用できます。

Process Explorer の使用 - http://download.sysinternals.com/files/ProcessExplorer.zipからダウンロードします。

Process Explorer は、どのハンドルおよび DLL プロセスが開いているか、またはロードされているかに関する情報を表示します。

Microsoft サイトから Process Explorer をダウンロードし、プログラムを実行します。[検索] メニューをクリックし、[ハンドルまたは DLL の検索] を選択します。ファイル名 (何らかのプロセスによってロックされているファイルの名前) を入力します。検索語句を入力したら、[検索] ボタンをクリックします。ファイルにアクセスします。

于 2013-09-20T23:46:38.500 に答える
1
File.SetAttributes(Application.dataPath + "/script", FileAttributes.Normal);
Directory.Move(Application.dataPath + "/script", Application.dataPath + "/../script");

これで問題が解決しました。

于 2017-11-09T13:07:23.653 に答える
0

私は同じ問題を抱えていました。時々失敗しましたが、常にではありませんでした。私はそれを Try Catch ブロックでラップし、ユーザーに Access Denied メッセージを提示しようと考えました。Try Catch ブロックでラップすると、失敗しなくなりました。理由は説明できません。

 If existingFile.FileName <> newFileName Then
    Dim dir As New IO.DirectoryInfo(existingFile.FilePath)
    Dim path As String = System.IO.Path.GetDirectoryName(dir.FullName)
    newFileName = path & "\" & newFileName

    File.SetAttributes(existingFile.FilePath, FileAttributes.Normal)
        Try
            IO.File.Move(existingFile.FilePath, newFileName)
        Catch ex As Exception

        End Try
End If
于 2020-04-14T09:16:29.897 に答える