いつもお世話になります。
VBScriptに引数を渡すにはどうすれば良いでしょうか?
下の方法では渡せませんでした。
アドバイスをお願い致します。
--------------------------------
var
Fname : string;
begin
FName := 'Test.vbs';
ShellExecute(Handle, 'OPEN', PChar(FName),
PChar('1'), nil, SW_NORMAL);
end;
--------------------------------
'test.vbs
msgbox WScript.Arguments.Item(0)
Mr.Xrayさんのサイトで見つけました。
http://mrxray.on.coocan.jp/Delphi/plSamples/950_VBScript.htm#05
ありがとうございました。
こんにちは.Mr.XRAYです.
サイトご利用ありがとうございます.解決ということですが,
http://mrxray.on.coocan.jp/Delphi/plSamples/950_VBScript.htm#05
はちょっと質問の趣旨とは意味あいが違うと思われますが.
VBScriptに限らず,ShellExecuteでコマンドライン引数を渡して起動する場合,
Stringとして明示的にキャストすれば渡せます.
動作確認は,Windows XP(SP3) + Delphi 2010(UP5) Pro
procedure TForm1.Button1Click(Sender: TObject);
var
Fname : String;
Para : String;
begin
FName := 'Test.vbs';
Para := '1';
ShellExecute(Handle, 'OPEN', PChar(FName), PChar(Para), nil, SW_NORMAL);
end;
あるいは
procedure TForm1.Button2Click(Sender: TObject);
var
Fname : String;
begin
FName := 'Test.vbs';
ShellExecute(Handle, 'OPEN', PChar(FName), PChar(String('1')), nil, SW_NORMAL);
end;
更に,あるいはNull文字を追加してやります.
procedure TForm1.Button3Click(Sender: TObject);
var
Fname : String;
begin
FName := 'Test.exe';
ShellExecute(Handle, 'OPEN', PChar(FName), PChar('1'+ #0), nil, SW_NORMAL);
end;
こんにちは。
http://yozda.exblog.jp/tags/Delphi/
こちらの方もページを作っておられるようです
プログラムにスクリプト機能が内蔵されると
いろんなことができそうで、いいですね。
>http://yozda.exblog.jp/tags/Delphi/
おおっ,こんなすばらしい記事が,サンクスです.
VBScriptの記事書くときFusaさんの記事を参考にさせていただきました.
このリンクの記事は見落としていたようです(調べたのか? > 自分)
Mr.XRAYさん、Fusaさん
ありがとうございました。
質問の趣旨を断念し、スクリプトファイルに追記する方向で進んでいました(^^;
今まで漠然とやっていたのですが、
「Stringとして明示的にキャストすれば渡せます」でスッキリしました。
ところで、恥ずかしい話ですが、もしお時間ありましたら詳しく教えて下さい。
1.明示的にキャストしていない'1'はStringで無く何なのか。
2.'1'+ #0 の意味
何故これが「String('1')」や「var Para:String;のPara:='1'」と
同じ扱いになるのか。
キーワードが一般的すぎて検索しても該当の説明を見つけられずにおります。
よろしくお願いいたします。
直接定数を書いたり、const S = '1'とした場合などは真の定数となり、型は可変です。
string型を必要とする引数として渡した場合はstring型に、PChar型を必要とする引数として渡した場合はPChar型になります。
簡単な例で示せば、
const Value = '1';
procedure ProcA(S: PChar);
procedure ProcB(S: string);
という前提の場合、
ProcA(Value); // ←このValueはPChar型
ProcB(Value); // ←このValueはstring型
というようにコンパイル時に自動的に変換されます。
これはstring型の変数にPChar型の定数を入れたり、
PChar型の変数にstring型の定数を代入するなど、
実行時に不要な変換が起こらないようにするためです。
つまり必要な型に応じて自動的に変換されるので、
PChar(String('1'))というようなキャストは不要ですし、
どちらの場合も自動的に末尾にnullが付加されるので、
PChar('1'+ #0)といった記述も不要です。
ただしconst Value: string = '1'といったように、
型付きの定数にした場合は変数と同じ扱いになるため、キャストが必要です。
// この辺りの動作はデバッグ実行時にIDEのCPUウィンドウを開くと分かります
Tentさん、ありがとうございました。
◆上記案1
var Para : String;
Para := '1';
ShellExecute(Handle, 'OPEN', PChar(FName), PChar(Para), nil, SW_NORMAL);
の場合はString型として定義済みの為、PChar(Para) とする必要がある。
◆上記案2
ShellExecute(Handle, 'OPEN', PChar(FName), PChar(String('1')), nil, SW_NORMAL);
は、PChar(String('1')) としなくても '1' だけで良い。
◆上記案3
ShellExecute(Handle, 'OPEN', PChar(FName), PChar('1'+ #0), nil, SW_NORMAL);
は型を定義していないため、PChar('1'+ #0) としなくても '1' だけで良い。
◆備考
①PChar(String('1')) や ②PChar('1'+ #0) が成功するのに、
③PChar('1') が成功しない理由は、
①はString('1')の時点で自動変換でヌル文字が付く、
②は手動でヌル文字を付けているが③は付いていないため。
という事なのですね。(備考部分は自信が無いですが…)
とても良く理解できました。
ありがとうございました。
◆メモ:String型とPChar型の関係
ShellExecuteはWindows APIなので文字列を渡すには、
DelphiでのString型とは違いポインタ変数であるPChar型を使う必要がある。
PChar型は文字列の最後にヌル文字#0が付加してある型。
var
P:PChar
begin
P := PChar('1')
ここで1文字だけ指定すると本来 '' で囲まれた文字列が格納されている
アドレスを返さないといけないのに '' で囲まれた1文字のコード
を返しているみたい。
2文字以上あればアドレスを返してるのでバグのような気がするけど
KHE00221さん
ありがとうございます。
上の備考で書いたものの
・PChar(String('1')) や PChar('1'+ #0) が成功するのに、
PChar('1') が成功しない
点が、どうも納得できてなかったのですが、
バグであるとすると納得できます。
こんな単純(?)なバグってあるんですね...
言語のバグに遭遇することが初めてなので驚きです。
>ここで1文字だけ指定すると本来 '' で囲まれた文字列が格納されている
>アドレスを返さないといけないのに '' で囲まれた1文字のコード
>を返しているみたい。
>2文字以上あればアドレスを返してるのでバグのような気がするけど
バグではないと思いますよ。
Delphiは「文字列」と「文字定数」は同じ書き方になっていて、'1'と書くと「文字列」と「文字定数」の両方の解釈が出来ます。
「長さが 1 の文字列」は どの「文字型」とも互換性があり、1文字だけの場合は「明示的に文字列」としないかぎり「文字定数」とみなされるので、
> P := PChar('1');
のPの値が「文字列'1'の格納アドレス」にならず、「文字'1'の文字コード」になるのは当然です。
この場合の'1'は「文字定数」と解釈されるので、定数値 #$31 をPChar型にキャストしても $31 の値は変わりませんから。
というよりさんの仰る通りバグではありません。
SizeOf('1')とSizeOf('11')の返値を見れば分かると思います。
ヘルプにも、長さが1の場合は(文字列型ではなく)文字型と互換性を持つ、と書いてあります。
書き忘れましたが、キャストは最低限にしたほうが良いと思います。
上記の通り定数は自動的に適切な型に変換される機構がありますから、
不必要なキャストや意味を理解せずにするキャストは本来不要な問題を引き起こします。
あれまっ,
ちょっとした間にいろいろ参考になる内容が.
あまり解説付きでレスすると文章が長くなるし,嫌われそうなのでので省略しましたが.
PChar('1'+ #0)
のコード書いておけば終端文字のことを調べるかな〜と,想定して.
>書き忘れましたが、キャストは最低限にしたほうが良いと思います。
ですね.ということで,
PChar('1'),
もできればやめた方がいいです.もちろん,PChar(String('1'))も.
OPENにもつけていませんよね.
Delphiでは,型を指定して値を代入するという方法が良いかも知れません.
と言いつつ,私もよくやっていますけど.自戒も含めて.
var
P:PChar
begin
P := Char('1')
の場合きちんとアドレスになるわけだが・・・・
動きとしては
P := PChar(100);
P := PChar(300);
なんかと同じなんだよね・・・
ツイート | ![]() |