実行ファイル名を変更したら動きが変わる?

[戻る]
わだちん 2002/02/20(水) 19:14:59
実行ファイル名をエクスプローラで変更し実行すると
発生していたエラーが発生しなくなったんですが何故でしょう?

ファイルのコピーをする処理があるのですがコピー時に
実行ファイル名Aの場合はエラーが発生、
実行ファイル名Bの場合は正常に処理が行われる。

ちなみに、コピーの処理にはSHFileOperationを使用しています。

レジストリに実行ファイル名Aの値が登録されていない事は確認しました。

説明不足ですが調査するきっかけになるような事でも良いので
宜しくお願いします。

sara 2002/02/21(木) 08:42:03
発生していたエラーはどんなものなのでしょうか?

わだちん 2002/02/21(木) 09:58:03
”フォルダa:\は存在しません。作成しますか?”と言うエラーメッセージが出ます。

sara 2002/02/21(木) 10:17:30
> 実行ファイル名をエクスプローラで変更し実行すると
> 発生していたエラーが発生しなくなった
 とありますが、エラーが発生しなくなった段階で、さらに実行ファイル名を元に戻して実行し
てみるとどうなりますか? その実行時の状況の違いは本当に実行ファイル名だけですか? カレ
ントディレクトリや a: ドライブの状況なども本当に同じですか?

 それから、その実行ファイルはコンソールアプリなのかそうでないのか、OSの種類など、も
う少し情報を提示してください。

わだちん 2002/02/21(木) 10:54:08
何度もすいません。
環境はWindows2000 Sp2のVC++6.0 Sp3です。

ファイル名は戻しても結果は同じでエラーが発生します。
何度変更してもAはエラーBは正常となります。
実行環境もまったく同じです。
エクスプローラでファイル名の変更をしているだけなので。

アプリは簡単なCADツールです。

何かあればお願いします。

sara 2002/02/21(木) 11:27:53
エクスプローラではなく、プロジェクトの設定のリンクの出力ファイル名をBの名前に変更して
ビルドしてできたものを実行してみるとどうですか? A,Bの名前のものをデバッグモードで
実行してみるとどうでしょうか?

他に気になることは
○VC++のSP5をインストールしてリビルドしてみるとどうか?
○SHFileOperationに渡しているファイル名はフルパスか、相対パスか? 
○コピー処理にSHFileOperation以外の関数を使うとどうなるか?(手間がかかりますけど)

わだちん 2002/02/21(木) 11:53:51
何度も本当にありがとうございます。

>エクスプローラではなく、プロジェクトの設定のリンクの出力ファイル名をBの名前に変更し>ビルドしてできたものを実行してみるとどうですか? 
試しましたが結果は同じでした。

>A,Bの名前のものをデバッグモードで実行してみるとどうでしょうか?
正常に動作します。

>○VC++のSP5をインストールしてリビルドしてみるとどうか?
すいません、SP5でした。

>○SHFileOperationに渡しているファイル名はフルパスか、相対パスか? 
フルパスです。

>○コピー処理にSHFileOperation以外の関数を使うとどうなるか?(手間がかかりますけど)
今から試そうと思っています。

1つ言い忘れていた事があります。
コンパイル時のオプションで”構造体メンバのアラインメント”という項目がありますが
現在、”2バイト”と設定しています。
あるホームページで”8バイトにした方が良い”とあったので”8バイト”に変更しました。
この場合、名前に関係なく正常に動作しました。
しかし、”8バイト”に変更した場合にファイル読込処理で正常にファイルが
読み込めなくなったため”2バイト”に戻しています。

sara 2002/02/21(木) 13:22:38
> コンパイル時のオプションで”構造体メンバのアラインメント”という項目がありますが
> 現在、”2バイト”と設定しています。

 この辺は問題かもしれません。SHFileOperationのあるshell32.libのコンパイルオプション
との兼ね合いが疑問です。デバッグモードでは正常だということからも、この辺があやしいと思
われます。

> しかし、”8バイト”に変更した場合にファイル読込処理で正常にファイルが
> 読み込めなくなったため”2バイト”に戻しています。

 読み込めるように修正した方が良いと思います。

わだちん 2002/02/21(木) 13:35:19
>読み込めるように修正した方が良いと思います。
そうですね。
ただ、なんか気持ちが悪いです。

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

sara 2002/02/21(木) 14:32:42
> ただ、なんか気持ちが悪いです。

 私としては、名前を変更してエラーがなかったのは、ただの偶然だと考えます。いわゆる動作
不定の現象ですね。
 構造体のアライメントがどういうものかを理解すれば、すっきりすると思います。

 それから余計なことかもしれませんが、構造体のアライメントによってファイルの読み込み動
作が変化するようなアルゴリズムは避けた方が良いですよ。それは、今回のようなエラーを回避
するという事ではなく、プログラムの安定性や移植性の問題です。

 今回の件は私もとても勉強になりました。

わだちん 2002/02/21(木) 15:06:40
[[解決]]
> 私としては、名前を変更してエラーがなかったのは、ただの偶然だと考えます。
>いわゆる動作不定の現象ですね。
>
やっぱり、そうでしょうかね。

> 構造体のアライメントがどういうものかを理解すれば、すっきりすると思います。
>
イメージではわかっている気ではいるんですが、
理解してないんでしょうね。

> それから余計なことかもしれませんが、構造体のアライメントによってファイルの
>読み込み動作が変化するようなアルゴリズムは避けた方が良いですよ。
>それは、今回のようなエラーを回避するという事ではなく、
>プログラムの安定性や移植性の問題です。
>
おっしゃる通りです。

まさに今回、Win95からWin2000への移植ではまりました。
ただ、言い訳ではないのですが他人が開発したアプリだったので
なるべく関係なさそうなソースは触りたくなかった事が背景にありました。

> 今回の件は私もとても勉強になりました。
>
そう言って頂けるとありがたいです。
長々とお世話になりました。
ありがとうございました。

クラフトマン 2002/02/21(木) 16:25:52
すこし補足しておきます。

構造体のアライメントを2バイトにしているのは、ファイルのデータが2バイトアライメンド
になっているからでしょう。(例えば、ファイルの先頭にWORD、その直後に隙間なくDWORDが
あるような構造)
ファイルの仕様がそうなっているのであれば、プロジェクトの設定で全体のアライメントを
変更するのではなく、#pragma packディレクティブで、ファイルにアクセスするための構造
体だけ、アライメントを変更すればよいと思います。
構造体の宣言(定義ではなく宣言)の前後に、#pragma packディレクティブをつけます。
#pragma pack(1)
struct tag_hogehoge {
    BYTE byHoge;
    WORD wHoge;
    DWORD dwHoge;
}
#pragma pack()
この例では、先頭のpack(1)で、アライメントを1バイトにして、末尾のpack()でアライメ
ントをプロジェクト設定に戻しています。

#SHFileOperationが誤動作したのは、SHFILEOPSTRUCTのFILEOP_FLAGSが、実はWORDなの
#で、それ以降がずれてしまったためですかね。

わだちん 2002/02/21(木) 17:18:24
[[解決]]
saraさん、クラフトマンさんありがとうございました。
#pragma packで問題なく読み込むことが出来ました。

他に影響がないか確認しますが。
本当にありがとうございました。

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