RunCMD采用的是读取进程标准输出的方式,不会调用CMD进程操作

RunCMD 纯函数调用示例1

SetBatchLines -1

MsgBox % StrSplit(RunCmd("WMIC OS get version"), "`n", "`r ").2     ; OS version
MsgBox % RunCmd(A_ComSpec . " /c ftype AutoHotkeyScript")           ; executable for .ahk files 
MsgBox % RunCmd("Where user32.dll")                                 ; fullpath to user32.dll
MsgBox % RunCmd( A_Comspec . " /c Dir *.* /s",  A_AhkPath . "\..\") ; AutoHotkey files

;--------------------------------------例子2----------------------------------------------
MsgBox % RunCmd("ping autohotkey.com -n 1",,,"pingHelper") ; ahk官网的IP:104.18.44.93

pingHelper(Line, LineNum) {
  If (LineNum=2) {
    A_Args.RunCMD.PID := 0 ; Cancel RunCMD()
    Return StrSplit(Line, ["[","]"]).2
  }
}
;--------------------------------------例子3----------------------------------------------
MsgBox % "我的外网IP:" . ExternalIP()  ; 似乎不能稳定获取

ExternalIP(P*) {
  If P.Count()=2
    Return P[2]=6 ? StrSplit(P[1], ["Address:  ","`r`n"]).2 : ""  
  Return RunCmd("nslookup myip.opendns.com. resolver1.opendns.com",,,A_ThisFunc)
}

; 出处:https://www.autohotkey.com/boards/viewtopic.php?f=6&t=74647
;-------------------------------------- RunCMD v0.97 --------------------------------------
RunCMD(CmdLine, WorkingDir:="", Codepage:="CP0", Fn:="RunCMD_Output", Slow:=1) {
  Local
  Global A_Args

  Slow := !! Slow
  , Fn := IsFunc(Fn) ? Func(Fn) : 0
  , DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "Int",0)
  , DllCall("SetHandleInformation", "Ptr",hPipeW, "Int",1, "Int",1)
  , DllCall("SetNamedPipeHandleState","Ptr",hPipeR, "UIntP",PIPE_NOWAIT:=1, "Ptr",0, "Ptr",0)
  , P8 := (A_PtrSize=8)
  , VarSetCapacity(SI, P8 ? 104 : 68, 0)
  , NumPut(P8 ? 104 : 68, SI)
  , NumPut(STARTF_USESTDHANDLES:=0x100, SI, P8 ? 60 : 44,"UInt")
  , NumPut(hPipeW, SI, P8 ? 88 : 60)
  , NumPut(hPipeW, SI, P8 ? 96 : 64)
  , VarSetCapacity(PI, P8 ? 24 : 16)

  If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "Int",0, "Int",True,"Int",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1, "UInt"), "Int",0,"Ptr",WorkingDir ? &WorkingDir : 0, "Ptr",&SI, "Ptr",&PI)
    Return Format("{1:}", "", ErrorLevel := -1, DllCall("CloseHandle", "Ptr",hPipeW), DllCall("CloseHandle", "Ptr",hPipeR))

  DllCall("CloseHandle", "Ptr",hPipeW)
  , A_Args.RunCMD := { "PID": NumGet(PI, P8? 16 : 8, "UInt") }
  , File := FileOpen(hPipeR, "h", Codepage)

  , LineNum := 1, sOutput := ""
  While ( A_Args.RunCMD.PID | DllCall("Sleep", "Int",Slow) ) and DllCall("PeekNamedPipe", "Ptr",hPipeR, "Ptr",0, "Int",0, "Ptr",0, "Ptr",0, "Ptr",0)
    While A_Args.RunCMD.PID and StrLen(Line := File.ReadLine())
      sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line

  A_Args.RunCMD.PID := 0
  , hProcess := NumGet(PI, 0)
  , hThread := NumGet(PI, A_PtrSize)

  , DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0)
  , DllCall("CloseHandle", "Ptr",hProcess)
  , DllCall("CloseHandle", "Ptr",hThread)
  , DllCall("CloseHandle", "Ptr",hPipeR)
  , ErrorLevel := ExitCode

  Return sOutput
}

 

RunCMD带Gui示例演示2

#NoEnv
#SingleInstance, Force
SetWorkingDir %A_ScriptDir%
SetBatchLines -1
Menu, Tray, Icon, %A_Comspec%

Gui, Margin, 15, 15
Gui, Font, s9, Consolas
Gui, Add, Text,, Output
Gui, Add, Edit, y+3 -Wrap +HScroll R20 HwndhEdit1, % Format("{:81}", "")
ControlGetPos,,,W,,,ahk_id %hEdit1%
Gui, Add, Text,, Command Line
Gui, Add, Edit, y+3 -Wrap HwndhEdit2 w%W%, Dir
Gui, Add, Button, x+0 w0 h0 Default gRunCMD, <F2> RunCMD
Gui, Add, StatusBar
SB_SetParts(200,200), SB_SetText("`t<Esc> Cancel/Clear", 1),  SB_SetText("`t<Enter> RunCMD", 2)
GuiControl,, Edit1
Gui, Show,, RunCMD() - Realtime per line streaming demo 


RunCMD:
  SB_SetText("", 3)
  GuiControlGet, Cmd,, %hEdit2%
  GuiControl, Disable, Button1
  ExitCode := RunCMD(A_Comspec . " /c " . Cmd)
  SB_SetText("`tExitCode : " ErrorLevel, 3)
  GuiControl, Enable, Button1
  Edit_Append(hEdit2,"")
  GuiControl, Focus,Edit2
Return                                                            ; end of auto-execute section 



#IfWinActive RunCMD() ahk_class AutoHotkeyGUI
  Esc::
    GuiControl, Focus,Edit2
    Edit_Append(hEdit2,"")
    If (A_Args.RunCMD.PID)
      {
        A_Args.RunCMD.PID := 0
        Return
      }  
    SB_SetText("", 3)
    GuiControl,,Edit1
    GuiControl,,Edit2
  Return
#IfWinActive



RunCmd_Output(Line, LineNum) {
Global 
  If ( SubStr(Line,-1)!="`r`n" )
    Line .= "`r`n"
  Edit_Append(hEdit1, Line)
}


Edit_Append(hEdit, Txt) { ; Modified version by SKAN
Local        ; Original by TheGood on 09-Apr-2010 @ autohotkey.com/board/topic/52441-/?p=328342
  L := DllCall("SendMessage", "Ptr",hEdit, "UInt",0x0E, "Ptr",0 , "Ptr",0)   ; WM_GETTEXTLENGTH
       DllCall("SendMessage", "Ptr",hEdit, "UInt",0xB1, "Ptr",L , "Ptr",L)   ; EM_SETSEL
       DllCall("SendMessage", "Ptr",hEdit, "UInt",0xC2, "Ptr",0 , "Str",Txt) ; EM_REPLACESEL
}


RunCMD(CmdLine, WorkingDir:="", Codepage:="CP0", Fn:="RunCMD_Output", Slow:=1) {
  Local
  Global A_Args

  Slow := !! Slow
  , Fn := IsFunc(Fn) ? Func(Fn) : 0
  , DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "Int",0)
  , DllCall("SetHandleInformation", "Ptr",hPipeW, "Int",1, "Int",1)
  , DllCall("SetNamedPipeHandleState","Ptr",hPipeR, "UIntP",PIPE_NOWAIT:=1, "Ptr",0, "Ptr",0)
  , P8 := (A_PtrSize=8)
  , VarSetCapacity(SI, P8 ? 104 : 68, 0)
  , NumPut(P8 ? 104 : 68, SI)
  , NumPut(STARTF_USESTDHANDLES:=0x100, SI, P8 ? 60 : 44,"UInt")
  , NumPut(hPipeW, SI, P8 ? 88 : 60)
  , NumPut(hPipeW, SI, P8 ? 96 : 64)
  , VarSetCapacity(PI, P8 ? 24 : 16)

  If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "Int",0, "Int",True,"Int",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1, "UInt"), "Int",0,"Ptr",WorkingDir ? &WorkingDir : 0, "Ptr",&SI, "Ptr",&PI)
    Return Format("{1:}", "", ErrorLevel := -1, DllCall("CloseHandle", "Ptr",hPipeW), DllCall("CloseHandle", "Ptr",hPipeR))

  DllCall("CloseHandle", "Ptr",hPipeW)
  , A_Args.RunCMD := { "PID": NumGet(PI, P8? 16 : 8, "UInt") }
  , File := FileOpen(hPipeR, "h", Codepage)

  , LineNum := 1, sOutput := ""
  While ( A_Args.RunCMD.PID | DllCall("Sleep", "Int",Slow) ) and DllCall("PeekNamedPipe", "Ptr",hPipeR, "Ptr",0, "Int",0, "Ptr",0, "Ptr",0, "Ptr",0)
    While A_Args.RunCMD.PID and StrLen(Line := File.ReadLine())
      sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line

  A_Args.RunCMD.PID := 0
  , hProcess := NumGet(PI, 0)
  , hThread := NumGet(PI, A_PtrSize)

  , DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0)
  , DllCall("CloseHandle", "Ptr",hProcess)
  , DllCall("CloseHandle", "Ptr",hThread)
  , DllCall("CloseHandle", "Ptr",hPipeR)
  , ErrorLevel := ExitCode

  Return sOutput
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。