ファイルオープン時の相対パス指定

[戻る]
まりのちゃん 2006/06/23(金) 10:09:28
ファイルオープン時の相対パス指定がうまくいきません。
どなたかご存知の方いらっしゃいましたら、教えていただけないでしょうか?

MSDNライブラリでOpenメソッドについて
--------------------------------------------------------------------------
lpszFileName 
目的のファイルのパスを示す文字列。相対パス、絶対パス、またはネットワーク名 
(UNC) を指定できます。 
--------------------------------------------------------------------------
とあり相対パス指定は可能とあります。
下記のコメント部分のような実装を行いましたが、いずれも失敗していまいます。
正しい相対パスの指定方法を教えていただけないでしょうか。
ちなみに現在はDebugモードで実行しているので
Debugフォルダにconfをおいて検証を行っています。

CStdioFile hfile;
CString fileName;

fileName = "C:\\TEST\\TEST.conf";
//fileName = "TEST.conf";     ←ダメ
//fileName = ".\\TEST.conf"; ←ダメ

if(!hfile.Open((LPCTSTR)fileName, CFile::modeRead, &e))
{
    return false;
}

Blue 2006/06/23(金) 10:24:40
カレントディレクトリは確かに C:\TEST になっていますか?

// カレントディレクトリ確認
TCHAR cd[ MAX_PATH ];
::GetCurrentDirectory( sizeof( cd ) / sizeof( cd[ 0 ] ), cd );
AfxMessageBox( cd );

まりのちゃん 2006/06/23(金) 10:32:58
Blueさん毎回ありがとうございます。

>カレントディレクトリは確かに C:\TEST になっていますか?
いえ今現在はVisual Studio Projects配下のフォルダの
Debugフォルダで作業を行ってます。

情報たらずですいません。
C:\TEST指定の場合はここにconfがあって、
exeのほうはVisual Studio Projects配下にある状態です。
つまりconfとexeが別フォルダにあって
アプリのOpenメソッドの指定でconfの場所をフルパス指定しています。

//fileName = "TEST.conf";     ←ダメ
//fileName = ".\\TEST.conf"; ←ダメ
と記述したほうは
Visual Studio Projects配下のDebugフォルダ(コンパイル時に自動でexeがおかれる場
所)にexeとconfがある状態です。

すいませんうまく伝わったでしょうか?

Blue 2006/06/23(金) 10:38:55
ん〜とりかえずカレントディレクトリはどこになっているのか確認できましたか?
VCの実行ボタンで実行するときと、exeを直接動かすときではカレントディレクトリ
が違ったような気がするんですけど。

まりのちゃん 2006/06/23(金) 10:45:59
>Blueさん
教えて頂いたロジックを実装し、実行してみました。
実行ディレクトリは一緒のようです。

F5で実行した場合と直接起動した場合に表示されたメッセージです。
C:\Documents and Settings\XXXX\My Documents\Visual Studio Projects\YYYY\Debug

んー 2006/06/23(金) 10:46:13
IDE上から実行したときはカレントはDebugやReleaaseじゃなく、プロジェクトのあるディ
レクトリなりますが…

Blueさんが書かれているようにGetCurrentDirectoryで確認されましたか?
思い込みで試行錯誤しないで、面倒だと思っても確認したほうがよいです。
(結局それが時間の節約にもなりますし)

Blue 2006/06/23(金) 10:46:14
ちなみに VC6 の場合、プロジェクトの設定で
「作業用のディレクトリ」が指定できます。
(デバッグタブ、カテゴリ-一般の 作業用のディレクトリ)

指定しないと、プロジェクトのディレクトリ(おそらくdswのあるディレクトリ)
になってしまうようです。

VC6以外の場合はワカリマセン。
※↑のようにVC6の場合とか回答者側で環境を仮定しないと回答できない質問もあるので
 質問時には、必ず環境を明記しましょう。
 (OS,VCのバージョン,プロジェクトの種類等)

んー 2006/06/23(金) 10:51:42
書いている間に書き込みが…
debugになってましたか…
失礼しました。

まりのちゃん 2006/06/23(金) 10:54:04
>んーさんへ
>Blueさんが書かれているようにGetCurrentDirectoryで確認されましたか?
>思い込みで試行錯誤しないで、面倒だと思っても確認したほうがよいです。
>(結局それが時間の節約にもなりますし)
すいません書き方が悪かったですね。

// カレントディレクトリ確認
TCHAR cd[ MAX_PATH ];
::GetCurrentDirectory( sizeof( cd ) / sizeof( cd[ 0 ] ), cd );
AfxMessageBox( cd );
を実装して、実行してみました。
実行ディレクトリは一緒のようです。

F5で実行した場合と直接起動した場合に表示されたメッセージです。
C:\Documents and Settings\XXXX\My Documents\Visual Studio Projects\YYYY\Debug

Blue 2006/06/23(金) 11:00:53
> 実行ディレクトリは一緒のようです。
ん〜、ではOpenが失敗する理由は File Not Found ではないのかな?


最終手段です。PathSearchAndQualifyを使って確認します。

#include <shlwapi.h>
#pragma comment( lib, "shlwapi.lib" )


// 略


CString fileName;

fileName = _T( "TEST.conf" );

TCHAR path[ MAX_PATH ];
::PathSearchAndQualify( fileName, path, sizeof( path ) / sizeof( path[ 0 ] ) );
AfxMessageBox( path );


メッセージボックスででてきたパスで正しいか確認してみてください。

まりのちゃん 2006/06/23(金) 11:07:54
[[解決]]
う〜ん解決なんでしょうか?

C:\Documents and Settings\XXXX\My Documents\Visual Studio Projects\YYYY\Debug
から
C:\TESTフォルダに
exeとconfを持っていったところうまくいきました。
〜Visual Studio Projects\YYYY\Debug配下ではうまく行かないのはなぜ?
なんででしょう?
ここはユーザが作成したファイルなど置いてはいけないんですかね〜?

これ以上皆様の時間を割くわけに行かないので、
とりあえず回避策がみつかりましたので解決にチェックしておきます。

この理由について今は調べてる時間がないので
後でわかりましたらカキコします。

ありがとうございました。

まりのちゃん 2006/06/23(金) 11:12:35
>> 実行ディレクトリは一緒のようです。
>ん〜、ではOpenが失敗する理由は File Not Found ではないのかな?

この辺は書き込みするにあったてちゃんと確認しました。
File Not Foundではないです。

ちなみに
if(!hfile.Open((LPCTSTR)fileName, CFile::modeRead, &e))
{
    DWORD code = GetLastError();
    return false;
}
とした場合、code=0x0000002でした。
MSDNライブラリで確認しましたが、
0x0000002のエラー要因は見つかりませんでした。

Blue 2006/06/23(金) 11:22:15
>     DWORD code = GetLastError();
ではなく、CFileExceptionの変数 e から取得すればいいのでは?
DWORD code = e.m_cause;

> MSDNライブラリで確認しましたが、
> 0x0000002のエラー要因は見つかりませんでした。
MSDNではなく、VC6の場合メニューのツールから「エラー検索」を選んで検索します。
(2は結局「File Not Found」なんだけどね。)


> ※↑のようにVC6の場合とか回答者側で環境を仮定しないと回答できない質問もあるの
>  で質問時には、必ず環境を明記しましょう。
>  (OS,VCのバージョン,プロジェクトの種類等)
2回目。

kure 2006/06/23(金) 11:22:16
GetLastError() == 2は
ERROR_FILE_NOT_FOUNDですよっと。

kure 2006/06/23(金) 11:22:42
かぶった...orz

まりのちゃん 2006/06/23(金) 11:33:33
すいません調べがたりませんでした。
Buleさんありがとうございます。

>MSDNではなく、VC6の場合メニューのツールから「エラー検索」を選んで検索します。
>(2は結局「File Not Found」なんだけどね。)

今後調べるのに参考になります。

しかし
C:\Documents and Settings\XXXX\My Documents\Visual Studio Projects\YYYY\Debug
にconfファイルがあるのに
「File Not Found」って・・・・。

みなさまありがとうございました。

Blue 2006/06/23(金) 11:34:36
PathSearchAndQualifyなんて使う必要なかったですね。
CStdioFileから取れます。

if(!hfile.Open((LPCTSTR)fileName, CFile::modeRead, &e))
{
    AfxMessageBox( hfile.GetFilePath() );
    return false;
}

通りすがりの名無しさん 2006/06/24(土) 03:35:48
>MSDNライブラリで確認しましたが、
>0x0000002のエラー要因は見つかりませんでした。
FormatMessage呼べばエラー文字列に変換してくれるよ

dairygoods 2006/06/24(土) 10:37:28
MFC の例外(CExceptionの派生)なら、
e->ReportError();
が簡単。

超初心者 2006/06/24(土) 14:26:26
VS2005で試したがオープンできたぞ。
ファイルがあるのに開けないって変だね。
アクセス拒否とかならありえるけど。

古いスレッドには追加発言できません。