1 #Region "Microsoft.VisualBasic::ddae0b72912f83cfa8aec30722a11992, Microsoft.VisualBasic.Core\CommandLine\InteropService\Abstract.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     '     Class InteropService
35     
36     '         Properties: IORedirect, IsAvailable, Path
37     
38     '         Constructor: (+2 OverloadsSub New
39     '         FunctionGetLastCLRException, GetLastError, RunDotNetApp, RunProgram, ToString
40     
41     '     Class CLIBuilder
42     
43     '         FunctionToString
44     
45     
46     ' /********************************************************************************/
47
48 #End Region
49
50 Imports System.Runtime.CompilerServices
51 Imports System.Text.RegularExpressions
52 Imports Microsoft.VisualBasic.ApplicationServices.Debugging.Diagnostics
53 Imports Microsoft.VisualBasic.Language
54 Imports Microsoft.VisualBasic.Text
55
56 Namespace CommandLine.InteropService
57
58     ''' <summary>
59     ''' The class object which can interact with the target commandline program.
60     ''' (与目标命令行程序进行命令行交互的编程接口,本类型的对象的作用主要是生成命令行参数)
61     ''' </summary>
62     ''' <remarks></remarks>
63     Public Class InteropService : Inherits CLIBuilder
64
65         ''' <summary>
66         ''' App path
67         ''' </summary>
68         ''' <returns></returns>
69         Public ReadOnly Property Path As String
70             <MethodImpl(MethodImplOptions.AggressiveInlining)>
71             Get
72                 Return _executableAssembly
73             End Get
74         End Property
75
76         ''' <summary>
77         ''' 这个只读属性返回目标可执行文件是否有效
78         ''' </summary>
79         ''' <returns></returns>
80         Public ReadOnly Property IsAvailable As Boolean
81             <MethodImpl(MethodImplOptions.AggressiveInlining)>
82             Get
83                 Return _executableAssembly.FileExists
84             End Get
85         End Property
86
87         ''' <summary>
88         ''' 默认是不做IO重定向的
89         ''' </summary>
90         ''' <returns></returns>
91         Public Property IORedirect As Boolean = False
92
93         Sub New()
94         End Sub
95
96         ''' <summary>
97         ''' 通过应用程序的可执行文件路径来构建命令行的交互对象
98         ''' </summary>
99         ''' <param name="app"></param>
100         Sub New(app As String)
101             _executableAssembly = app
102         End Sub
103
104         ''' <summary>
105         ''' Assembly path for the target invoked program.
106         ''' </summary>
107         ''' <remarks></remarks>
108         Protected Friend _executableAssembly As String
109
110         Dim lastProc As IIORedirectAbstract
111
112         Public Function RunDotNetApp(args$) As IIORedirectAbstract
113             lastProc = App.Shell(_executableAssembly, args, CLR:=True)
114             Return lastProc
115         End Function
116
117         ''' <summary>
118         ''' 线程不安全
119         ''' </summary>
120         ''' <returns></returns>
121         <MethodImpl(MethodImplOptions.AggressiveInlining)>
122         Public Function GetLastCLRException() As ExceptionData
123             Return GetLastError(lastProc)
124         End Function
125
126         Public Shared Function GetLastError(proc As IIORedirectAbstract) As ExceptionData
127             Dim out$ = proc?.StandardOutput Or EmptyString
128             Dim err$ = out _
129                 .Match("^\[INFOM .+?\] \[Log\].+$", RegexOptions.Multiline) _
130                 .StringReplace("\[.+?\] \[Log\]\s+""") _
131                 .Trim(" "c, ASCII.TAB, ASCII.CR, ASCII.LF)
132             Dim logs As List(Of String()) = err _
133                 .ReadAllText(throwEx:=False, suppress:=True) _
134                 .LineTokens _
135                 .FlagSplit(Function(s) s.IsPattern("[=]+")) _
136                 .AsList
137
138             If logs.IsNullOrEmpty Then
139                 Return Nothing
140             End If
141
142             Dim typeINF = logs(-3).Where(Function(s) Not s.StringEmpty).First.Trim(":"c)
143             Dim message = logs(-2).Where(Function(s) Not s.StringEmpty).Select(Function(s) Mid(s, 9).Trim).ToArray
144             Dim tracess = logs(-1).Where(Function(s) Not s.StringEmpty).Select(Function(s) Mid(s, 6).Trim).ToArray
145
146             Return ExceptionData.CreateInstance(message, tracess, typeINF)
147         End Function
148
149         ''' <summary>
150         ''' 运行非.NET应用程序
151         ''' 请注意,这个函数只是生成了具体的进程调用对象,还需要手动调用
152         ''' <see cref="IIORedirectAbstract.Run()"/>或者
153         ''' <see cref="IIORedirectAbstract.Start(Boolean)"/>
154         ''' 方法才会启动目标进程
155         ''' </summary>
156         ''' <param name="args$"></param>
157         ''' <returns></returns>
158         ''' 
159         <MethodImpl(MethodImplOptions.AggressiveInlining)>
160         Public Function RunProgram(args$, Optional stdin$ = NothingAs IIORedirectAbstract
161             Return App.Shell(_executableAssembly, args, CLR:=False, stdin:=stdin)
162         End Function
163
164         Public Overrides Function ToString() As String
165             If String.IsNullOrEmpty(_executableAssembly) Then
166                 Return MyBase.ToString()
167             Else
168                 Return _executableAssembly
169             End If
170         End Function
171     End Class
172
173     Public MustInherit Class CLIBuilder
174
175         Public Overrides Function ToString() As String
176             Return Me.GetCLI
177         End Function
178     End Class
179 End Namespace