SUMMARY Moderate: Requires basic macro, coding, and interoperability skills. This article describes and gives an example of how you can use the Shell() function in Access Basic to run intrinsic MS-DOS commands, such as Copy, Dir, Del, and so on. This article assumes that you are familiar with Access Basic and with creating Microsoft Access applications using the programming tools provided with Microsoft Access. For more information about Access Basic, please refer to the "Building Applications" manual. MORE INFORMATION The Shell() function in Access Basic requires that you specify a file that has an extension of .EXE, .COM, .BAT or .PIF. These file types are registered as executable applications in the listed locations in the following operating environments: Windows 3.x and Windows for Workgroups 3.x ------------------------------------------ Filename: WIN.INI Section: [windows] Item: Programs=com exe bat pif Windows NT 3.x ---------------------------------------------------------------------- Filename: REGEDT32.EXE Registry Key: HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows Value: Programs Type: REG_SZ Item: com exe bat pif cmd Using the Shell() function to run MS-DOS commands requires the use of the COMMAND.COM program. The COMMAND.COM program supports two optional parameters that you can use to run an intrinsic (or built in) MS-DOS function: COMMAND /C: This syntax runs a built in function, and then closes the MS-DOS session. COMMAND /K: This syntax runs a built in function and returns the MS-DOS command prompt. Example To create a sample application that demonstrates the use of these techniques, follow these steps: Create a module and type the following line in the Declarations section: Option Explicit Type the following two functions: Function ShellDOS_Exit() As Integer On Local Error Goto ShellDOS_Exit_Err Dim MyCommand As String Dim TaskId As Integer ' Create command string to show the contents of current ' directory. Upon completion the window closes. MyCommand = "COMMAND.COM /C DIR /P" TaskId = Shell(MyCommand, 1) ShellDOS_Exit = True ShellDOS_Exit_End: Exit Function ShellDOS_Exit_Err: MsgBox Error$ Resume ShellDOS_Exit_End End Function Function ShellDOS_Stay() As Integer On Local Error Goto ShellDOS_Stay_Err Dim MyCommand As String Dim TaskId As Integer ' Create command string to show the contents of current ' directory. Upon completion the window remain opens ' at the MS-DOS prompt. MyCommand = "COMMAND.COM /K DIR /P" TaskId = Shell(MyCommand, 1) ShellDOS_Stay = True ShellDOS_Stay_End: Exit Function ShellDOS_Stay_Err: MsgBox Error$ Resume ShellDOS_Stay_End End FunctionTo test the first function, type the following line in the Immediate window, and then press ENTER: ? ShellDOS_Exit()Note that the MS-DOS window displays the contents of the current directory (prompting you to press a key if the contents of the directory exceeds one display page) and returns True as a result of the function. To test the second function, type the following line in the Immediate window, and then press ENTER: ? ShellDOS_Stay()Note that the MS-DOS window displays the contents of the current directory (prompting you to press a key if the contents of the directory exceeds one display page) and then keeps the MS-DOS session open and active, displaying the MS-DOS command prompt. The function also returns True as a result.
11楼这个API声明有点问题,应该按下面这样声明,否则程序不能用。 在文本框txtCommand输入DOS命令,按回车后在文本框txtMessage中输出DOS窗口的内容。Option Explicit Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Long hStdInput As Long hStdOutput As Long hStdError As Long End TypePrivate Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End TypePrivate Declare Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByRef lpProcessAttributes As Any, ByRef lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByRef lpEnvironment As Any, ByVal lpCurrentDriectory As String, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Long Private Declare Function CloseHandle Lib "kernel32 " (ByVal hObject As Long) As Long Private Declare Function CreatePipe Lib "kernel32 " (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As Any, ByVal nSize As Long) As Long Private Declare Function WriteFile Lib "kernel32 " (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long Private Declare Function ReadFile Lib "kernel32 " (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long Private Declare Function SetHandleInformation Lib "kernel32 " (ByVal hObject As Long, ByVal dwMask As Long, ByVal dwFlags As Long) As Long Private Declare Function SetNamedPipeHandleState Lib "kernel32 " (ByVal hNamedPipe As Long, lpMode As Long, lpMaxCollectionCount As Long, lpCollectDataTimeout As Long) As Long Private Declare Sub Sleep Lib "kernel32 " (ByVal dwMilliseconds As Long)Private Const STARTF_USESTDHANDLES = &H100 Private Const HANDLE_FLAG_INHERIT = 1 Private Const DETACHED_PROCESS = &H8 Private Const PIPE_NOWAIT = &H1Dim hReadPipe As Long Dim hWritePipe As Long Dim hChildReadPipe As Long Dim hChildWritePipe As LongPrivate Sub Form_Load() txtCommand.Text = " " txtMessage.Text = " " txtMessage.Locked = True
' 创建CMD进程 Dim stProcessInfo As PROCESS_INFORMATION Dim stStartInfo As STARTUPINFO stStartInfo.cb = LenB(stStartInfo) stStartInfo.dwFlags = STARTF_USESTDHANDLES stStartInfo.hStdError = hWritePipe stStartInfo.hStdOutput = hWritePipe stStartInfo.hStdInput = hChildReadPipe
Dim strExe As String strExe = "cmd " If CreateProcess(ByVal vbNullString, ByVal strExe, ByVal 0, ByVal 0, ByVal True, ByVal DETACHED_PROCESS, ByVal 0, ByVal vbNullString, stStartInfo, stProcessInfo) = False Then MsgBox "启动进程失败! " Exit Sub Else CloseHandle stProcessInfo.hThread CloseHandle stProcessInfo.hProcess End If ReadFromChildPipe End SubPrivate Sub Form_Unload(Cancel As Integer) CloseHandle hReadPipe CloseHandle hWritePipe CloseHandle hChildReadPipe CloseHandle hChildWritePipe End SubPrivate Sub txtCommand_KeyPress(KeyAscii As Integer) If KeyAscii = vbKeyReturn Then Dim nWrite As Long Dim strBuffer As String strBuffer = txtCommand.Text & vbCrLf Dim bResult As Boolean bResult = WriteFile(ByVal hChildWritePipe, ByVal strBuffer, ByVal Len(strBuffer), nWrite, ByVal 0) If bResult = True Then ReadFromChildPipe Else MsgBox "写入失败. " End If txtCommand.Text = " " End If End SubPrivate Sub ReadFromChildPipe() Dim nRead As Long Dim strBuffer As String Dim nBufferLen As Long nRead = -1 Do While nRead <> 0 nBufferLen = 65536 strBuffer = String(nBufferLen, Chr(0)) Sleep 10 ReadFile hReadPipe, ByVal strBuffer, ByVal nBufferLen, nRead, ByVal 0 Sleep 10 If nRead <> 0 Then strBuffer = Left(strBuffer, nRead) txtMessage.Text = txtMessage.Text & strBuffer txtMessage.SelStart = Len(txtMessage.Text) End If Loop End Sub
例子:直接读取CMD的返回信息调用Ping检测网络状态 Dim strTarget As String Dim strPingResults As String Dim objWShell As Object Dim objWExec As Object strTarget = "www.google.com" 'IP address or hostname Set objWShell = CreateObject("WScript.Shell") Set objWExec = objWShell.Exec("ping -n 3 -w 1000 " & strTarget) DoEvents strPingResults = LCase(objWExec.StdOut.ReadAll) If InStr(strPingResults, "reply from ") Then MsgBox "已经联网" Else MsgBox "请检查网络连接设置" End If
cmd写一句,你可能要调N*2+1行的代码
Moderate: Requires basic macro, coding, and interoperability skills. This article describes and gives an example of how you can use the Shell() function in Access Basic to run intrinsic MS-DOS commands, such as Copy, Dir, Del, and so on. This article assumes that you are familiar with Access Basic and with creating Microsoft Access applications using the programming tools provided with Microsoft Access. For more information about Access Basic, please refer to the "Building Applications" manual. MORE INFORMATION
The Shell() function in Access Basic requires that you specify a file that has an extension of .EXE, .COM, .BAT or .PIF. These file types are registered as executable applications in the listed locations in the following operating environments:
Windows 3.x and Windows for Workgroups 3.x
------------------------------------------
Filename: WIN.INI
Section: [windows]
Item: Programs=com exe bat pif Windows NT 3.x
----------------------------------------------------------------------
Filename: REGEDT32.EXE
Registry Key:
HKEY_CURRENT_USER\Software\Microsoft\WindowsNT\CurrentVersion\Windows
Value: Programs
Type: REG_SZ
Item: com exe bat pif cmd
Using the Shell() function to run MS-DOS commands requires the use of the COMMAND.COM program. The COMMAND.COM program supports two optional parameters that you can use to run an intrinsic (or built in) MS-DOS function:
COMMAND /C: This syntax runs a built in function, and then closes
the MS-DOS session.
COMMAND /K: This syntax runs a built in function and returns the
MS-DOS command prompt.
Example
To create a sample application that demonstrates the use of these techniques, follow these steps:
Create a module and type the following line in the Declarations section:
Option Explicit
Type the following two functions:
Function ShellDOS_Exit() As Integer
On Local Error Goto ShellDOS_Exit_Err
Dim MyCommand As String
Dim TaskId As Integer
' Create command string to show the contents of current
' directory. Upon completion the window closes.
MyCommand = "COMMAND.COM /C DIR /P"
TaskId = Shell(MyCommand, 1)
ShellDOS_Exit = True
ShellDOS_Exit_End:
Exit Function
ShellDOS_Exit_Err:
MsgBox Error$
Resume ShellDOS_Exit_End
End Function Function ShellDOS_Stay() As Integer
On Local Error Goto ShellDOS_Stay_Err
Dim MyCommand As String
Dim TaskId As Integer
' Create command string to show the contents of current
' directory. Upon completion the window remain opens
' at the MS-DOS prompt.
MyCommand = "COMMAND.COM /K DIR /P"
TaskId = Shell(MyCommand, 1)
ShellDOS_Stay = True
ShellDOS_Stay_End:
Exit Function
ShellDOS_Stay_Err:
MsgBox Error$
Resume ShellDOS_Stay_End
End FunctionTo test the first function, type the following line in the Immediate window, and then press ENTER:
? ShellDOS_Exit()Note that the MS-DOS window displays the contents of the current directory (prompting you to press a key if the contents of the directory exceeds one display page) and returns True as a result of the function.
To test the second function, type the following line in the Immediate window, and then press ENTER:
? ShellDOS_Stay()Note that the MS-DOS window displays the contents of the current directory (prompting you to press a key if the contents of the directory exceeds one display page) and then keeps the MS-DOS session open and active, displaying the MS-DOS command prompt. The function also returns True as a result.
可以利用管道技术,VB可以执行DOS命令并显示DOS窗口(CMD命令窗口)的内容!
在文本框txtCommand输入DOS命令,按回车后在文本框txtMessage中输出DOS窗口的内容。Option Explicit
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End TypePrivate Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End TypePrivate Declare Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByRef lpProcessAttributes As Any, ByRef lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByRef lpEnvironment As Any, ByVal lpCurrentDriectory As String, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32 " (ByVal hObject As Long) As Long
Private Declare Function CreatePipe Lib "kernel32 " (phReadPipe As Long, phWritePipe As Long, lpPipeAttributes As Any, ByVal nSize As Long) As Long
Private Declare Function WriteFile Lib "kernel32 " (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
Private Declare Function ReadFile Lib "kernel32 " (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Private Declare Function SetHandleInformation Lib "kernel32 " (ByVal hObject As Long, ByVal dwMask As Long, ByVal dwFlags As Long) As Long
Private Declare Function SetNamedPipeHandleState Lib "kernel32 " (ByVal hNamedPipe As Long, lpMode As Long, lpMaxCollectionCount As Long, lpCollectDataTimeout As Long) As Long
Private Declare Sub Sleep Lib "kernel32 " (ByVal dwMilliseconds As Long)Private Const STARTF_USESTDHANDLES = &H100
Private Const HANDLE_FLAG_INHERIT = 1
Private Const DETACHED_PROCESS = &H8
Private Const PIPE_NOWAIT = &H1Dim hReadPipe As Long
Dim hWritePipe As Long
Dim hChildReadPipe As Long
Dim hChildWritePipe As LongPrivate Sub Form_Load()
txtCommand.Text = " "
txtMessage.Text = " "
txtMessage.Locked = True
' 创建管道
CreatePipe hReadPipe, hWritePipe, ByVal 0, ByVal 0
CreatePipe hChildReadPipe, hChildWritePipe, ByVal 0, ByVal 0
SetHandleInformation hWritePipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT
SetHandleInformation hChildReadPipe, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT
Dim dwMode As Long
dwMode = PIPE_NOWAIT
SetNamedPipeHandleState hReadPipe, dwMode, ByVal 0, ByVal 0
' 创建CMD进程
Dim stProcessInfo As PROCESS_INFORMATION
Dim stStartInfo As STARTUPINFO
stStartInfo.cb = LenB(stStartInfo)
stStartInfo.dwFlags = STARTF_USESTDHANDLES
stStartInfo.hStdError = hWritePipe
stStartInfo.hStdOutput = hWritePipe
stStartInfo.hStdInput = hChildReadPipe
Dim strExe As String
strExe = "cmd "
If CreateProcess(ByVal vbNullString, ByVal strExe, ByVal 0, ByVal 0, ByVal True, ByVal DETACHED_PROCESS, ByVal 0, ByVal vbNullString, stStartInfo, stProcessInfo) = False Then
MsgBox "启动进程失败! "
Exit Sub
Else
CloseHandle stProcessInfo.hThread
CloseHandle stProcessInfo.hProcess
End If
ReadFromChildPipe
End SubPrivate Sub Form_Unload(Cancel As Integer)
CloseHandle hReadPipe
CloseHandle hWritePipe
CloseHandle hChildReadPipe
CloseHandle hChildWritePipe
End SubPrivate Sub txtCommand_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
Dim nWrite As Long
Dim strBuffer As String
strBuffer = txtCommand.Text & vbCrLf
Dim bResult As Boolean
bResult = WriteFile(ByVal hChildWritePipe, ByVal strBuffer, ByVal Len(strBuffer), nWrite, ByVal 0)
If bResult = True Then
ReadFromChildPipe
Else
MsgBox "写入失败. "
End If
txtCommand.Text = " "
End If
End SubPrivate Sub ReadFromChildPipe()
Dim nRead As Long
Dim strBuffer As String
Dim nBufferLen As Long
nRead = -1
Do While nRead <> 0
nBufferLen = 65536
strBuffer = String(nBufferLen, Chr(0))
Sleep 10
ReadFile hReadPipe, ByVal strBuffer, ByVal nBufferLen, nRead, ByVal 0
Sleep 10
If nRead <> 0 Then
strBuffer = Left(strBuffer, nRead)
txtMessage.Text = txtMessage.Text & strBuffer
txtMessage.SelStart = Len(txtMessage.Text)
End If
Loop
End Sub
'读文件c:\exefiles.txt的内容
Dim strPingResults As String
Dim objWShell As Object
Dim objWExec As Object
strTarget = "www.google.com" 'IP address or hostname
Set objWShell = CreateObject("WScript.Shell")
Set objWExec = objWShell.Exec("ping -n 3 -w 1000 " & strTarget)
DoEvents
strPingResults = LCase(objWExec.StdOut.ReadAll)
If InStr(strPingResults, "reply from ") Then
MsgBox "已经联网"
Else
MsgBox "请检查网络连接设置"
End If