1 #Region "Microsoft.VisualBasic::c21444f9fdd16531295d9549501357c7, Microsoft.VisualBasic.Core\CommandLine\CLI\ProcExtensions.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Module ProcessExtensions
35     
36     '         Function: FindProc, (+2 OverloadsGetProc
37     '         Delegate Sub
38     
39     '             Function: [Call]
40     
41     '             Sub: ExecSub
42     
43     
44     
45     ' /********************************************************************************/
46
47 #End Region
48
49 Imports System.IO
50 Imports System.Runtime.CompilerServices
51 Imports Microsoft.VisualBasic.Language
52 Imports Proc = System.Diagnostics.Process
53
54 Namespace CommandLine
55
56     ''' <summary>
57     ''' How to found the process by CLI
58     ''' </summary>
59     Public Module ProcessExtensions
60
61         ''' <summary>
62         ''' <see cref="Process.GetProcessById"/>
63         ''' </summary>
64         ''' <param name="pid"></param>
65         ''' <returns></returns>
66         ''' 
67         <MethodImpl(MethodImplOptions.AggressiveInlining)>
68         Public Function GetProc(pid As IntegerAs Process
69             Return Process.GetProcessById(pid)
70         End Function
71
72         ''' <summary>
73         ''' Get process by command line parameter.(按照命令行参数来获取进程实例)
74         ''' </summary>
75         ''' <param name="CLI"></param>
76         ''' <returns></returns>
77         <Extension> Public Function GetProc(CLI As StringAs Process
78             Dim CLICompared As CommandLine = CLI
79             Dim listProc As Process() = Proc.GetProcesses
80             Dim process = LinqAPI.DefaultFirst(Of Process) _
81  _
82                 () <= From proc As Process
83                       In listProc
84                       Let args = TryParse(proc.StartInfo.Arguments)
85                       Where CLITools.Equals(CLICompared, args)  ' 由于参数的顺序可能会有些不一样,所以不可以直接按照字符串比较来获取
86                       Select proc
87
88             Return process
89         End Function
90
91         ''' <summary>
92         ''' 这个主要是为了<see cref="IORedirectFile"/>对象进行相关进程的查找而设置的,
93         ''' 对于<see cref="IORedirect"/>而言则直接可以从其属性<see cref="IORedirect.ProcessInfo"/>之中获取相关的进程信息
94         ''' </summary>
95         ''' <param name="IO"></param>
96         ''' <returns></returns>
97         Public Function FindProc(IO As IIORedirectAbstract) As Process
98             Dim proc As Process = IO.CLIArguments.GetProc
99
100             If proc Is Nothing Then '空值说明进程还没有启动或者已经终止了,所以查找将不会查找到进程的信息
101                 Dim msg As String = String.Format(NoProcessFound, IO.ToString)
102                 Call VBDebugger.Warning(msg)
103             End If
104
105             Return proc
106         End Function
107
108         Const NoProcessFound As String = "Unable to found associated process {0}, it maybe haven't been started or already terminated."
109
110         Public Delegate Sub dReadLine(strLine As String)
111
112         ''' <summary>
113         ''' 执行CMD命令
114         ''' 
115         ''' Example:
116         ''' 
117         ''' ```vbnet
118         ''' Call excuteCommand("ipconfig""/all"AddressOf PrintMessage)
119         ''' ```
120         ''' </summary>
121         ''' <param name="app">命令</param>
122         ''' <param name="args">参数</param>
123         ''' <param name="onReadLine">行信息(委托)</param>
124         ''' <remarks>https://github.com/lishewen/LSWFramework/blob/master/LSWClassLib/CMD/CMDHelper.vb</remarks>
125         Public Sub ExecSub(app As String, args As String, onReadLine As dReadLine, Optional [in] As String = "")
126             Dim p As New Process
127             p.StartInfo = New ProcessStartInfo
128             p.StartInfo.FileName = app
129             p.StartInfo.Arguments = args
130             p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
131             p.StartInfo.RedirectStandardOutput = True
132             p.StartInfo.RedirectStandardInput = True
133             p.StartInfo.UseShellExecute = False
134             p.StartInfo.CreateNoWindow = True
135             p.Start()
136
137             Dim reader As StreamReader = p.StandardOutput
138             Dim line As String = reader.ReadLine
139
140             If Not String.IsNullOrEmpty([in]) Then
141                 Dim writer As StreamWriter = p.StandardInput
142                 Call writer.WriteLine([in])
143                 Call writer.Flush()
144             End If
145
146             While Not reader.EndOfStream
147                 onReadLine(line)
148                 line = reader.ReadLine()
149             End While
150
151             Call p.WaitForExit()
152         End Sub
153
154         ''' <summary>
155         ''' 
156         ''' </summary>
157         ''' <param name="app">The file path of the application to be called by its parent process.</param>
158         ''' <param name="args">CLI arguments</param>
159         ''' <returns></returns>
160         <Extension>
161         Public Function [Call](app As String, args As StringOptional [in] As String = ""As String
162             Dim STDout As New List(Of String)
163             Call ExecSub(app, args, AddressOf STDout.Add, [in])
164             Return STDout.JoinBy(vbCrLf)
165         End Function
166     End Module
167 End Namespace