質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Q&A

解決済

2回答

6734閲覧

vbscriptでコマンドラインインタフェースを操作したい

rrss

総合スコア7

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

0グッド

0クリップ

投稿2017/04/14 15:19

編集2017/04/14 16:06

vbscriptでコマンドラインインタフェースを操作したい

vbscriptで、コマンドラインインタフェースのアプリケーション(以下「アプリ」)を操作するスクリプトを書いています。
この「アプリ」は、既存で存在する製品です。

操作したいアプリケーションに対しては、「接続先」、「ID」、「PASS」をこの順番にプロンプトで入力していき、
ID/PASSが合っていれば、認証が通り、OKを文字として返す、というような仕様です。

今書いているコードは、以下のような内容です。
当該アプリをExecメソッドで実行し、StdIn.Writelineでvbスクリプトから当該アプリに対し入力を与えています。


set sobj = CreateObject("WScript.Shell")
set objExec = sobj.Exec(アプリのパス)
objExec.StdIn.Writeline(「接続先」)
objExec.StdIn.Writeline(「ID」)
objExec.StdIn.Writeline(「PASS」)
Wscript.Sleep(5000)
objExec.Terminate()


一番最後にTeminate()を実行しているのは、この後、この処理の実行結果の出力を、
StdOut.AtEndOfStreamを利用して、出力結果の内容を最後までの一連でチェックする処理が続くのですが、
AtEndOfStreamとなる為には、呼び出したプログラムが終了していないとAtEndOfStreamとならないと
私が考えているために、止む無く入れています。

さらにその前に、Wscript.Sleepを入れているのは、ID/PASSの認証処理が行われている最中にアプリを
Terminateしてしまうと、認証処理が「途中」の状態のStdOutになってしまう為、
結果を正しく判定できないので、これも止む無く入れています。

この状態でもある程度は動くのですが、認証する際にネットワーク通信を利用しておりまして、
通信状況によっては上記の5000msのスリープでも足りずに、結果を正しく補足できない場合があります。

Sleepを長くすればいいのは理解できるのですが、そうすると、ネットワーク通信に問題がなく、
アプリが即座に結果を返してくれるような状況でも、長く設定したSleep分だけ待たなくてはいけないので、
あまり長くはしたくないと考えています。

「接続先」「ID」「PASS」を入れたあと、「なんらかの文字が出力され」、さらにその後に「文字の出力が止まった」後、起動したアプリを終了させる、ような方法は無いでしょうか。つまり、最後の「PASS」を入れたあと、「再度入力待ちになったタイミング」にてアプリを終了させる、ような方法はありませんでしょうか。
スリープしたあとにTerminateする、しか方法はないでしょうか。

このアプリは「quit」というコマンドがあり、このコマンドでアプリ自体を停止できます。
ので、「PASS」の入力の後に「quit」を入れる、というのも試みてみたのですが、
ID/PASSが間違っていた場合、再びID入力待ちになってしまうのがこのアプリの仕様でして、
IDの入力待ちになっているタイミングでの「quit」コマンド入力は、IDが「quit」として解釈されてしまい、
コマンドを終了させるという意図した動作をしてくれません。

何かお知恵を拝借したく、投稿させて頂きます。
皆様、何卒よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

汎用的な物は無理でしょう。
アプリ依存の話になりますが、
案1:objExec.StdIn.Close で、プログラムが終了してくれないか?
案2:VPNクライアントと言うことなので、コマンドの出力結果で成功失敗を見ずに、VPN内のノードに対しpingしてみて成功失敗を判断する

投稿2017/04/15 00:07

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rrss

2017/04/15 01:13

otnさん ご返信誠にありがとうございます。早速StdIn.Closeを試してみましたが、プログラムは終了してくれませんでした。 pingによるネットワーク到達確認は、気が付かない視点でした。ありがとうございます。しかし、失敗した理由をある程度は利用者に確認させたいと考えておりまして、例えば単純にID/PASSが間違っているだけなのか、そもそも認証システムへネットワーク的に到達しないのか、はたまた待ちが発生していてタイムアウトが発生したのか等など。。。
otn

2017/04/15 01:20

なるほど。自分が使うので無いなら、結果確認は必要ですね。
guest

0

ベストアンサー

VBScript-外部コマンドを実行する

run の代わりに exec を使うと標準出力が利用できるそうです。

追記

よく読むと既に exec を使ってらっしゃるようで、トンチンカンな回答でした。
でしたら、対話的に入出力できるはずなので、強制終了させずに対話してみてください。

投稿2017/04/14 16:37

編集2017/04/14 22:45
Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rrss

2017/04/14 23:26

Zuishinさん ご返答ありがとうございます!!強制終了はしたくないですので対話させるようにしたいのですが。。。 例えば、このアプリは、「接続先」をWritelineでスクリプトで入力させたあと、アプリ側で「Username:」というプロンプトが出て、「ID」の入力待ちになるのですが、この「Username:」というプロンプトを待ってから、Writelineで「ID」を与える、という対話は、どのように記述すればいいのでしょうか・・・・初心者ですみません。
Zuishin

2017/04/14 23:48

どういうアプリですか?
rrss

2017/04/14 23:53

cisco社のAnyConnectというVPNクライアントソフトの部品のvpncli.exeというアプリなのですが。。。
Zuishin

2017/04/15 00:21

VPN 接続するだけのアプリですね? だとしたらその後の出力というのはそれ程長いものではないと思うんですが、どういう結果が返るんでしょうか?
rrss

2017/04/15 00:50

①[出力]まず起動すると、以下が表示されます。起動しただけで接続の状態や、ネットワーク接続ができる状態かが確認され、その状況が表示されます。 Cisco AnyConnect Secure Mobility Client (version 4.2.01022) . Copyright (c) 2004 - 2015 Cisco Systems, Inc. All Rights Reserved. >> state: Disconnected >> state: Disconnected >> notice: Ready to connect. >> registered with local VPN subsystem. ②[出力]この後、以下のプロンプトで待ちになります。 VPN> ③[入力]ここで、接続先を入力します。 VPN> connect <接続先> ④[出力]そうすると、接続先へアクセスを試みるメッセージが以下の通り表示されます。 >> contacting host (<接続先>) for login information... >> notice: Contacting <接続先>. >> Please enter your username and password. ⑤[出力]この後、以下のプロンプトで待ちになります。 Username: ⑥[入力]ここで、IDを入力します。 Username: test1 ⑦[出力]この後、以下のプロンプトで待ちになります。 Password: ⑧[入力]ここで、PASSを入力します。 Password: ******** ⑨[出力]IDとPASSから、認証が行われ、認証OKだと以下のような一連のメッセージが表示されます。最後「state: Connected」で接続完了です。 >> state: Connecting >> notice: Establishing VPN session... >> notice: The AnyConnect Downloader is performing update checks... >> notice: Checking for profile updates... >> notice: Checking for product updates... >> notice: Checking for customization updates... >> notice: Performing any required updates... >> notice: The AnyConnect Downloader updates have been completed. >> state: Connecting >> notice: Establishing VPN session... >> notice: Establishing VPN - Initiating connection... >> notice: Establishing VPN - Examining system... >> notice: Establishing VPN - Activating VPN adapter... >> notice: Establishing VPN - Configuring system... >> notice: Establishing VPN... >> state: Connected >> notice: Connected to <接続先>. >> state: Connected ⑩[出力]この後、以下のプロンプトで待ちになります。もう実行すべきことはありません。 VPN>
Zuishin

2017/04/15 02:21

プロンプトがエラー出力に出ていれば話は簡単なのですが、そうじゃないんでしょうね。 どうも私は問題の把握がまだできていなかったようです。 つまり、 1 パスワードまでをアプリの入力に渡す 2 アプリの認証を待つためにしばらくスリープ 3 アプリの出力を得る という手順で、アプリの認証が成功したことは出力でわかる、失敗したことは待たなければわからないという条件がある。 この時、スリープ時間を長くすれば失敗したことを判別できる可能性は高くなるが、それだと待ち時間が常に長くなるという問題がある。 こういうことだと理解しました。 これは VBS でないとダメなのですか? たとえば、VBS でなければ次の手順が取れます。 1 パスワードまでを入力に渡す 2 一定時間後に発動するようタイマーをセットする 3 アプリの出力を待って、出力があった時点で処理 4 出力がない場合、2 でセットしたタイマーが発動し、現在の処理を強制終了して最初からやり直す
rrss

2017/04/16 17:13

貴重なご意見ありがとうございます。また私の拙い文章を正確に読み取って下さり感謝しております。頂きましたご意見を元に検討させて頂きます。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問