Advertisement
Guest User

Capture output value shell command in VBA-2

a guest
Dec 21st, 2023
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 11.07 KB | None | 0 0
  1. Option Explicit
  2.  
  3. 'Declaring the necessary API functions and types based on Excel version.
  4. #If Win64 Then
  5.    
  6.     'For 64 bit Excel.
  7.     'Creates an anonymous pipe, and returns handles to the read and write ends of the pipe.
  8.     Public Declare PtrSafe Function CreatePipe Lib "kernel32" (phReadPipe As LongPtr, _
  9.                                                                 phWritePipe As LongPtr, _
  10.                                                                 lpPipeAttributes As Any, _
  11.                                                                 ByVal nSize As Long) As Long
  12.    
  13.     'Reads data from the specified file or input/output (I/O) device. Reads occur at the position specified by the file pointer if supported by the device.
  14.     Public Declare PtrSafe Function ReadFile Lib "kernel32" (ByVal hFile As LongPtr, _
  15.                                                              lpBuffer As Any, _
  16.                                                              ByVal nNumberOfBytesToRead As Long, _
  17.                                                              lpNumberOfBytesRead As Long, _
  18.                                                              lpOverlapped As Any) As Long
  19.    
  20.     'Creates a new process and its primary thread. The new process runs in the security context of the calling process.
  21.     Public Declare PtrSafe Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, _
  22.                                                                                          ByVal lpCommandLine As String, _
  23.                                                                                          lpProcessAttributes As Any, _
  24.                                                                                          lpThreadAttributes As Any, _
  25.                                                                                          ByVal bInheritHandles As Long, _
  26.                                                                                          ByVal dwCreationFlags As Long, _
  27.                                                                                          lpEnvironment As Any, _
  28.                                                                                          ByVal lpCurrentDriectory As String, _
  29.                                                                                          lpStartupInfo As STARTUPINFO, _
  30.                                                                                          lpProcessInformation As PROCESS_INFORMATION) As Long
  31.    
  32.     'Closes an open object handle.
  33.     Public Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As LongPtr) As Long
  34.    
  35.     'Contains the security descriptor for an object and specifies whether the handle retrieved by specifying this structure is inheritable.
  36.     Public Type SECURITY_ATTRIBUTES
  37.         nLength                 As Long
  38.         lpSecurityDescriptor    As LongPtr
  39.         bInheritHandle          As Long
  40.     End Type
  41.    
  42.     'Specifies the window station, desktop, standard handles, and appearance of the main window for a process at creation time.
  43.     Public Type STARTUPINFO
  44.         cb                  As Long
  45.         lpReserved          As String
  46.         lpDesktop           As String
  47.         lpTitle             As String
  48.         dwX                 As Long
  49.         dwY                 As Long
  50.         dwXSize             As Long
  51.         dwYSize             As Long
  52.         dwXCountChars       As Long
  53.         dwYCountChars       As Long
  54.         dwFillAttribute     As Long
  55.         dwFlags             As Long
  56.         wShowWindow         As Integer
  57.         cbReserved2         As Integer
  58.         lpReserved2         As LongPtr
  59.         hStdInput           As LongPtr
  60.         hStdOutput          As LongPtr
  61.         hStdError           As LongPtr
  62.     End Type
  63.    
  64.     'Contains information about a newly created process and its primary thread.
  65.     Public Type PROCESS_INFORMATION
  66.         hProcess        As LongPtr
  67.         hThread         As LongPtr
  68.         dwProcessId     As Long
  69.         dwThreadId      As Long
  70.     End Type
  71.                                    
  72. #Else
  73.  
  74.     'For 32 bit Excel.
  75.     Public Declare Function CreatePipe Lib "kernel32" (phReadPipe As Long, _
  76.                                                        phWritePipe As Long, _
  77.                                                        lpPipeAttributes As Any, _
  78.                                                        ByVal nSize As Long) As Long
  79.                                                        
  80.     Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, _
  81.                                                      lpBuffer As Any, _
  82.                                                      ByVal nNumberOfBytesToRead As Long, _
  83.                                                      lpNumberOfBytesRead As Long, _
  84.                                                      lpOverlapped As Any) As Long
  85.                                                      
  86.     Public Declare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String, _
  87.                                                                                  ByVal lpCommandLine As String, _
  88.                                                                                  lpProcessAttributes As Any, _
  89.                                                                                  lpThreadAttributes As Any, _
  90.                                                                                  ByVal bInheritHandles As Long, _
  91.                                                                                  ByVal dwCreationFlags As Long, _
  92.                                                                                  lpEnvironment As Any, _
  93.                                                                                  ByVal lpCurrentDriectory As String, _
  94.                                                                                  lpStartupInfo As STARTUPINFO, _
  95.                                                                                  lpProcessInformation As PROCESS_INFORMATION) As Long
  96.                                                                                  
  97.     Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
  98.    
  99.     'Types.
  100.     Public Type SECURITY_ATTRIBUTES
  101.         nLength                                As Long
  102.         lpSecurityDescriptor                   As Long
  103.         bInheritHandle                         As Long
  104.     End Type
  105.  
  106.     Public Type STARTUPINFO
  107.         cb                                     As Long
  108.         lpReserved                             As String
  109.         lpDesktop                              As String
  110.         lpTitle                                As String
  111.         dwX                                    As Long
  112.         dwY                                    As Long
  113.         dwXSize                                As Long
  114.         dwYSize                                As Long
  115.         dwXCountChars                          As Long
  116.         dwYCountChars                          As Long
  117.         dwFillAttribute                        As Long
  118.         dwFlags                                As Long
  119.         wShowWindow                            As Integer
  120.         cbReserved2                            As Integer
  121.         lpReserved2                            As Long
  122.         hStdInput                              As Long
  123.         hStdOutput                             As Long
  124.         hStdError                              As Long
  125.     End Type
  126.    
  127.     Public Type PROCESS_INFORMATION
  128.         hProcess                               As Long
  129.         hThread                                As Long
  130.         dwProcessId                            As Long
  131.         dwThreadId                             As Long
  132.     End Type
  133.    
  134. #End If
  135.  
  136. 'Contants.
  137. Public Const STARTF_USESHOWWINDOW  As Long = &H1
  138. Public Const STARTF_USESTDHANDLES  As Long = &H100
  139. Public Const SW_HIDE               As Integer = 0
  140. Public Const BUFSIZE               As Long = 1024 * 10
  141.  
  142. Public Function ExecuteAndCapture(ByVal CommandLine As String, Optional ByVal StartInFolder As String = vbNullString) As String
  143.  
  144.     '------------------------------------------------------------------------------------
  145.     'Runs a console application (with a hidden window) and returns its output as string.
  146.     'First it creates a pipe and executes the console application, telling it
  147.     'to send the output and (any) error information to the pipe.
  148.     'Then, it reads from the pipe until there is no output left to read.
  149.        
  150.     'Written By:    Christos Samaras
  151.     'Date:          17/09/2017
  152.     'Last Updated:  26/01/2020
  153.     'E-mail:        xristos.samaras@gmail.com
  154.     'Site:          https://www.myengineeringworld.net
  155.     '------------------------------------------------------------------------------------
  156.  
  157.     'Declaring the necessary variables (different for 32 or 64 bit Excel).
  158.     #If Win64 Then
  159.         Dim hPipeRead       As LongPtr
  160.         Dim hPipeWrite      As LongPtr
  161.     #Else
  162.         Dim hPipeRead       As Long
  163.         Dim hPipeWrite      As Long
  164.     #End If
  165.    
  166.     'Declaring the rest variables.
  167.     Dim sa                  As SECURITY_ATTRIBUTES
  168.     Dim si                  As STARTUPINFO
  169.     Dim pi                  As PROCESS_INFORMATION
  170.     Dim baOutput(BUFSIZE)   As Byte
  171.     Dim sOutput             As String
  172.     Dim sTemp               As String
  173.     Dim lBytesRead          As Long
  174.    
  175.     'Set the security attributes.
  176.     With sa
  177.         .nLength = Len(sa)
  178.         .bInheritHandle = 1
  179.     End With
  180.    
  181.     'Create the pipe.
  182.     If CreatePipe(hPipeRead, hPipeWrite, sa, 0) = 0 Then
  183.         Exit Function
  184.     End If
  185.    
  186.     'Set the startup information.
  187.     With si
  188.         .cb = Len(si)
  189.         .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
  190.         .wShowWindow = SW_HIDE
  191.         .hStdOutput = hPipeWrite
  192.         .hStdError = hPipeWrite
  193.     End With
  194.    
  195.     'Create the process and run the console application.
  196.     If CreateProcess(vbNullString, CommandLine, ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&, StartInFolder, si, pi) Then
  197.        
  198.         Call CloseHandle(hPipeWrite)
  199.         Call CloseHandle(pi.hThread)
  200.         hPipeWrite = 0
  201.        
  202.         Do
  203.             'Wait.
  204.             DoEvents
  205.            
  206.             'If all the information is read from the pipe, then exit.
  207.             If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then
  208.                 Exit Do
  209.             End If
  210.            
  211.             'Pass the inforrmation to a variable.
  212.             sOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
  213.             If sOutput <> vbNullString Then sTemp = sTemp & sOutput
  214.            
  215.         Loop
  216.        
  217.         'Close the handle to the process.
  218.         Call CloseHandle(pi.hProcess)
  219.        
  220.     End If
  221.    
  222.     'Close the handle to the pipe.
  223.     Call CloseHandle(hPipeRead)
  224.     Call CloseHandle(hPipeWrite)
  225.    
  226.     'Return the output.
  227.     ExecuteAndCapture = sTemp
  228.    
  229. End Function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement