- PR -

操作対象のフォルダの「ドライブのルート直下」にアクセス権が無いとDirectoryNotFoundException

1
投稿者投稿内容
おむすび君
常連さん
会議室デビュー日: 2005/03/11
投稿数: 29
投稿日時: 2005-05-20 10:39
操作対象のフォルダの「ドライブのルート直下」にアクセス権が無いとDirectoryNotFoundException


C#でファイル読み書き、ディレクトリ作成などを行いたいと思っています。
訳あってプロセスの実行アカウントが決められています。(Domain Usersとします)

フォルダ作成、ファイル入出力などを行う対象のフォルダには
実行アカウントで許可されるアクセス権が付与されています。

ここで(一般的な.NETのライブラリと思われる)
System.IO.FileStream
System.IO.Directory.CreateDirectory
などを使うと以下のような例外が出ます。

-----------
System.IO.DirectoryNotFoundException: パス "d:\test\test1.txt" の一部が見つかりませんでした。

at System.IO.__Error.WinIOError(Int32 errorCode, String str)

at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy)

at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
-----------

こういう状況です。

d: <-- Administrators と SYSTEMのみ※Domain Usersなし
└─test <-- いろいろ...+Domain Usersあり


長くなるので割愛しますが、アクセス権の妥当性といいますかそういったものは確認してるつもりです。
恐らく FileStreamやCreateDirectoryでは初期処理の中で最初に各ドライブの検索かなんかをやろうとして(?)、
そこが権限で見えないから例外が出てると思っています。
(余談ですが、C++でWin32APIとか使って同じようなものを作ったところ、例外は出ませんでした。
個人的には、対象のフォルダにアクセス権があるんだから例外が出なくたっていいじゃないかと思っています。)

そういうわけで別のライブラリか何かを使って対策したいのですが

ディレクトリ作成については、Win32APIを使って対策しました。
何故ならパラメータがstringだし簡単だからです。
[DllImport("imagehlp.dll")]
private static extern bool MakeSureDirectoryPathExists(string path);

ファイル入出力を実現するのに、もっとも簡単な代案は何でしょうか?
ちなみにC#で作りたいというのは必須条件です。
ご存知の方教えて下さい。宜しくお願いします。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-05-20 11:31
諸農です。

ちょっと確認したいのですが、

引用:

コード:
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy)

   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)





これって、FileStreamのコンストラクタでエラーが出ているってことですよね?
つまり、ディレクトリの作成ではエラーが出ていないということですか?

もしかしてなんですけど、

コード:
string myPath = @"D:\\\\Temp\\\\test\\\\test1.txt";//ストリームで開きたいファイル名
if (!Directory.Exists(myPath))
{
    Directory.CreateDirectory(myPath);
    using (FileStream fs = new FileStream(myPath, FileMode.Create))
    {
        StreamWriter sw = new StreamWriter(fs);
        sw.WriteLine("これは書き込みデータです");
    }
}



これだと、権限が無いエラーが出ますね。

おむすび君さんの遭遇した例外を再現できるコードをアップしていただけませんか?

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
おむすび君
常連さん
会議室デビュー日: 2005/03/11
投稿数: 29
投稿日時: 2005-05-20 12:53

早速のご回答ありがとうございます。記述が足りずにすみません。
先の例外はおっしゃるとおりFileStreamのインスタンス生成で起きた例外です。
それぞれのクラスは個別で使っていますので特に前後関係はありません。(一番下にソースを記載しました)

---------------------
ちなみにDirectory.CreateDirectory()では以下の例外がでました。
これについてはMakeSureDirectoryPathExistsを代用して対策したので
記述をしなかった...というわけでした。わかりずらくてすみません。


System.IO.DirectoryNotFoundException: パス "d:\" の一部が見つかりませんでした。
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.Directory.InternalCreateDirectory(String fullPath, String path)
at System.IO.Directory.CreateDirectory(String path)

---------------------
※ソースです
極端に書くとこういう感じです
public class Directory
{
public static bool isExists(string path)
{
return Directory.Exists(path); //※アクセス権が無いと…実際にフォルダがあってもfalseが返る
}

public static bool CreateDir(string path)
{
System.IO.Directory.CreateDirectory(path);
return true;
}
}

public class File
{
public static void Write(string path, Byte[] data)
{
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
fs.Write(data, 0, data.Length);
fs.Flush();
fs.Close();
}

public static Byte[] Read(string path)
{
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
Byte[] data = new Byte[fs.Length];

int offset=0;
int remaining = data.Length;

while (remaining > 0)
{
int read = fs.Read(data, offset, remaining);
remaining -= read;
offset += read;
}
fs.Close();
return data;
}

public static void Delete(string path)
{
File.Delete(path);
}
}
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2005-05-20 16:49
諸農です。

再現のテストをする暇が無いので、
とりあえずキーワードです。

DirectoryInfo
FileIOPermission

おむすび君
常連さん
会議室デビュー日: 2005/03/11
投稿数: 29
投稿日時: 2005-05-20 17:20
ありがとうございます。
このキーワードで調べてみます。

ちなみに以下を見つけて「おっ!」と思ったのですが
よくわかりませんでした。
試したところコード中のSubString()で落ちてしまったりしています。
別件でしょうか...
Directory.CreateDirectory() method bug fixed
http://www.codeproject.com/csharp/CreateDirectorymethod.asp
おむすび君
常連さん
会議室デビュー日: 2005/03/11
投稿数: 29
投稿日時: 2005-05-20 20:29
【解決】
まずいくつか質問させていただいたうち、
勘違いも含まれており問題をややこしくしてしまいました。
すみません。まとめます。


[問題]
操作対象のフォルダの「ドライブのルート直下」にアクセス権が無いとDirectoryNotFoundExceptionが出た
これに該当してしまうものは以下だと思った。
System.IO.Directory.CreateDirectory <--これは本当にNG
System.IO.FileStream <--※これは間違い。今回の件にはヒットしない


[結論]
System.IO.Directory.CreateDirectoryの代わりに Win32 APIのMakeSureDirectoryPathExists()を使った。(私は)
以下も有効な対策の一つかもしれませんし他にもあるかもしれません。。
Directory.CreateDirectory() method bug fixed
http://www.codeproject.com/csharp/CreateDirectorymethod.asp


[備考〜なんでFileStreamもNGだと勘違いしたか]
MakeSureDirectoryPathExists()の使い方を誤っていた。
最後に "\" を付けないと、それはファイル名と見なされるとのことで、
http://nienie.com/~masapico/api_MakeSureDirectoryPathExists.html

それを知らずにフォルダの無いパスに対してFileStreamしていたから(すみません...)


そういうわけでとにかく解決いたしました。
Jubeiさん誠にありがとうございました。
またよろしくお願いいたします。
1

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