vbからDOSコマンドを実行し、結果を取得するには?

解決


もっき  2004-12-08 02:26:28  No: 87216

いつも、拝見させていただいています。
既出かもしれませんが、VBからDOSコマンド(copyとか)を実行し、
その結果(成功、失敗)を取得したいと思うのですが、方法がわかりません。
SHELL関数なんかで取得できるのでしょうか?
それようのコントロール(Inetみたいな)が用意されているのでしょうか?
結果をファイルに書き出したりなど、できるだけ使用せずに、
やりたいのですが、よろしくお願いいたします。

OS Windows98 SE
VB 5.0


de  2004-12-08 03:16:50  No: 87217

http://www1.harenet.ne.jp/cgi-bin/cgiwrap/unaap/lib/smp.cgi?c1=2&c2=2&function=&page=2
の15番のところにVB5のサンプルがあります。


もっき  2004-12-08 19:09:58  No: 87218

deさん、早速のご返答ありがとうございます。

サンプルとても参考になりました。

ただ、大変恐縮なんですが、私のイメージとしては
コマンドを実行(copyなど)し、その結果を取得する
(成功は0、エラーはそれ以外の数値)ようなものを
作りたいと思っていまして・・・

このサンプルが応用できそうなんですが、
その方法がどうしてもわかりません。

あと、話がちょっとそれるのですが、
DosのcopyとAPIに用意されているCopyFileでは
機能に違いがあるのでしょうか?

よろしく、お願いいたします。


ねろ  2004-12-08 23:37:07  No: 87219

>の15番のところにVB5のサンプルがあります。
マルチスレッドですか。(^^;
Dos画面がチラッと見えてもいいのなら
    Dim ws As Object
    Dim we As Object
    dosCommand = "dir c:\"  'コマンド
    Set ws = CreateObject("WScript.Shell")
    Set we = ws.Exec("%ComSpec% /c " & dosCommand)
    Do
        DoEvents
    Loop While (we.Status)
    If Not we.StdErr.AtEndOfStream Then
        Text1.Text = "エラー" & vbCrLf & we.StdErr.ReadAll
    ElseIf Not we.StdOut.AtEndOfStream Then
        Text1.Text = we.StdOut.ReadAll
    End If
    Set we = Nothing 'オブジェクトの開放
    Set ws = Nothing

こんなことで。


もっき  2004-12-09 01:07:20  No: 87220

ねろさん、さっそくやってみました。が、

>If Not we.StdErr.AtEndOfStream Then
ここでかたまってしまいます。
私はcopyコマンドを実行したんですが、
かたまった時点で一応ファイルはコピーされているようです。

res = we.stdOut.ReadAll
If res = "" Then
    MsgBox "エラー詳細" & vbCrLf & we.StdErr.ReadAll
Else
    MsgBox "成功"
End If

なんてやってみましたが、これも
res = we.stdOut.ReadAll
でかたまってしまいます。
どうしてもうまくいきません。

なんども質問して申し訳ないですが、よろしくお願いいたします。


ねろ  2004-12-09 02:17:40  No: 87221

え!かたまりますか。(^^;
WScriptはwin98/MEの環境はだめですか。
匿名パイプに戻るか。。。
ファイルに吐き出すか。。。
弱りました。


ねろ  2004-12-10 00:00:01  No: 87222

コンソール上の文字を読み取ることは可能なので、
かなりいいかげんなコードですが、成功、不成功だけなら何とか。。。

Option Explicit
Private Declare Function AllocConsole Lib "kernel32" () As Long
Private Declare Function FreeConsole Lib "kernel32" () As Long
Private Declare Function ReadConsoleOutputCharacter Lib _
    "kernel32" Alias "ReadConsoleOutputCharacterA" _
    (ByVal hConsoleOutput As Long, ByVal lpCharacter As String, _
    ByVal nLength As Long, ByVal CoordXY As Long, _
    lpNumberOfCharsRead As Long) As Long
Private Declare Function GetConsoleScreenBufferInfo Lib "kernel32" _
    (ByVal hConsoleOutput As Long, lpConsoleScreenBufferInfo _
    As CONSOLE_SCREEN_BUFFER_INFO) As Long
Private Declare Function GetStdHandle Lib "kernel32" _
    (ByVal nStdHandle As Long) As Long
Private Type COORD
        x As Integer
        y As Integer
End Type

Private Type SMALL_RECT
        Left As Integer
        Top As Integer
        Right As Integer
        Bottom As Integer
End Type
Private Type CONSOLE_SCREEN_BUFFER_INFO
        dwSize As COORD
        dwCursorPosition As COORD
        wAttributes As Integer
        srWindow As SMALL_RECT
        dwMaximumWindowSize As COORD
End Type
Private Const STD_OUTPUT_HANDLE = -11&

Private Sub Command1_Click()
    Dim ConsoleInfo As CONSOLE_SCREEN_BUFFER_INFO
    Dim ConsoleText As String
    Dim NrOfConsoleChars As Long
    Dim NrOfChrRead As Long
    Dim Start As Long
    Dim handle As Long
    On Error GoTo e
    AllocConsole 'コンソールを起動
    handle = GetStdHandle(STD_OUTPUT_HANDLE)
    Shell Environ("ComSpec") & " /c  copy test1.txt test2.txt"
    'Shell Environ("ComSpec") & " /c  dir c:\"
 
    handle = GetStdHandle(STD_OUTPUT_HANDLE)
    NrOfConsoleChars = 10000 'コンソール上の文字数
    ConsoleText = String(NrOfConsoleChars, vbNullChar)
    GetConsoleScreenBufferInfo handle, ConsoleInfo
    Start = 0
    DoEvents
    Do
        ReadConsoleOutputCharacter handle, ConsoleText, NrOfConsoleChars, _
            Start, NrOfChrRead
        ConsoleText = Left(ConsoleText, NrOfChrRead)
        Text1.Text = Trim(ConsoleText)
    Loop While Len(Trim(Text1.Text)) < 10  '文字の長さは適当に

e:
     FreeConsole 'コンソールを閉じる
End Sub

全部の文字を読み取りたい場合は、Shell関数は非同期なんでLoopの代わりに十分の
時間を待ってConsoleTextを取得します。
それとまずいことに、改行が入りません。ただし、成功か不成功かを判断することは
可能かな。。。。。。。。。。。。(汗


m2m10  2004-12-10 22:03:04  No: 87223

解決したとおもいますが、
2つも方法で  DIR  です。

Sub test()
    Dim oShell
    Set oShell = CreateObject("WSCript.shell")
    oShell.Run "cmd /c  dir D:\*.txt >D:\123.1"
    Set oShell = Nothing
End Sub

Sub test01()
 A = Shell("command.com /c dir D:\*.txt >D:\123.1")
End Sub


もっき  2004-12-13 17:59:35  No: 87224

ねろさん、m2m10さん、お返事遅くなりました。

なるほど、コンソール上の文字を取得して、
その文字から、判定するわけですね。

ちょっと苦しいですが、やってみようと思います。

とても丁寧に教えていただいたのに、返事が遅くなってしまい
申し訳ありませんでした。

教えていただいたコードをもとにやってみようと思います。
本当にありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加