引数について

解決


yashichi  2004-03-31 17:08:40  No: 82801  IP: [192.*.*.*]

初めて投稿します。
VB初心者ですみませんが
他システムから引数取得について教えてください。

他システムから受け渡された引数をVB側で引き継ぐには
どのようにすればよろしいのでしょうか?
Call Shell(Path)を使えばよろしいのでしょうか?

本文が短くて申し訳ございませんがよろしくお願いいたします。

編集 削除
nanashi  2004-03-31 17:13:15  No: 82802  IP: [192.*.*.*]

実行時のコマンドライン引数のことを言っているならCommand関数で取得することが出来ます。

編集 削除
yasu  2004-03-31 18:19:45  No: 82803  IP: [192.*.*.*]

nanashiさん返信ありがとうございます。

引渡側の方はDelphiでCreateProcess関数を使って引数を
渡しています。
  If Not CreateProcess('C:\work\SRC\Unit1\Project2.exe',
                       PChar(Edit1.Text),
                       nil,
                       nil,
                       False,
                       CREATE_DEFAULT_ERROR_MODE,
                       nil,
                       nil,
                       SI,
                       PI) then
    Raise Exception.Create('Exec Error ' + IntToStr(GetLastError));
  While WaitForSingleObject(PI.hProcess, 0) = WAIT_TIMEOUT Do
    Application.ProcessMessages;

上記のEdit1.Textの引数を渡したいのですがうまくいきません。

あまり、理解できていなくて申し訳ないのですがVBでCommand関数を
使った時にまず引数をどのように設定すればよろしいのでしょうか?

編集 削除
たかみちえ  URL  2004-03-31 22:55:29  No: 82804  IP: [192.*.*.*]

コマンドラインというのは、おそらくあなたも今までフリー・シェア・パッケージ問わずソフトを使っていて、
使ったことはあると思います。Command関数はその文字列を得るための関数です。
上で書いているものの場合、C:\work\SRC\Unit1\Project2.exe (Edit1.Textの内容) となります。
これをCommand関数で取得します。


  あとお節介ですが、コマンドラインは512文字だったか、そのくらいの長さまでしか指定できません。
よって、Text1の文字列長によってはうまく渡せないことがあるので、
Text1の文字列長が不定で、ある程度長くなりそうな場合は、
ファイルに保存して、そのパスを渡すなどの工夫を考える必要があります。
  それと、CreateProcessでプロセスを作成したあと、
ProcessInfomationのhProcessを、CloseHandle APIで閉じるようにしてください。
終了待ちをしているのならば、そのあとに。

  あと一つ、DelphiにはWin32Checkという関数があります。これはAPIの戻り値からエラーを判断し、
RaiseLastOSErrorを呼び出すという処理を自動でやってくれるので、活用するといいかと。

編集 削除
nanashi  2004-04-01 11:11:51  No: 82805  IP: [192.*.*.*]

> 上記のEdit1.Textの引数を渡したいのですがうまくいきません。

どううまくいかないのでしょうか?
VBのプログラムが起動しないのか、Command関数で引数を取得できないのか。

> あまり、理解できていなくて申し訳ないのですがVBでCommand関数を
> 使った時にまず引数をどのように設定すればよろしいのでしょうか?

引数の指定は私に聞かれても答えようがありません。
貴方が使いたいように指定してください。


下記のような簡単なプログラムを作ってコマンドライン引数を確認してみては?
これでフォーム上に引数が表示されなければ、呼び出し側の問題でしょう。

Option Explicit

Private Sub Form_Load()
    Dim sBuff As String
    
    sBuff = Command()
    
    With Me
        .AutoRedraw = True
        Me.Print sBuff
        .Show
    End With
End Sub

編集 削除
yasu  2004-04-02 13:05:20  No: 82806  IP: [192.*.*.*]

たかみちえさん、nanashiさんいろいろありがとう
ございます。

nanashiさんに教えていただいたプログラムで実行してみましたが
引数を取得できていない模様です。
たぶん、Delphi側の方が原因みたいです。
もう少しいろいろやってみます。

編集 削除
yasu  2004-04-02 17:02:18  No: 82807  IP: [192.*.*.*]

いろいろ試してみたのですが
ShellExecute(Handle,
             'OPEN',
             'C:\work\SRC\Unit1\Project2.exe',
             PChar(Test),
             nil,
             SW_SHOW);
だと、うまくVB側にも引き渡されるのですが
CreateProcessだと引き渡されてきません。
何が原因でしょうか?

編集 削除
たかみちえ  URL  2004-04-02 19:13:23  No: 82808  IP: [192.*.*.*]

関係ないと思っていたのですが、
CreateProcess APIは、第二引数にコマンドライン全文(実行パスを含みという意味)を書いた方がよいことになっています。
別に書いた方がいいわけではないのですが、その方がいろいろな条件を付けずに済むぶん、都合がいいです。
http://www.microsoft.com/japan/developer/library/jpwinpf/_win32_createprocess.htm
実際上ので問題はないはずですが、試してみてください。

  また、おんぷむらのうら>おんぷ村倉庫>Delphiユニットに、
stdFilesというDelphiユニットがあります。
この中のRunAs関数が、CreateProcess  APIを呼び出す関数ですので、これを使ってもいいでしょう。

  なお、ShellExecute APIでそのパラメータを指定すると、全く別の意味になります。
詳しくはGoogleなどで検索してみればわかると思います。
WaitFlagにwfWaitNone以外のパラメータを指定すれば、終了待ちも行えます。

編集 削除
たかみちえ  URL  2004-04-02 19:15:42  No: 82809  IP: [192.*.*.*]

訂正、別の意味にはなりません(^_^;
普段ShellExecuteにコマンドラインをつけたりはしないもので、すっかり忘れてました。

編集 削除
yashichi  2004-04-05 13:28:30  No: 82810  IP: [192.*.*.*]

CreateProcessでも引き渡すことができました。

ただ不思議なことに引渡項目の前に空白を入れてやらないと
うまく引き渡されないのです。
例)
If Not CreateProcess('C:\work\SRC\Unit1\Project2.exe',
                       PChar(' '+test),←この部分なんですけど!
                       nil,
                       nil,
                       False,
                       CREATE_DEFAULT_ERROR_MODE,
                       nil,
                       nil,
                       SI,
                       PI) then
    Raise Exception.Create('Exec Error ' + IntToStr(GetLastError));
  While WaitForSingleObject(PI.hProcess, 0) = WAIT_TIMEOUT Do
    Application.ProcessMessages;
※VB側はnanashiさんから教えて頂いたプログラムを使っています。

今はRunAs関数を用いてやってみています。

編集 削除
たかみちえ  URL  2004-04-05 14:43:27  No: 82811  IP: [192.*.*.*]

ああなるほど、そういうことでしたか。

  あなたが最初に提示したものの場合は、
たとえば、ファイルパス(上で第一引数に指定したもの)をA、コマンドラインをBとすると、
AB  という形式になってしまい、AB両方を連結した文字列と見なされてしまうため、失敗するのです。
つまり、C:\work\SRC\Unit1\Project2.exeB となってしまうということです。
スペースを入れると、C:\work\SRC\Unit1\Project2.exe Bとなり、大丈夫 ということです。

編集 削除
yashichi  2004-04-05 14:56:30  No: 82812  IP: [192.*.*.*]

なるほど、そういうことだったのですね。
原因がわかりました。ありがとうございます。

RunAs関数のほうはやってみましたがファイルパスと
コマンドラインを設定してやってみたところすんなり
動作確認ができました。
ありがとうございます。

ちなみにこの関数はVBSでも同じように使える関数なのでしょうか?
いろいろ質問ばかりして申し訳ございませんがご教授ねがいます。

編集 削除
yashichi  2004-04-05 15:26:27  No: 82813  IP: [192.*.*.*]

たかみちえさん。

VBSでも問題なくできました。
今回はいろいろありがとうございます。

とても助かりました。

また、わからないことがあった時はお願いいたします。

編集 削除