現象:
AAA.EXEから書き込み禁止にしたUSBメモリー上にあるBBB.EXEを
ShellExecuteで実行させようとすると「ディスクは書込み禁止です」という
エラーが発生します。
判明していること:
1.このエラーはAAA.EXE側で発生しており、
エラーメッセージを無視して進めばBBB.EXEは正常に起動されます。
2.BBB.EXEを書き込み可能なデバイス上に移動させるとエラーは発生しません。
3.最初から書き込み不可能なCD-ROM上にあるBBB.EXEでもエラーは発生しません。
書き込み可能なデバイスを書き込み禁止モードにしている場合に
発生していると思われるのですがShellExecuteでEXEを実行させる場合には
書き込み禁止は解除しておかないといけないのでしょうか?
追記
WindowsXPで発生したエラーです。Vistaでは正常に動作しました。
ShellExecuteのパラメタとか2つのEXEの処理内容などはどうなってるの?
情報が不十分でした。すいません。
AAA.EXEはフォーム上にボタンを1つ配置してクリックすると次の
処理を実行させるだけのプログラムです。
ShellExecute(Handle,'open',PChar('F:\project2.exe'),nil,nil,0);
BBB.EXEというのが、この'F:\project2.exe'にあたり
こちらはコンポーネント等を何も配置していないない
新規作成時のフォーム状態でコンパイルしただけのものです。
AAA.EXE、BBB.EXE共にはファイルの書き込み処理は一切行っていません。
Delphiのバージョンは5と2007でテストしましたが
どちらも同じ結果でした。
ちなみにCreateProcessを使用するとエラーは発生しませんでした。
CreateProcessを使用すればよい話ではあるのですが、
原因がわからないと今後ShellExecuteを使用できなくなってしまうので
なんとかならないものかと調査している次第です。
ShellExecute は、CreateProcess や WinExec とは違って、ファイルを表示したり
編集するために実行ファイルを呼び出すときに使います。つまり、ファイルにアクセス
することが前提となっているから、読取専用メディアではエラー表示するのでは?
第二パラメータ 'open' は、関連付けされたアプリを使ってまさしくファイルを
開くためのものです。
試してないので何とも言えないけど。
ShellExecuteの作業ディレクトリーを別の場所にしてみたら?
(デフォルトはカレントになっていると思うので)
えーと さん
>読取専用メディアではエラー表示するのでは?
私もそう思ったのですが、CD-RやDVD-Rの読取専用メディアでは
正常に動くのです。
読取専用メディアと書込可能メディアだが書込禁止にしてある状態では
動きが異なっているような気がします。
これは? さん
作業ディレクトリを設定しても現象はかわりませんでした。
ShellExecute(Handle,'open',PChar('F:\project2.exe'),nil,PChar('D:\TEMP'),0);
USBデバイスの外付けドライブでしかテストしていなかったので、
書込み禁止にしたFDDやMOでもテストしてみようと思います。
ドライバーのバグじゃないの?
FDDを書込み禁止にしてみたところ、同じ現象が発生しました。
このことからUSBデバイス特有の問題ではないと思われます。
他のXP端末でも同じ現象が発生するので、
XPでのShellExecuteは物理的に書込できないドライブ上のファイルには
READモードでアクセスして書込可能なドライブ上のファイルには
READWRITEモードでアクセスするという動きのようですね。
Vistaの場合は書込可能ドライブでも書込み禁止なら
READモードでアクセスしているようです。
とりあえず、このような仕様だということで理解しておくことにします。
書込みしていただいたみなさん、ありがとうございました。
CreateProcessだとエラーにならないということですけど、
ShellExecuteはシェル(エクスプローラなど)でのファイル操作をエミュレートするものです。
問題のファイルをエクスプローラから実行した場合はどうでしょうか?
もし同じエラーになるようなら、ファイルを実行するにあたってシェルが何らかの書き込み動作を行っていることになります。
ついでに第2引数の'open'についてですが、
必ずしもすべてのファイルタイプでopenがデフォルトのアクションとは限りません。
(例えばマルチメディアファイルではplayがデフォルトのことが多いですし、
稀にですがopenが定義されておらず、かわりにeditなどがデフォルトになっているケースもあります。)
標準の動作をさせたければnilを指定するのが正解です。
考えにくいことではありますが、.exeの「open」アクションに何か仕込まれているのかも?
追記です。
> ファイルを実行するにあたってシェルが何らかの書き込み動作を行っていることになります。
で思い出しましたが、かつてアプリケーションの使用頻度を記録して
デフラグ時に高速化するIALAとかいう仕組がありましたね。
またXPだと、スタートメニューの項目の並びが使用頻度で変わったりします。
これらはさすがに起動先メディアに記録を書き込んだりはしないと思いますが、
その手のサードパーティ製ツールが組み込まれていたりはしないでしょうか。
>問題のファイルをエクスプローラから実行した場合はどうでしょうか?
エクスプローラから実行した場合にはエラーは発生せず、
同じようにコマンドラインから実行させた場合もエラーは発生しませんでした。
>ついでに第2引数の'open'についてですが、
レジストリを調べてみましたが、怪しい設定は見つかりませんでした。
念のため第2引数をnilにして実行した場合もエラーが発生しました。
>その手のサードパーティ製ツールが組み込まれていたりはしないでしょうか。
起動先メディアに情報を書き込むようなツールは組み込まれていないようです。
今更なのですが、エラーメッセージ「ディスクは書き込み禁止です。」には
続きがあって「ボリューム(ドライブX:内)の書き込み禁止を解除してください。」
と表示されていました。
無視して進めば問題ありませんが、理由があって書込み禁止にしているので
「解除してください」と表示されるのも困ります。
とりあえずCreateProcessで逃げましたが、今後何か情報があれば
こちらに追記していきたいと思います。
ツイート | ![]() |