web-dev-qa-db-ja.com

プログラムでモデムを制御する方法は?

現在、私が定期的にダイヤルするコンピューターは約20〜30台あります。現在、Windowsでハイパーターミナルを使用していますXP SP3)これを行うには、コンピューターを他のコンピューターに接続すると、情報の文字列が出力され、手動で目で確認してExcelに入力します。

手動接続には適していますが、自動化する必要があると感じる退屈なプロセスです。とても面倒なので(通常は1回あたり30〜40分)、今は週に1回実行していますが、理想的には、毎日スケジュールされたタスクとして実行する必要があります。ただし、ハイパーターミナルはスクリプト機能を提供していないようです。さらに、セッションロギング機能を使用してみましたが、うまく機能していないようです。

おそらくバッチまたはVBSまたはPowerShellスクリプトを使用して、一連のコンピューターに順番にダイヤルし、ターミナル出力をタイムスタンプ付きのテキストファイルに自動的に記録する方法はありますか?

追加された警告は、例外を処理できる必要があることです。コンピュータがビジーの場合。ハイパーターミナルには「ビジー時にリダイヤル」機能があり、それを使用したり、残りのコンピュータにダイヤルしてからそのコンピュータに戻ったりすることがあります。それをスクリプトに組み込む必要もあります。

ウォーダイヤリングが可能であることを考えると、出力はログに記録されず、キャリアトーンの有無のみが記録されるので、これは達成可能だと思います。これを実装するにはどうすればよいですか?

可能であれば、バッチまたはVBSソリューションが必要です。 Windows XPでのPowerShellサポートがどれほど優れているかはわかりません。さまざまな理由から、追加のツール(Pythonなど)をマシンにインストールしたくないと思います。

説明:ある時点で、ヘイズのコマンドを使用して回線にダイヤルアウトできるスクリプトを作成した友人がいます。それは簡単な部分です。難しいのは、リモートコンピュータからの印刷物を検出し、それをテキストファイルに記録できることです。

ハイパーターミナルの有料版は、これらの線に沿ってスクリプトを作成する機能を提供しますが、ビジー番号も処理できるカスタムスクリプトを使用して、これを無料で実行したいと思います。

ありがとう!

PowerShell

PowerShellスクリプトを実行すると次のようになります。 enter image description here

これが私が試したスクリプトです:

# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM3"
$serialPort.BaudRate = 1200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 23000
$serialPort.DtrEnable = "true"
# or in one command
# $serialPort= new-Object System.IO.Ports.SerialPort COM#,Baudrate,None,8,one
# Open the connection
$serialPort.Open()
# write to it
$serialPort.WriteLine( "at+csq" + "`r" )
$serialPort.WriteLine( "atdt1NPANXXXXXX" + "`r" )
# wait
start-sleep -m 50
# read line
$line = $serialPort.ReadLine()
Write-Host $line
# write to it
$serialPort.Close()

これまでで最も近い解決策:

私が得ることができた最も近いものはAHKを使用することです。これはかなり気難しいですが、役に立つのに十分な時間機能します。私の計画は、それをバッチスクリプトに接続し、各番号を渡して、各コンピューターからの印刷出力が正常に得られるまで繰り返すことです。

2
InterLinked

AutoHotkey.comが役立つ場合があります。

それを確実に機能させるための重要な秘訣は、正しいアプローチを使用することだと思います。キーストロークをMicrosoftWindowsにダンプして、Windowsがそれをフォアグラウンドアプリケーションに提供することは、最も安定した方法ではありません。これは、PuTTYと対話するために使用したコードです。スクリプトを開始してPuTTYを起動することは十分に機能しましたが、PuTTYがバックグラウンドにある場合でも、プログラムはPuTTYの正しいインスタンスと対話できました。

(このサンプルコードを大幅に適合させたいと思うでしょう。)

sPuTTYloc:="C:\Users\\me\PuTTY\PuTTY.exe"
sSiteName:="NameOfSite"
Run, "%sPuTTYloc%" -load "%sSiteName%",,UseErrorLevel,sPuTTYPID

    if %sPuTTYPID%
    {
        WinWait, ahk_pid %sPuTTYPID%
        sleep ,5000
        IfWinExist,ahk_pid %sPuTTYPID%
        {
            ControlSend,,{Enter},ahk_pid %sPuTTYPID%
; other stuff
        else
        {
MsgBox "PuTTY Window closed, spot #1"
            return ; Apparently the PuTTY window closed
        }
        Sleep 1500
        IfWinExist,ahk_pid %sPuTTYPID%
        {
            ; do other stuff
        }
        else
        {
MsgBox "PuTTY Window closed, spot #2"
            return ; Apparently the PuTTY window closed
        }
        Sleep 1500
        return
    }
return

「IfWinExist」を何度も呼び出して、物事を細かく分割しているという説得力のある理由は必ずしもありません。スクリプトを作成して最初にデバッグしたとき、リモートエンドが接続を終了した場合(PuTTYウィンドウが閉じてしまう)のデバッグに役立つことがわかりました(または、少なくとも何が起こっているのかがよくわかったように感じました)。 。

主なことは、ControlSendを使用して、Runコマンドで作成されたPIDを使用してプログラムにキーストロークを与えることにより、何か問題が発生した場合、スクリプトはWindowsにキーストロークを送信しようとし続けず、最終的にキーストロークが発生することです。間違ったプログラムに入ります。

1
TOOGAM

問題を解決できるツールは AT Command Tester Desktop App 、7日間の無料トライアル付きの商用製品($ 9.95)です。

この製品は、[スクリプトモード]タブでATコマンドのスクリプトを実行でき、ローカルコンピューターからスクリプトを保存およびロードできます。

また、次の方法で呼び出すことができるコマンドラインモードもあります。

atc –port portname –script filename

このツールは、モデムログを収集して保存することもできます。モデムがないか、呼び出す番号がわからないため、試していませんが、ログがテキストファイルとして保存されている場合は、エラー/成功の小さなテキスト検索スクリプトを作成するのは簡単です。

enter image description here


独自のスクリプトを作成したい場合は、 System.IO.Ports.SerialPortクラス を使用して簡単なPowerShellスクリプトで作成できます。

ここに例があります(テストされておらず、非常に理論的です):

# Create your instance of the SerialPort Class
$serialPort = new-Object System.IO.Ports.SerialPort
# Set various COM-port settings
$serialPort.PortName = "COM1"
$serialPort.BaudRate = 19200
$serialPort.WriteTimeout = 500
$serialPort.ReadTimeout = 3000
$serialPort.DtrEnable = "true"
# or in one command
# $serialPort= new-Object System.IO.Ports.SerialPort COM#,Baudrate,None,8,one
# Open the connection
$serialPort.Open()
# write to it
$serialPort.WriteLine( "at+csq" + "`r" )
# wait
start-sleep -m 50
# read line
$line = $serialPort.ReadLine()
Write-Host $line
# write to it
$serialPort.Close()

モデムで使用される行末文字には注意が必要であることに注意してください。

これがXP VM .Net Framework 2.0と KB9689 をインストールした場所)での私のセッションです。 COM1には何も接続されていないため、タイムアウトで終了するまでReadLine()呼び出しでハングしました。

スクリプトにコピーアンドペーストエラーがあり、修正されたことに注意してください。動作しなかった行は次のとおりです。

$line = $port.ReadLine()

それはすべきだった:

$line = $serialPort.ReadLine()

enter image description here

3
harrymc

モデムを制御する最も基本的な方法は、シリアルポートを介してコマンドを送信することです。ほぼすべてのダイヤルアップモデムは、ATDATHなどの Hayes ATコマンド (通常はシリアルモデムのハードウェアで、 USB/PCIモデム用のドライバによってエミュレートされることもあります)。

例:

  • Linux/OpenBSD/FreeBSD:すべてのプログラムとライブラリは、最終的に/dev/ttyS*特殊ファイルを使用してシリアルポートにアクセスします。 (注:Linuxでは、USBシリアルアダプターの名前はttyUSBまたはttyACMです。)
    ほとんどの場合、プログラムはパスを通常のファイルであるかのように開き、コマンドを書き込んだりフラッシュしたりして、応答を読み取ることができます。

  • Windows:すべてのプログラムは、最終的に\\.\COM1:特殊ファイルを使用してシリアルポートにアクセスします。最初の4つは、単にCOM1:として開くことができます(ショートカットはMS-DOSの遺物です)。

  • PowerShell:このトピックには DevBlog があります。

  • Python: pySerial を使用します。

Windowsでのもう1つの方法は、 Telephony API を使用することです。ただし、データ(端末)通話をサポートしているのか、音声通話のみをサポートしているのかわかりません。

2
user1686

補足として:モデムを制御するために使用するユーティリティは2つだけです。私はたくさんのSMSを送受信します、ツールはこれのために作られています。これらは複数のモデムをサポートし、ATコマンドを使用してモデムを初期化します。すべての関数はSMSで動作するようにレイアウトされていますが、initスクリプトなどで高度にカスタマイズできます。私はしていません。別のモデムにダイヤルインして何らかのデータを受信するような完全なサイクルをテストしましたが、それらを調べる価値があるかもしれません。

http://smstools3.kekekasvi.com/index.phphttps://wammu.eu/smsd/

1
pebwindkraft