Skip to content

Commit ce0e962

Browse files
authored
Merge pull request #214 from WeihanLi/dev
1.0.68 preview 2
2 parents 3dff33e + 72c0ca9 commit ce0e962

File tree

11 files changed

+154
-194
lines changed

11 files changed

+154
-194
lines changed

samples/DotNetCoreSample/Program.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,7 @@
22
// Licensed under the Apache license.
33

44
using DotNetCoreSample;
5-
using Microsoft.EntityFrameworkCore;
6-
using Microsoft.Extensions.Configuration;
7-
using Microsoft.Extensions.DependencyInjection;
8-
using System.Net.Mime;
9-
using WeihanLi.Common.Event;
105
using WeihanLi.Common.Helpers;
11-
using WeihanLi.Extensions;
12-
using WeihanLi.Extensions.Dump;
136

147
Console.WriteLine("----------DotNetCoreSample----------");
158

@@ -348,7 +341,9 @@
348341
// // registration would be disposed when cts dispose
349342
// }
350343

351-
await InvokeHelper.TryInvokeAsync(EventTest.MainTest);
344+
// await InvokeHelper.TryInvokeAsync(EventTest.MainTest);
345+
346+
InvokeHelper.TryInvoke(CommandExecutorTest.MainTest);
352347

353348
ConsoleHelper.ReadKeyWithPrompt("Press any key to exit");
354349

src/WeihanLi.Common/DependencyResolver.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
// Copyright (c) Weihan Li. All rights reserved.
2+
// Licensed under the Apache license.
3+
4+
using Microsoft.Extensions.DependencyInjection;
25
using WeihanLi.Common.DependencyInjection;
36

47
namespace WeihanLi.Common;
@@ -54,7 +57,8 @@ private sealed class ServiceProviderDependencyResolver(ServiceProvider servicePr
5457
return serviceProvider.GetService(serviceType);
5558
}
5659

57-
[RequiresUnreferencedCode("Calls WeihanLi.Common.DependencyInjectionExtensions.GetServices(Type)")]
60+
[RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")]
61+
[RequiresUnreferencedCode("Unreferenced code may be used")]
5862
public IEnumerable<object> GetServices(Type serviceType)
5963
{
6064
return serviceProvider.GetServices(serviceType);

src/WeihanLi.Common/Event/EventBus.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,7 @@ public async Task<bool> PublishAsync<TEvent>(TEvent @event, EventProperties? pro
5252
return false;
5353
}
5454

55-
[Obsolete("Use SubscribeAsync instead", true)]
56-
public bool Subscribe(Type eventType, Type eventHandlerType) => _subscriptionManager.Subscribe(eventType, eventHandlerType);
57-
5855
public Task<bool> SubscribeAsync(Type eventType, Type eventHandlerType) => _subscriptionManager.SubscribeAsync(eventType, eventHandlerType);
5956
public Task<bool> SubscribeAsync<TEvent>(IEventHandler<TEvent> eventHandler) => _subscriptionManager.SubscribeAsync(eventHandler);
60-
61-
[Obsolete("Use UnSubscribeAsync instead", true)]
62-
public bool UnSubscribe(Type eventType, Type eventHandlerType) => _subscriptionManager.UnSubscribe(eventType, eventHandlerType);
63-
6457
public Task<bool> UnSubscribeAsync(Type eventType, Type eventHandlerType) => _subscriptionManager.UnSubscribeAsync(eventType, eventHandlerType);
6558
}

src/WeihanLi.Common/Event/IEventSubscriber.cs

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -32,44 +32,6 @@ public interface IEventSubscriber
3232

3333
public static class EventSubscriberExtensions
3434
{
35-
/// <summary>
36-
/// add event handler for event
37-
/// </summary>
38-
/// <typeparam name="TEvent">TEvent</typeparam>
39-
/// <returns>whether the operation success</returns>
40-
[Obsolete("Use SubscribeAsync instead", true)]
41-
public static bool Subscribe<TEvent>(this IEventSubscriber subscriber, Func<TEvent, Task> handler)
42-
{
43-
return subscriber.SubscribeAsync(new DelegateEventHandler<TEvent>(handler))
44-
.GetAwaiter().GetResult();
45-
}
46-
47-
/// <summary>
48-
/// add event handler for event
49-
/// </summary>
50-
/// <typeparam name="TEvent">TEvent</typeparam>
51-
/// <typeparam name="TEventHandler">TEventHandler</typeparam>
52-
/// <returns>whether the operation success</returns>
53-
[Obsolete("Use SubscribeAsync instead", true)]
54-
public static bool Subscribe<TEvent, TEventHandler>(this IEventSubscriber subscriber)
55-
where TEventHandler : class, IEventHandler<TEvent>
56-
{
57-
return subscriber.Subscribe(typeof(TEvent), typeof(TEventHandler));
58-
}
59-
60-
/// <summary>
61-
/// add event handler for event
62-
/// </summary>
63-
/// <param name="subscriber">event subscriber</param>
64-
/// <param name="eventType">event type</param>
65-
/// <param name="eventHandlerType">eventHandler type</param>
66-
/// <returns>whether the operation success</returns>
67-
[Obsolete("Use SubscribeAsync instead", true)]
68-
public static bool Subscribe(this IEventSubscriber subscriber, Type eventType, Type eventHandlerType)
69-
{
70-
return subscriber.SubscribeAsync(eventType, eventHandlerType).GetAwaiter().GetResult();
71-
}
72-
7335
/// <summary>
7436
/// add event handler for event
7537
/// </summary>
@@ -82,32 +44,6 @@ public static Task<bool> SubscribeAsync<TEvent, TEventHandler>(this IEventSubscr
8244
return subscriber.SubscribeAsync(typeof(TEvent), typeof(TEventHandler));
8345
}
8446

85-
/// <summary>
86-
/// remove event handler for event
87-
/// </summary>
88-
/// <typeparam name="TEvent">TEvent</typeparam>
89-
/// <typeparam name="TEventHandler">TEventHandler</typeparam>
90-
/// <returns>whether the operation success</returns>
91-
[Obsolete("Use UnSubscribeAsync instead", true)]
92-
public static bool UnSubscribe<TEvent, TEventHandler>(this IEventSubscriber subscriber)
93-
where TEventHandler : class, IEventHandler<TEvent>
94-
{
95-
return subscriber.UnSubscribe(typeof(TEvent), typeof(TEventHandler));
96-
}
97-
98-
/// <summary>
99-
/// remove event handler for event
100-
/// </summary>
101-
/// <param name="subscriber">event subscriber</param>
102-
/// <param name="eventType">event type</param>
103-
/// <param name="eventHandlerType">eventHandler type</param>
104-
/// <returns>whether the operation success</returns>
105-
[Obsolete("Use UnSubscribeAsync instead", true)]
106-
public static bool UnSubscribe(this IEventSubscriber subscriber, Type eventType, Type eventHandlerType)
107-
{
108-
return subscriber.UnSubscribeAsync(eventType, eventHandlerType).GetAwaiter().GetResult();
109-
}
110-
11147
/// <summary>
11248
/// remove event handler for event
11349
/// </summary>

src/WeihanLi.Common/Extensions/ProcessExtension.cs

Lines changed: 101 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static Task WaitForExitAsync(this Process process, CancellationToken canc
2525
{
2626
Guard.NotNull(process);
2727
process.EnableRaisingEvents = true;
28-
var tcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
28+
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
2929
try
3030
{
3131
process.Exited += EventHandler;
@@ -47,7 +47,7 @@ public static Task WaitForExitAsync(this Process process, CancellationToken canc
4747

4848
return tcs.Task;
4949

50-
void EventHandler(object o, EventArgs eventArgs) => tcs.TrySetResult(null);
50+
void EventHandler(object o, EventArgs eventArgs) => tcs.TrySetResult();
5151
}
5252
#endif
5353

@@ -93,8 +93,23 @@ public static CommandResult GetResult(this ProcessStartInfo psi)
9393
using var stdOut = new StringWriter(stdOutStringBuilder);
9494
var stdErrStringBuilder = new StringBuilder();
9595
using var stdErr = new StringWriter(stdErrStringBuilder);
96-
var exitCode = GetExitCode(psi, stdOut, stdErr);
97-
return new CommandResult(exitCode, stdOutStringBuilder.ToString(), stdErrStringBuilder.ToString());
96+
var exitCode = -1;
97+
int? processId = null;
98+
Action<Process> processStartAction = p => processId = p.Id;
99+
100+
try
101+
{
102+
using var process = psi.ExecuteProcess(stdOut, stdErr, processStartAction);
103+
exitCode = process.ExitCode;
104+
}
105+
catch (Win32Exception win32Exception)
106+
{
107+
exitCode = win32Exception.ErrorCode;
108+
}
109+
return new(exitCode, stdOutStringBuilder.ToString(), stdErrStringBuilder.ToString())
110+
{
111+
ProcessId = processId
112+
};
98113
}
99114

100115
/// <summary>
@@ -107,16 +122,30 @@ public static async Task<CommandResult> GetResultAsync(this ProcessStartInfo psi
107122
{
108123
var stdOutStringBuilder = new StringBuilder();
109124
#if NETSTANDARD2_1 || NET6_0_OR_GREATER
110-
await
125+
await
111126
#endif
112127
using var stdOut = new StringWriter(stdOutStringBuilder);
113128
var stdErrStringBuilder = new StringBuilder();
114129
#if NETSTANDARD2_1 || NET6_0_OR_GREATER
115-
await
130+
await
116131
#endif
117132
using var stdErr = new StringWriter(stdErrStringBuilder);
118-
var exitCode = await GetExitCodeAsync(psi, stdOut, stdErr, cancellationToken);
119-
return new(exitCode, stdOutStringBuilder.ToString(), stdErrStringBuilder.ToString());
133+
var exitCode = -1;
134+
int? processId = null;
135+
Action<Process> processStartAction = p => processId = p.Id;
136+
try
137+
{
138+
using var process = await psi.ExecuteProcessAsync(stdOut, stdErr, processStartAction.WrapTask(), cancellationToken);
139+
exitCode = process.ExitCode;
140+
}
141+
catch (Win32Exception win32Exception)
142+
{
143+
exitCode = win32Exception.ErrorCode;
144+
}
145+
return new(exitCode, stdOutStringBuilder.ToString(), stdErrStringBuilder.ToString())
146+
{
147+
ProcessId = processId
148+
};
120149
}
121150

122151
/// <summary>
@@ -128,11 +157,55 @@ public static async Task<CommandResult> GetResultAsync(this ProcessStartInfo psi
128157
/// <returns>Process exit code</returns>
129158
public static int GetExitCode(this ProcessStartInfo psi, TextWriter? stdOut = null,
130159
TextWriter? stdErr = null)
160+
{
161+
try
162+
{
163+
using var process = psi.ExecuteProcess(stdOut, stdErr);
164+
return process.ExitCode;
165+
}
166+
catch (Win32Exception win32Exception)
167+
{
168+
return win32Exception.ErrorCode;
169+
}
170+
}
171+
172+
/// <summary>
173+
/// Wait for process exit and get exit code
174+
/// </summary>
175+
/// <param name="psi">Process is started from this information</param>
176+
/// <param name="stdOut">Defaults to Console.Out</param>
177+
/// <param name="stdErr">Defaults to Console.Error</param>
178+
/// <param name="cancellationToken">cancellationToken</param>
179+
/// <returns>Process exit code</returns>
180+
public static async Task<int> GetExitCodeAsync(this ProcessStartInfo psi, TextWriter? stdOut = null,
181+
TextWriter? stdErr = null, CancellationToken cancellationToken = default)
182+
{
183+
try
184+
{
185+
using var process = await psi.ExecuteProcessAsync(stdOut, stdErr, null, cancellationToken);
186+
return process.ExitCode;
187+
}
188+
catch (Win32Exception win32Exception)
189+
{
190+
return win32Exception.ErrorCode;
191+
}
192+
}
193+
194+
/// <summary>
195+
/// Execute process
196+
/// </summary>
197+
/// <param name="psi">Process is started from this information</param>
198+
/// <param name="stdOut">Defaults to Console.Out</param>
199+
/// <param name="stdErr">Defaults to Console.Error</param>
200+
/// <param name="processStartAction">Action to execute when process start</param>
201+
/// <returns>Process executed</returns>
202+
public static Process ExecuteProcess(this ProcessStartInfo psi, TextWriter? stdOut = null,
203+
TextWriter? stdErr = null, Action<Process>? processStartAction = null)
131204
{
132205
psi.RedirectStandardOutput = stdOut != null;
133206
psi.RedirectStandardError = stdErr != null;
134-
psi.UseShellExecute = false;
135-
using var process = new Process();
207+
208+
var process = new Process();
136209
process.StartInfo = psi;
137210
process.OutputDataReceived += (_, e) =>
138211
{
@@ -145,69 +218,62 @@ public static int GetExitCode(this ProcessStartInfo psi, TextWriter? stdOut = nu
145218
stdErr?.WriteLine(e.Data);
146219
};
147220

148-
try
149-
{
150-
process.Start();
151-
}
152-
catch (Win32Exception win32Exception)
153-
{
154-
return win32Exception.ErrorCode;
155-
}
221+
process.Start();
222+
processStartAction?.Invoke(process);
156223

157224
process.BeginOutputReadLine();
158225
process.BeginErrorReadLine();
159226
process.WaitForExit();
160227

161-
return process.ExitCode;
228+
return process;
162229
}
163230

164231
/// <summary>
165-
/// Wait for process exit and get exit code
232+
/// Execute process
166233
/// </summary>
167234
/// <param name="psi">Process is started from this information</param>
168235
/// <param name="stdOut">Defaults to Console.Out</param>
169236
/// <param name="stdErr">Defaults to Console.Error</param>
237+
/// <param name="processStartAction">Action to execute when process start</param>
170238
/// <param name="cancellationToken">cancellationToken</param>
171239
/// <returns>Process exit code</returns>
172-
public static async Task<int> GetExitCodeAsync(this ProcessStartInfo psi, TextWriter? stdOut = null,
173-
TextWriter? stdErr = null, CancellationToken cancellationToken = default)
240+
public static async Task<Process> ExecuteProcessAsync(this ProcessStartInfo psi, TextWriter? stdOut = null,
241+
TextWriter? stdErr = null, Func<Process, Task>? processStartAction = null, CancellationToken cancellationToken = default)
174242
{
175243
psi.RedirectStandardOutput = stdOut != null;
176244
psi.RedirectStandardError = stdErr != null;
177-
psi.UseShellExecute = false;
178-
using var process = new Process();
245+
246+
var process = new Process();
179247
process.StartInfo = psi;
180-
var stdOutComplete = new TaskCompletionSource<object?>();
181-
var stdErrComplete = new TaskCompletionSource<object?>();
248+
var stdOutComplete = new TaskCompletionSource();
249+
var stdErrComplete = new TaskCompletionSource();
182250
process.OutputDataReceived += (_, e) =>
183251
{
184252
if (e.Data != null)
185253
stdOut?.WriteLine(e.Data);
186254
else
187-
stdOutComplete.SetResult(null);
255+
stdOutComplete.SetResult();
188256
};
189257
process.ErrorDataReceived += (_, e) =>
190258
{
191259
if (e.Data != null)
192260
stdErr?.WriteLine(e.Data);
193261
else
194-
stdErrComplete.SetResult(null);
262+
stdErrComplete.SetResult();
195263
};
196-
try
197-
{
198-
process.Start();
199-
}
200-
catch (Win32Exception win32Exception)
264+
265+
process.Start();
266+
if (processStartAction is not null)
201267
{
202-
return win32Exception.ErrorCode;
268+
await processStartAction.Invoke(process);
203269
}
204270

205271
process.BeginOutputReadLine();
206272
process.BeginErrorReadLine();
207273
using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, ApplicationHelper.ExitToken);
208274
cts.Token.Register((p) => ((Process)p!).TryKill(), process);
209275
await Task.WhenAll(process.WaitForExitAsync(cts.Token), stdOutComplete.Task, stdErrComplete.Task);
210-
return process.ExitCode;
276+
return process;
211277
}
212278

213279
/// <summary>

0 commit comments

Comments
 (0)