2013-07-09 43 views
1

我目前正在研究一个程序,该程序采用计算机名称列表,在相关计算机上运行一系列命令提示符查询,然后将信息导出到Excel文件中。因此,举例来说,我的节目贯穿CMD命令:将CLI输出导出到Excel

wmic /node:COMPUTERNAME /user:USER /password:PASSWORD cpu get name 

,这会返回给定的计算机CPU名称/速度,等我快到的问题是,我可以将其导出到一个新的文本文件,然后拉入标题,所以,而不是只是返回“英特尔酷睿2双核2.66GHz”,它返回这个。

 
Name 
Intel Core 2 Duo 2.66 GHz 

但是,我会不会导出这个出来excel,而不是一个文本文件。但是,当我为多台计算机执行此操作时,它会将所有内容导出为一个单元格,而不是将数据解析出来。

所以我的问题是:使用命令提示符,有无论如何发送或解析出数据到一个excel文件,有没有办法这样做,只是拉特定的信息,你指定?

+1

你是如何在一个单元格中完成的? – stenci

+3

如何将其导出为CSV? – chancea

回答

0

您可以使用此VBA代码在您的CLI命令的excel单元中运行,并将结果作为每个单元格的值返回。 exemple

Function CMD(commande As String) 
    CMD = GetCommandOutput(commande) 
End Function 

在其他模块添加此

'Attribute VB_Name = "CmdOutput" 
Option Explicit 
'''''''''''''''''''''''''''''''''''''''' 
' Joacim Andersson, Brixoft Software 
' http://www.brixoft.net 
'''''''''''''''''''''''''''''''''''''''' 

' STARTUPINFO flags 
Private Const STARTF_USESHOWWINDOW = &H1 
Private Const STARTF_USESTDHANDLES = &H100 

' ShowWindow flags 
Private Const SW_HIDE = 0 

' DuplicateHandle flags 
Private Const DUPLICATE_CLOSE_SOURCE = &H1 
Private Const DUPLICATE_SAME_ACCESS = &H2 

' Error codes 
Private Const ERROR_BROKEN_PIPE = 109 

Private Type SECURITY_ATTRIBUTES 
    nLength As Long 
    lpSecurityDescriptor As Long 
    bInheritHandle As Long 
End Type 

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 Type 

Private Type PROCESS_INFORMATION 
    hProcess As Long 
    hThread As Long 
    dwProcessId As Long 
    dwThreadId As Long 
End Type 

Private Declare Function CreatePipe _ 
Lib "kernel32" (_ 
phReadPipe As Long, _ 
phWritePipe As Long, _ 
lpPipeAttributes As Any, _ 
ByVal nSize As Long) 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 CreateProcess _ 
Lib "kernel32" Alias "CreateProcessA" (_ 
ByVal lpApplicationName As String, _ 
ByVal lpCommandLine As String, _ 
lpProcessAttributes As Any, _ 
lpThreadAttributes As Any, _ 
ByVal bInheritHandles As Long, _ 
ByVal dwCreationFlags As Long, _ 
lpEnvironment As Any, _ 
ByVal lpCurrentDriectory As String, _ 
lpStartupInfo As STARTUPINFO, _ 
lpProcessInformation As PROCESS_INFORMATION) As Long 

Private Declare Function GetCurrentProcess _ 
Lib "kernel32"() As Long 

Private Declare Function DuplicateHandle _ 
Lib "kernel32" (_ 
ByVal hSourceProcessHandle As Long, _ 
ByVal hSourceHandle As Long, _ 
ByVal hTargetProcessHandle As Long, _ 
lpTargetHandle As Long, _ 
ByVal dwDesiredAccess As Long, _ 
ByVal bInheritHandle As Long, _ 
ByVal dwOptions As Long) As Long 

Private Declare Function CloseHandle _ 
Lib "kernel32" (_ 
ByVal hObject As Long) As Long 

Private Declare Function OemToCharBuff _ 
Lib "user32" Alias "OemToCharBuffA" (_ 
lpszSrc As Any, _ 
ByVal lpszDst As String, _ 
ByVal cchDstLength As Long) As Long 

' Function GetCommandOutput 
' 
' sCommandLine: [in] Command line to launch 
' blnStdOut  [in,opt] True (defualt) to capture output to STDOUT 
' blnStdErr  [in,opt] True to capture output to STDERR. False is default. 
' blnOEMConvert: [in,opt] True (default) to convert DOS characters to Windows, False to skip conversion 
' 
' Returns:  String with STDOUT and/or STDERR output 
' 
Public Function GetCommandOutput(sCommandLine As String, _ 
Optional blnStdOut As Boolean = True, _ 
Optional blnStdErr As Boolean = False, _ 
Optional blnOEMConvert As Boolean = True _ 
) As String 

    Dim hPipeRead As Long, hPipeWrite1 As Long, hPipeWrite2 As Long 
    Dim hCurProcess As Long 
    Dim sa As SECURITY_ATTRIBUTES 
    Dim si As STARTUPINFO 
    Dim pi As PROCESS_INFORMATION 
    Dim baOutput() As Byte 
    Dim sNewOutput As String 
    Dim lBytesRead As Long 
    Dim fTwoHandles As Boolean 

    Dim lRet As Long 
    Dim endTime As Date 


    Const BUFSIZE = 1024  ' pipe buffer size 

    endTime = Now + TimeValue("00:00:05") 

    ' At least one of them should be True, otherwise there's no point in calling the function 
    If (Not blnStdOut) And (Not blnStdErr) Then 
     Err.Raise 5   ' Invalid Procedure call or Argument 
    End If 

    ' If both are true, we need two write handles. If not, one is enough. 
    fTwoHandles = blnStdOut And blnStdErr 

    ReDim baOutput(BUFSIZE - 1) As Byte 

    With sa 
     .nLength = Len(sa) 
     .bInheritHandle = 1 ' get inheritable pipe handles 
    End With 

    If CreatePipe(hPipeRead, hPipeWrite1, sa, BUFSIZE) = 0 Then 
     Exit Function 
    End If 

    hCurProcess = GetCurrentProcess() 

    ' Replace our inheritable read handle with an non-inheritable. Not that it 
    ' seems to be necessary in this case, but the docs say we should. 
    Call DuplicateHandle(hCurProcess, hPipeRead, hCurProcess, hPipeRead, 0&, _ 
         0&, DUPLICATE_SAME_ACCESS Or DUPLICATE_CLOSE_SOURCE) 

    ' If both STDOUT and STDERR should be redirected, get an extra handle. 
    If fTwoHandles Then 
     Call DuplicateHandle(hCurProcess, hPipeWrite1, hCurProcess, hPipeWrite2, 0&, _ 
          1&, DUPLICATE_SAME_ACCESS) 
    End If 

    With si 
     .cb = Len(si) 
     .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES 
     .wShowWindow = SW_HIDE   ' hide the window 

     If fTwoHandles Then 
      .hStdOutput = hPipeWrite1 
      .hStdError = hPipeWrite2 
     ElseIf blnStdOut Then 
      .hStdOutput = hPipeWrite1 
     Else 
      .hStdError = hPipeWrite1 
     End If 
    End With 

    If CreateProcess(vbNullString, sCommandLine, ByVal 0&, ByVal 0&, 1, 0&, _ 
    ByVal 0&, vbNullString, si, pi) Then 

     ' Close thread handle - we don't need it 
     Call CloseHandle(pi.hThread) 

     ' Also close our handle(s) to the write end of the pipe. This is important, since 
     ' ReadFile will *not* return until all write handles are closed or the buffer is full. 
     Call CloseHandle(hPipeWrite1) 
     hPipeWrite1 = 0 
     If hPipeWrite2 Then 
      Call CloseHandle(hPipeWrite2) 
      hPipeWrite2 = 0 
     End If 

     Do 
      ' Add a DoEvents to allow more data to be written to the buffer for each call. 
      ' This results in fewer, larger chunks to be read. 
      'DoEvents 

      If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then 
       Exit Do 
      End If 

      If Now > endTime Then 
       GetCommandOutput = GetCommandOutput & "CMD(""TimeOut"")" 
       Exit Do 
      End If 

      If blnOEMConvert Then 
       ' convert from "DOS" to "Windows" characters 
       sNewOutput = String$(lBytesRead, 0) 
       Call OemToCharBuff(baOutput(0), sNewOutput, lBytesRead) 
      Else 
       ' perform no conversion (except to Unicode) 
       sNewOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead) 
      End If 

      GetCommandOutput = GetCommandOutput & sNewOutput 

      ' If you are executing an application that outputs data during a long time, 
      ' and don't want to lock up your application, it might be a better idea to 
      ' wrap this code in a class module in an ActiveX EXE and execute it asynchronously. 
      ' Then you can raise an event here each time more data is available. 
      'RaiseEvent OutputAvailabele(sNewOutput) 
     Loop 

     ' When the process terminates successfully, Err.LastDllError will be 
     ' ERROR_BROKEN_PIPE (109). Other values indicates an error. 

     Call CloseHandle(pi.hProcess) 
    Else 
     GetCommandOutput = "Failed to create process, check the path of the command line." 
    End If 

    ' clean up 
    Call CloseHandle(hPipeRead) 
    If hPipeWrite1 Then 
     Call CloseHandle(hPipeWrite1) 
    End If 
    If hPipeWrite2 Then 
     Call CloseHandle(hPipeWrite2) 
    End If 
End Function 
0

wmic可以创建CSV输出,这是Excel识别的文本格式:

wmic /node:HOST /user:USER /password:PASS /output:C:\path\to\output.csv cpu get name /format:CSV 

你需要为这个管理权限,不过,否则你会得到这样的错误:

无效的XSL格式(或)文件名。