@devscholar/node-ps1-dotnet 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EnsureBom.ps1 +27 -0
- package/LICENSE.md +22 -0
- package/README.md +65 -0
- package/examples/console/await-delay/await-delay.ts +14 -0
- package/examples/console/console-input/console-input.ts +18 -0
- package/examples/winforms/counter/counter.ts +47 -0
- package/examples/winforms/drag-box/drag-box.ts +62 -0
- package/examples/wpf/counter/counter.ts +55 -0
- package/examples/wpf/drag-box/drag-box.ts +84 -0
- package/examples/wpf/webview2-browser/WebView2Libs/Microsoft.Web.WebView2.Core.dll +0 -0
- package/examples/wpf/webview2-browser/WebView2Libs/Microsoft.Web.WebView2.Core.dll.backup +0 -0
- package/examples/wpf/webview2-browser/WebView2Libs/Microsoft.Web.WebView2.Wpf.dll +0 -0
- package/examples/wpf/webview2-browser/WebView2Libs/Microsoft.Web.WebView2.Wpf.dll.backup +0 -0
- package/examples/wpf/webview2-browser/WebView2Libs/WebView2License.txt +27 -0
- package/examples/wpf/webview2-browser/counter.html +31 -0
- package/examples/wpf/webview2-browser/webview2-browser.ts +90 -0
- package/package.json +19 -0
- package/scripts/PsBridge/BridgeState.cs +39 -0
- package/scripts/PsBridge/Protocol.cs +222 -0
- package/scripts/PsBridge/PsBridge.psd1 +10 -0
- package/scripts/PsBridge/PsBridge.psm1 +22 -0
- package/scripts/PsBridge/PsHost.cs +393 -0
- package/scripts/PsBridge/PsHostEntry.cs +23 -0
- package/scripts/PsBridge/Reflection.cs +830 -0
- package/scripts/PsHost.ps1 +11 -0
- package/src/index.ts +510 -0
- package/src/ipc.ts +182 -0
- package/src/types.ts +21 -0
- package/src/utils.ts +13 -0
- package/start.js +67 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
// scripts/PsBridge/Reflection.cs
|
|
2
|
+
using System;
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.IO;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using System.Reflection;
|
|
7
|
+
using System.Runtime.InteropServices;
|
|
8
|
+
using System.Threading.Tasks;
|
|
9
|
+
|
|
10
|
+
public static class Reflection
|
|
11
|
+
{
|
|
12
|
+
public static Dictionary<string, object> InvokeReflectionLogic(Dictionary<string, object> cmd)
|
|
13
|
+
{
|
|
14
|
+
var action = cmd["action"].ToString();
|
|
15
|
+
|
|
16
|
+
if (action == "GetRuntimeInfo")
|
|
17
|
+
{
|
|
18
|
+
var frameworkDescription = RuntimeInformation.FrameworkDescription;
|
|
19
|
+
var environmentVersion = Environment.Version.ToString();
|
|
20
|
+
string frameworkMoniker = InferFrameworkMoniker();
|
|
21
|
+
|
|
22
|
+
return new Dictionary<string, object>
|
|
23
|
+
{
|
|
24
|
+
{ "type", "runtimeInfo" },
|
|
25
|
+
{ "frameworkMoniker", frameworkMoniker },
|
|
26
|
+
{ "runtimeVersion", environmentVersion },
|
|
27
|
+
{ "frameworkDescription", frameworkDescription }
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (action == "GetType")
|
|
32
|
+
{
|
|
33
|
+
var name = cmd["typeName"].ToString();
|
|
34
|
+
var type = Type.GetType(name);
|
|
35
|
+
if (type == null)
|
|
36
|
+
{
|
|
37
|
+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
38
|
+
foreach (var asm in assemblies)
|
|
39
|
+
{
|
|
40
|
+
type = asm.GetType(name);
|
|
41
|
+
if (type != null) break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (type == null)
|
|
45
|
+
{
|
|
46
|
+
return new Dictionary<string, object> { { "type", "namespace" }, { "value", name } };
|
|
47
|
+
}
|
|
48
|
+
return Protocol.ConvertToProtocol(type);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (action == "Inspect")
|
|
52
|
+
{
|
|
53
|
+
var target = BridgeState.ObjectStore[cmd["targetId"].ToString()];
|
|
54
|
+
var memberName = cmd["memberName"].ToString();
|
|
55
|
+
|
|
56
|
+
if (target is Type)
|
|
57
|
+
{
|
|
58
|
+
var prop = ((Type)target).GetProperty(memberName, BindingFlags.Public | BindingFlags.Static);
|
|
59
|
+
if (prop != null)
|
|
60
|
+
{
|
|
61
|
+
return new Dictionary<string, object> { { "type", "meta" }, { "memberType", "property" } };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
var members = target.GetType().GetMember(memberName);
|
|
66
|
+
if (members != null && members.Length > 0)
|
|
67
|
+
{
|
|
68
|
+
var member = members[0];
|
|
69
|
+
if (member is PropertyInfo)
|
|
70
|
+
{
|
|
71
|
+
return new Dictionary<string, object> { { "type", "meta" }, { "memberType", "property" } };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return new Dictionary<string, object> { { "type", "meta" }, { "memberType", "method" } };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (action == "GetTypeName")
|
|
79
|
+
{
|
|
80
|
+
var target = BridgeState.ObjectStore[cmd["targetId"].ToString()];
|
|
81
|
+
var typeName = target.GetType().FullName;
|
|
82
|
+
return new Dictionary<string, object> { { "typeName", typeName } };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (action == "InspectType")
|
|
86
|
+
{
|
|
87
|
+
var typeName = cmd["typeName"].ToString();
|
|
88
|
+
var memberNames = (System.Collections.ArrayList)cmd["memberNames"];
|
|
89
|
+
var type = Type.GetType(typeName);
|
|
90
|
+
if (type == null)
|
|
91
|
+
{
|
|
92
|
+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
93
|
+
foreach (var asm in assemblies)
|
|
94
|
+
{
|
|
95
|
+
type = asm.GetType(typeName);
|
|
96
|
+
if (type != null) break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var result = new Dictionary<string, object>();
|
|
101
|
+
result["typeName"] = typeName;
|
|
102
|
+
var members = new Dictionary<string, string>();
|
|
103
|
+
|
|
104
|
+
foreach (string memberName in memberNames)
|
|
105
|
+
{
|
|
106
|
+
var prop = type.GetProperty(memberName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
|
|
107
|
+
if (prop != null)
|
|
108
|
+
{
|
|
109
|
+
members[memberName] = "property";
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
var methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
|
|
113
|
+
foreach (var m in methods)
|
|
114
|
+
{
|
|
115
|
+
if (m.Name == memberName)
|
|
116
|
+
{
|
|
117
|
+
members[memberName] = "method";
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (!members.ContainsKey(memberName))
|
|
122
|
+
{
|
|
123
|
+
members[memberName] = "method";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
result["members"] = members;
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (action == "AddEvent")
|
|
132
|
+
{
|
|
133
|
+
var target = BridgeState.ObjectStore[cmd["targetId"].ToString()];
|
|
134
|
+
var eventName = cmd["eventName"].ToString();
|
|
135
|
+
var cbId = cmd["callbackId"].ToString();
|
|
136
|
+
|
|
137
|
+
var eventInfo = target.GetType().GetEvent(eventName);
|
|
138
|
+
if (eventInfo != null)
|
|
139
|
+
{
|
|
140
|
+
var delegateType = eventInfo.EventHandlerType;
|
|
141
|
+
var invokeMethod = delegateType.GetMethod("Invoke");
|
|
142
|
+
var parameters = invokeMethod.GetParameters();
|
|
143
|
+
|
|
144
|
+
Delegate handler = null;
|
|
145
|
+
|
|
146
|
+
if (parameters.Length == 2)
|
|
147
|
+
{
|
|
148
|
+
var senderType = parameters[0].ParameterType;
|
|
149
|
+
var eType = parameters[1].ParameterType;
|
|
150
|
+
|
|
151
|
+
Action<object, object> handlerAction = (sender, e) =>
|
|
152
|
+
{
|
|
153
|
+
var writer = BridgeState.Writer;
|
|
154
|
+
if (writer == null) return;
|
|
155
|
+
|
|
156
|
+
var protoArgs = new List<Dictionary<string, object>>();
|
|
157
|
+
|
|
158
|
+
foreach (var arg in new object[] { sender, e })
|
|
159
|
+
{
|
|
160
|
+
if (arg == null)
|
|
161
|
+
{
|
|
162
|
+
protoArgs.Add(new Dictionary<string, object> { { "type", "null" } });
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
{
|
|
166
|
+
protoArgs.Add(Protocol.ConvertToProtocol(arg));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
var msg = new Dictionary<string, object>
|
|
171
|
+
{
|
|
172
|
+
{ "type", "event" },
|
|
173
|
+
{ "callbackId", cbId },
|
|
174
|
+
{ "args", protoArgs }
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
var json = SimpleJson.Serialize(msg);
|
|
178
|
+
writer.WriteLine(json);
|
|
179
|
+
|
|
180
|
+
try
|
|
181
|
+
{
|
|
182
|
+
if (PsHost.ProcessNestedCommands != null)
|
|
183
|
+
{
|
|
184
|
+
PsHost.ProcessNestedCommands();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch { }
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
handler = Delegate.CreateDelegate(delegateType, handlerAction.Target, handlerAction.Method);
|
|
191
|
+
}
|
|
192
|
+
else
|
|
193
|
+
{
|
|
194
|
+
Action<object[]> handlerAction = (args) =>
|
|
195
|
+
{
|
|
196
|
+
var writer = BridgeState.Writer;
|
|
197
|
+
if (writer == null) return;
|
|
198
|
+
|
|
199
|
+
var protoArgs = new List<Dictionary<string, object>>();
|
|
200
|
+
|
|
201
|
+
if (args != null)
|
|
202
|
+
{
|
|
203
|
+
foreach (var arg in args)
|
|
204
|
+
{
|
|
205
|
+
if (arg == null)
|
|
206
|
+
{
|
|
207
|
+
protoArgs.Add(new Dictionary<string, object> { { "type", "null" } });
|
|
208
|
+
}
|
|
209
|
+
else
|
|
210
|
+
{
|
|
211
|
+
protoArgs.Add(Protocol.ConvertToProtocol(arg));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
var msg = new Dictionary<string, object>
|
|
217
|
+
{
|
|
218
|
+
{ "type", "event" },
|
|
219
|
+
{ "callbackId", cbId },
|
|
220
|
+
{ "args", protoArgs }
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
var json = SimpleJson.Serialize(msg);
|
|
224
|
+
writer.WriteLine(json);
|
|
225
|
+
|
|
226
|
+
try
|
|
227
|
+
{
|
|
228
|
+
if (PsHost.ProcessNestedCommands != null)
|
|
229
|
+
{
|
|
230
|
+
PsHost.ProcessNestedCommands();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch { }
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
handler = Delegate.CreateDelegate(delegateType, handlerAction.Target, handlerAction.Method);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
eventInfo.AddEventHandler(target, handler);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return new Dictionary<string, object> { { "type", "void" } };
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (action == "New")
|
|
246
|
+
{
|
|
247
|
+
var type = (Type)BridgeState.ObjectStore[cmd["typeId"].ToString()];
|
|
248
|
+
var argsObj = cmd.ContainsKey("args") ? cmd["args"] : null;
|
|
249
|
+
var args = Protocol.ResolveArgs(argsObj);
|
|
250
|
+
|
|
251
|
+
object obj;
|
|
252
|
+
try
|
|
253
|
+
{
|
|
254
|
+
if (args.Length == 0)
|
|
255
|
+
{
|
|
256
|
+
obj = Activator.CreateInstance(type);
|
|
257
|
+
}
|
|
258
|
+
else
|
|
259
|
+
{
|
|
260
|
+
var constructors = type.GetConstructors();
|
|
261
|
+
Exception lastException = null;
|
|
262
|
+
|
|
263
|
+
foreach (var ctor in constructors)
|
|
264
|
+
{
|
|
265
|
+
var parameters = ctor.GetParameters();
|
|
266
|
+
if (parameters.Length != args.Length) continue;
|
|
267
|
+
|
|
268
|
+
var convertedArgs = new object[args.Length];
|
|
269
|
+
var match = true;
|
|
270
|
+
|
|
271
|
+
for (var i = 0; i < parameters.Length; i++)
|
|
272
|
+
{
|
|
273
|
+
var pType = parameters[i].ParameterType;
|
|
274
|
+
var arg = args[i];
|
|
275
|
+
|
|
276
|
+
if (arg == null)
|
|
277
|
+
{
|
|
278
|
+
convertedArgs[i] = null;
|
|
279
|
+
}
|
|
280
|
+
else if (pType.IsAssignableFrom(arg.GetType()))
|
|
281
|
+
{
|
|
282
|
+
convertedArgs[i] = arg;
|
|
283
|
+
}
|
|
284
|
+
else if (arg is IConvertible && !pType.IsAssignableFrom(typeof(string)))
|
|
285
|
+
{
|
|
286
|
+
try
|
|
287
|
+
{
|
|
288
|
+
convertedArgs[i] = Convert.ChangeType(arg, pType);
|
|
289
|
+
}
|
|
290
|
+
catch
|
|
291
|
+
{
|
|
292
|
+
match = false;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (pType.IsEnum && arg is int)
|
|
297
|
+
{
|
|
298
|
+
convertedArgs[i] = Enum.ToObject(pType, arg);
|
|
299
|
+
}
|
|
300
|
+
else
|
|
301
|
+
{
|
|
302
|
+
match = false;
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (match)
|
|
308
|
+
{
|
|
309
|
+
try
|
|
310
|
+
{
|
|
311
|
+
obj = ctor.Invoke(convertedArgs);
|
|
312
|
+
return Protocol.ConvertToProtocol(obj);
|
|
313
|
+
}
|
|
314
|
+
catch (Exception ex)
|
|
315
|
+
{
|
|
316
|
+
lastException = ex;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (lastException != null)
|
|
322
|
+
{
|
|
323
|
+
throw lastException;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
obj = Activator.CreateInstance(type);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
catch (Exception ex)
|
|
330
|
+
{
|
|
331
|
+
throw new Exception("New Error: " + ex.Message);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return Protocol.ConvertToProtocol(obj);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (action == "Invoke")
|
|
338
|
+
{
|
|
339
|
+
var target = BridgeState.ObjectStore[cmd["targetId"].ToString()];
|
|
340
|
+
var name = cmd["methodName"].ToString();
|
|
341
|
+
var argsObj = cmd.ContainsKey("args") ? cmd["args"] : null;
|
|
342
|
+
var realArgs = Protocol.ResolveArgs(argsObj);
|
|
343
|
+
|
|
344
|
+
var isStatic = target is Type;
|
|
345
|
+
var targetType = isStatic ? (Type)target : target.GetType();
|
|
346
|
+
|
|
347
|
+
if (isStatic && realArgs.Length == 0)
|
|
348
|
+
{
|
|
349
|
+
try
|
|
350
|
+
{
|
|
351
|
+
var prop = targetType.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
|
|
352
|
+
if (prop != null)
|
|
353
|
+
{
|
|
354
|
+
var result = prop.GetValue(null);
|
|
355
|
+
return Protocol.ConvertToProtocol(result);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
var field = targetType.GetField(name, BindingFlags.Public | BindingFlags.Static);
|
|
359
|
+
if (field != null)
|
|
360
|
+
{
|
|
361
|
+
var result = field.GetValue(null);
|
|
362
|
+
return Protocol.ConvertToProtocol(result);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch { }
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (!isStatic && realArgs.Length > 0)
|
|
369
|
+
{
|
|
370
|
+
var prop = targetType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
|
|
371
|
+
if (prop != null && prop.CanWrite)
|
|
372
|
+
{
|
|
373
|
+
try
|
|
374
|
+
{
|
|
375
|
+
var value = realArgs[0];
|
|
376
|
+
if (value != null && !prop.PropertyType.IsAssignableFrom(value.GetType()))
|
|
377
|
+
{
|
|
378
|
+
if (prop.PropertyType.IsEnum)
|
|
379
|
+
{
|
|
380
|
+
var intValue = value is long ? (int)(long)value : (int)value;
|
|
381
|
+
value = Enum.ToObject(prop.PropertyType, intValue);
|
|
382
|
+
}
|
|
383
|
+
else if (value is IConvertible)
|
|
384
|
+
{
|
|
385
|
+
value = Convert.ChangeType(value, prop.PropertyType);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
prop.SetValue(target, value);
|
|
389
|
+
return new Dictionary<string, object> { { "type", "void" } };
|
|
390
|
+
}
|
|
391
|
+
catch (Exception ex)
|
|
392
|
+
{
|
|
393
|
+
throw new Exception("Set Property Error '" + name + "': " + ex.Message);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (!isStatic && realArgs.Length == 0)
|
|
399
|
+
{
|
|
400
|
+
var prop = targetType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
|
|
401
|
+
if (prop != null)
|
|
402
|
+
{
|
|
403
|
+
return Protocol.ConvertToProtocol(prop.GetValue(target));
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
try
|
|
408
|
+
{
|
|
409
|
+
object result = null;
|
|
410
|
+
var bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase;
|
|
411
|
+
|
|
412
|
+
var hasDelegateArg = false;
|
|
413
|
+
foreach (var arg in realArgs)
|
|
414
|
+
{
|
|
415
|
+
if (arg is Delegate || arg is Func<object, object, object, object, object>)
|
|
416
|
+
{
|
|
417
|
+
hasDelegateArg = true;
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
var manualSuccess = false;
|
|
423
|
+
|
|
424
|
+
if (hasDelegateArg)
|
|
425
|
+
{
|
|
426
|
+
var methods = targetType.GetMethods(bindingFlags).Where(m => m.Name == name).ToArray();
|
|
427
|
+
|
|
428
|
+
foreach (var method in methods)
|
|
429
|
+
{
|
|
430
|
+
var parameters = method.GetParameters();
|
|
431
|
+
if (parameters.Length != realArgs.Length) continue;
|
|
432
|
+
|
|
433
|
+
var tempArgs = new object[realArgs.Length];
|
|
434
|
+
Array.Copy(realArgs, tempArgs, realArgs.Length);
|
|
435
|
+
var match = true;
|
|
436
|
+
|
|
437
|
+
for (var i = 0; i < parameters.Length; i++)
|
|
438
|
+
{
|
|
439
|
+
var pType = parameters[i].ParameterType;
|
|
440
|
+
var arg = tempArgs[i];
|
|
441
|
+
|
|
442
|
+
if (arg is Func<object, object, object, object, object>)
|
|
443
|
+
{
|
|
444
|
+
var func = (Func<object, object, object, object, object>)arg;
|
|
445
|
+
if (pType == typeof(Delegate))
|
|
446
|
+
{
|
|
447
|
+
try
|
|
448
|
+
{
|
|
449
|
+
tempArgs[i] = (Action)(() => func(null, null, null, null));
|
|
450
|
+
}
|
|
451
|
+
catch
|
|
452
|
+
{
|
|
453
|
+
match = false;
|
|
454
|
+
break;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
else if (typeof(Delegate).IsAssignableFrom(pType))
|
|
458
|
+
{
|
|
459
|
+
try
|
|
460
|
+
{
|
|
461
|
+
tempArgs[i] = Delegate.CreateDelegate(pType, func.Target, func.Method);
|
|
462
|
+
}
|
|
463
|
+
catch
|
|
464
|
+
{
|
|
465
|
+
match = false;
|
|
466
|
+
break;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
else
|
|
470
|
+
{
|
|
471
|
+
match = false;
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (tempArgs[i] == null)
|
|
476
|
+
{
|
|
477
|
+
match = false;
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else if (arg != null && !pType.IsAssignableFrom(arg.GetType()))
|
|
482
|
+
{
|
|
483
|
+
if (pType.IsEnum && (arg is int || arg is long))
|
|
484
|
+
{
|
|
485
|
+
var intVal = arg is long ? (int)(long)arg : (int)arg;
|
|
486
|
+
tempArgs[i] = Enum.ToObject(pType, intVal);
|
|
487
|
+
}
|
|
488
|
+
else if (IsNumericType(arg.GetType()) && IsNumericType(pType))
|
|
489
|
+
{
|
|
490
|
+
try
|
|
491
|
+
{
|
|
492
|
+
tempArgs[i] = Convert.ChangeType(arg, pType);
|
|
493
|
+
}
|
|
494
|
+
catch
|
|
495
|
+
{
|
|
496
|
+
match = false;
|
|
497
|
+
break;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else
|
|
501
|
+
{
|
|
502
|
+
match = false;
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
if (match)
|
|
509
|
+
{
|
|
510
|
+
try
|
|
511
|
+
{
|
|
512
|
+
var instanceToCall = isStatic ? null : target;
|
|
513
|
+
result = method.Invoke(instanceToCall, tempArgs);
|
|
514
|
+
manualSuccess = true;
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
catch { }
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
if (!manualSuccess)
|
|
523
|
+
{
|
|
524
|
+
var methods = targetType.GetMethods(bindingFlags).Where(m => m.Name == name).ToArray();
|
|
525
|
+
|
|
526
|
+
if (methods.Length == 1)
|
|
527
|
+
{
|
|
528
|
+
var method = methods[0];
|
|
529
|
+
var convertedArgs = ConvertArgsForMethod(method, realArgs);
|
|
530
|
+
result = method.Invoke(isStatic ? null : target, convertedArgs);
|
|
531
|
+
}
|
|
532
|
+
else if (methods.Length > 1 && realArgs.Length > 0)
|
|
533
|
+
{
|
|
534
|
+
MethodInfo bestMethod = FindBestMatchingMethod(methods, realArgs);
|
|
535
|
+
if (bestMethod != null)
|
|
536
|
+
{
|
|
537
|
+
var convertedArgs = ConvertArgsForMethod(bestMethod, realArgs);
|
|
538
|
+
result = bestMethod.Invoke(isStatic ? null : target, convertedArgs);
|
|
539
|
+
}
|
|
540
|
+
else
|
|
541
|
+
{
|
|
542
|
+
result = methods[0].Invoke(isStatic ? null : target, realArgs);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
else if (methods.Length > 0)
|
|
546
|
+
{
|
|
547
|
+
result = methods[0].Invoke(isStatic ? null : target, realArgs);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
return Protocol.ConvertToProtocol(result);
|
|
552
|
+
|
|
553
|
+
}
|
|
554
|
+
catch (Exception ex)
|
|
555
|
+
{
|
|
556
|
+
if (realArgs.Length == 0)
|
|
557
|
+
{
|
|
558
|
+
try
|
|
559
|
+
{
|
|
560
|
+
object val = null;
|
|
561
|
+
if (isStatic)
|
|
562
|
+
{
|
|
563
|
+
var prop = targetType.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
|
|
564
|
+
if (prop != null) val = prop.GetValue(null);
|
|
565
|
+
else
|
|
566
|
+
{
|
|
567
|
+
var field = targetType.GetField(name, BindingFlags.Public | BindingFlags.Static);
|
|
568
|
+
if (field != null) val = field.GetValue(null);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
else
|
|
572
|
+
{
|
|
573
|
+
var prop = targetType.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
|
|
574
|
+
if (prop != null) val = prop.GetValue(target);
|
|
575
|
+
else
|
|
576
|
+
{
|
|
577
|
+
var field = targetType.GetField(name, BindingFlags.Public | BindingFlags.Instance);
|
|
578
|
+
if (field != null) val = field.GetValue(target);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
if (val != null)
|
|
582
|
+
{
|
|
583
|
+
return Protocol.ConvertToProtocol(val);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
catch { }
|
|
587
|
+
}
|
|
588
|
+
var innerMsg = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
|
|
589
|
+
throw new Exception("Invoke Error (" + name + "): " + innerMsg);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (action == "AwaitTask")
|
|
594
|
+
{
|
|
595
|
+
var taskId = cmd["taskId"].ToString();
|
|
596
|
+
var task = (Task)BridgeState.ObjectStore[taskId];
|
|
597
|
+
try
|
|
598
|
+
{
|
|
599
|
+
task.Wait();
|
|
600
|
+
var taskType = task.GetType();
|
|
601
|
+
if (taskType.IsGenericType && taskType.GetGenericTypeDefinition() == typeof(Task<>))
|
|
602
|
+
{
|
|
603
|
+
var result = taskType.GetProperty("Result").GetValue(task);
|
|
604
|
+
return Protocol.ConvertToProtocol(result);
|
|
605
|
+
}
|
|
606
|
+
return new Dictionary<string, object> { { "type", "void" } };
|
|
607
|
+
}
|
|
608
|
+
catch (AggregateException ae)
|
|
609
|
+
{
|
|
610
|
+
var innerMsg = ae.InnerException != null ? ae.InnerException.Message : ae.ToString();
|
|
611
|
+
throw new Exception("Task Error: " + innerMsg);
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if (action == "LoadAssembly")
|
|
616
|
+
{
|
|
617
|
+
var assemblyName = cmd["assemblyName"].ToString();
|
|
618
|
+
Assembly asm = null;
|
|
619
|
+
try
|
|
620
|
+
{
|
|
621
|
+
asm = Assembly.Load(assemblyName);
|
|
622
|
+
}
|
|
623
|
+
catch
|
|
624
|
+
{
|
|
625
|
+
#pragma warning disable 618
|
|
626
|
+
try { asm = Assembly.LoadWithPartialName(assemblyName); } catch { }
|
|
627
|
+
#pragma warning restore 618
|
|
628
|
+
}
|
|
629
|
+
if (asm == null)
|
|
630
|
+
{
|
|
631
|
+
throw new Exception("Failed to load assembly: " + assemblyName);
|
|
632
|
+
}
|
|
633
|
+
return Protocol.ConvertToProtocol(asm);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (action == "Release")
|
|
637
|
+
{
|
|
638
|
+
Protocol.RemoveBridgeObject(cmd["targetId"].ToString());
|
|
639
|
+
return new Dictionary<string, object> { { "type", "void" } };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return new Dictionary<string, object> { { "type", "void" } };
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
private static object[] ConvertArgsForMethod(MethodInfo method, object[] args)
|
|
646
|
+
{
|
|
647
|
+
if (args == null || args.Length == 0) return args;
|
|
648
|
+
|
|
649
|
+
var parameters = method.GetParameters();
|
|
650
|
+
if (parameters.Length != args.Length) return args;
|
|
651
|
+
|
|
652
|
+
var convertedArgs = new object[args.Length];
|
|
653
|
+
Array.Copy(args, convertedArgs, args.Length);
|
|
654
|
+
|
|
655
|
+
for (var i = 0; i < parameters.Length; i++)
|
|
656
|
+
{
|
|
657
|
+
var pType = parameters[i].ParameterType;
|
|
658
|
+
var arg = args[i];
|
|
659
|
+
|
|
660
|
+
if (arg == null || pType.IsAssignableFrom(arg.GetType()))
|
|
661
|
+
{
|
|
662
|
+
continue;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
var argType = arg.GetType();
|
|
666
|
+
|
|
667
|
+
if (pType.IsEnum)
|
|
668
|
+
{
|
|
669
|
+
if (arg is int || arg is long)
|
|
670
|
+
{
|
|
671
|
+
var intVal = arg is long ? (int)(long)arg : (int)arg;
|
|
672
|
+
convertedArgs[i] = Enum.ToObject(pType, intVal);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
else if (pType == typeof(TimeSpan))
|
|
676
|
+
{
|
|
677
|
+
if (arg is long)
|
|
678
|
+
{
|
|
679
|
+
convertedArgs[i] = TimeSpan.FromMilliseconds((long)arg);
|
|
680
|
+
}
|
|
681
|
+
else if (arg is int)
|
|
682
|
+
{
|
|
683
|
+
convertedArgs[i] = TimeSpan.FromMilliseconds((int)arg);
|
|
684
|
+
}
|
|
685
|
+
else if (arg is double)
|
|
686
|
+
{
|
|
687
|
+
convertedArgs[i] = TimeSpan.FromMilliseconds((double)arg);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
else if (argType == typeof(string) && (pType == typeof(string) || pType == typeof(object)))
|
|
691
|
+
{
|
|
692
|
+
convertedArgs[i] = arg;
|
|
693
|
+
}
|
|
694
|
+
else if (IsNumericType(argType) && IsNumericType(pType))
|
|
695
|
+
{
|
|
696
|
+
try
|
|
697
|
+
{
|
|
698
|
+
convertedArgs[i] = Convert.ChangeType(arg, pType);
|
|
699
|
+
}
|
|
700
|
+
catch { }
|
|
701
|
+
}
|
|
702
|
+
else if (arg is IConvertible && pType != typeof(string))
|
|
703
|
+
{
|
|
704
|
+
try
|
|
705
|
+
{
|
|
706
|
+
convertedArgs[i] = Convert.ChangeType(arg, pType);
|
|
707
|
+
}
|
|
708
|
+
catch { }
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return convertedArgs;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
private static MethodInfo FindBestMatchingMethod(MethodInfo[] methods, object[] args)
|
|
716
|
+
{
|
|
717
|
+
if (methods == null || methods.Length == 0 || args == null || args.Length == 0)
|
|
718
|
+
return null;
|
|
719
|
+
|
|
720
|
+
foreach (var method in methods)
|
|
721
|
+
{
|
|
722
|
+
var parameters = method.GetParameters();
|
|
723
|
+
if (parameters.Length != args.Length) continue;
|
|
724
|
+
|
|
725
|
+
var match = true;
|
|
726
|
+
for (var i = 0; i < parameters.Length; i++)
|
|
727
|
+
{
|
|
728
|
+
var pType = parameters[i].ParameterType;
|
|
729
|
+
var arg = args[i];
|
|
730
|
+
var argType = arg != null ? arg.GetType() : null;
|
|
731
|
+
|
|
732
|
+
if (argType == null) continue;
|
|
733
|
+
|
|
734
|
+
if (!pType.IsAssignableFrom(argType))
|
|
735
|
+
{
|
|
736
|
+
if (argType == typeof(string))
|
|
737
|
+
{
|
|
738
|
+
if (pType != typeof(string) && pType != typeof(object))
|
|
739
|
+
{
|
|
740
|
+
match = false;
|
|
741
|
+
break;
|
|
742
|
+
}
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
if (pType.IsEnum)
|
|
747
|
+
{
|
|
748
|
+
if (!(arg is int || arg is long))
|
|
749
|
+
{
|
|
750
|
+
match = false;
|
|
751
|
+
break;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
else if (pType == typeof(TimeSpan) && IsNumericType(argType))
|
|
755
|
+
{
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
else if (IsNumericType(argType) && IsNumericType(pType))
|
|
759
|
+
{
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
else if (args[i] is IConvertible && pType != typeof(string))
|
|
763
|
+
{
|
|
764
|
+
continue;
|
|
765
|
+
}
|
|
766
|
+
else
|
|
767
|
+
{
|
|
768
|
+
match = false;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
if (match) return method;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
return null;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
private static string InferFrameworkMoniker()
|
|
781
|
+
{
|
|
782
|
+
var frameworkDescription = RuntimeInformation.FrameworkDescription;
|
|
783
|
+
var environmentVersion = Environment.Version;
|
|
784
|
+
|
|
785
|
+
if (frameworkDescription.StartsWith(".NET Framework"))
|
|
786
|
+
{
|
|
787
|
+
var versionParts = environmentVersion.ToString().Split('.');
|
|
788
|
+
if (versionParts.Length >= 2)
|
|
789
|
+
{
|
|
790
|
+
int major = int.Parse(versionParts[0]);
|
|
791
|
+
int minor = int.Parse(versionParts[1]);
|
|
792
|
+
return "net" + major + minor;
|
|
793
|
+
}
|
|
794
|
+
return "net472";
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
if (frameworkDescription.StartsWith(".NET") && !frameworkDescription.StartsWith(".NET Framework"))
|
|
798
|
+
{
|
|
799
|
+
var versionParts = environmentVersion.ToString().Split('.');
|
|
800
|
+
if (versionParts.Length >= 1)
|
|
801
|
+
{
|
|
802
|
+
int major = int.Parse(versionParts[0]);
|
|
803
|
+
return "net" + major + ".0";
|
|
804
|
+
}
|
|
805
|
+
return "net8.0";
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
if (frameworkDescription.StartsWith(".NET Core"))
|
|
809
|
+
{
|
|
810
|
+
var versionParts = environmentVersion.ToString().Split('.');
|
|
811
|
+
if (versionParts.Length >= 2)
|
|
812
|
+
{
|
|
813
|
+
int major = int.Parse(versionParts[0]);
|
|
814
|
+
int minor = int.Parse(versionParts[1]);
|
|
815
|
+
return "netcoreapp" + major + "." + minor;
|
|
816
|
+
}
|
|
817
|
+
return "netcoreapp3.1";
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
return "netstandard2.0";
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
private static bool IsNumericType(Type type)
|
|
824
|
+
{
|
|
825
|
+
return type == typeof(int) || type == typeof(long) || type == typeof(short) ||
|
|
826
|
+
type == typeof(byte) || type == typeof(double) || type == typeof(float) ||
|
|
827
|
+
type == typeof(decimal) || type == typeof(uint) || type == typeof(ulong) ||
|
|
828
|
+
type == typeof(ushort) || type == typeof(sbyte);
|
|
829
|
+
}
|
|
830
|
+
}
|