-
-
Notifications
You must be signed in to change notification settings - Fork 28
Open
Description
I'm developing a .NET Maui application for Android and Windows.
In the Windows application, I have a Windows BackgroundService doing some job with independence of the application state. My application and this BackgroundService should somehow communicate back and forth.
Since I don't have experience with Windows applications, I started searching documentation, and I found out about NamedPipes, and later, I found out about this wrapper that seems to make things easier.
So far, I tried these two scenarios:
First scenario
- Debug on Visual Studio both my application and the Windows BackgroundService. I can successfully communicate back and forth.
Second scenario
- Deploy my service on my computer and try to communicate from my application debugging on Visual Studio (on same computer).
- For the Windows BackgroundService deploying part, I'm following this docs.
- I can see my Windows BackgroundService running by Ctrl+Alt+Del and serching for its name.
- Now the same code as before isn't working anymore. await client.ConnectAsync(); is throwing System.UnauthorizedAccessException in System.Private.CoreLib.dll ("Access to the path is denied.")
This is the code I'm using on both scenarios:
Windows BackgroundService:
public sealed class WindowsBackgroundService(VFService vfService, ILogger<WindowsBackgroundService> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
PipeServer<PipeMessage> serverPipe = new PipeServer<PipeMessage>("01043009-CTPV_VF");
logger.LogInformation("Server is awakening");
serverPipe.ClientConnected += (o, args) => OnClientConnected(args);
serverPipe.ClientDisconnected += (o, args) => OnClientDisconnected(args);
serverPipe.MessageReceived += (sender, args) => OnMessageReceived(args.Message);
serverPipe.ExceptionOccurred += (o, args) => OnExceptionOccurred(args.Exception);
logger.LogInformation("Server pipe is UP");
try
{
await serverPipe.StartAsync();
logger.LogInformation("Server pipe is listening for connections now!");
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
}
}
catch (OperationCanceledException)
{
// When the stopping token is canceled, for example, a call made from services.msc,
// we shouldn't exit with a non-zero exit code. In other words, this is expected...
}
catch (Exception ex)
{
logger.LogError(ex, "{Message}", ex.Message);
// Terminates this process and returns an exit code to the operating system.
// This is required to avoid the 'BackgroundServiceExceptionBehavior', which
// performs one of two scenarios:
// 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
// 2. When set to "StopHost": will cleanly stop the host, and log errors.
//
// In order for the Windows Service Management system to leverage configured
// recovery options, we need to terminate the process with a non-zero exit code.
Environment.Exit(1);
}
finally
{
logger.LogInformation("Server has stopped");
//await serverPipe.StopAsync();
}
}
#region " Server Pipe "
private void OnClientConnected(ConnectionEventArgs<PipeMessage> args)
{
logger.LogInformation("New client connected");
}
private void OnClientDisconnected(ConnectionEventArgs<PipeMessage> args)
{
logger.LogInformation("Client disconnected");
}
private void OnMessageReceived(PipeMessage? message)
{
switch (message.Action)
{
case ActionType.SendText:
logger.LogInformation($"Text from client: {message.Text}");
break;
case ActionType.ShowTrayIcon:
throw new NotImplementedException();
case ActionType.HideTrayIcon:
throw new NotImplementedException();
default:
Console.WriteLine($"Unknown Action Type: {message.Action}");
break;
}
}
private void OnExceptionOccurred(Exception ex)
{
logger.LogInformation($"Exception occured in pipe: {ex}");
}
#endregion
}
My .NET Maui application:
Task.Run(async () =>
{
try
{
await using var client = new PipeClient<PipeMessage>("01043009-CTPV_VF", reconnectionInterval:TimeSpan.FromSeconds(5));
client.MessageReceived += (sender, args) => Debug.WriteLine(args.Message);
client.Disconnected += (o, args) => Debug.WriteLine("Disconnected from server");
client.Connected += (o, args) => Debug.WriteLine("Connected to server");
client.ExceptionOccurred += (o, args) => Debug.WriteLine(args.Exception);
await client.ConnectAsync();
await client.WriteAsync(new PipeMessage
{
Action = ActionType.SendText,
Text = "Hello from client",
});
}
catch (Exception ex)
{
var tmp = ex;
}
});
What I'm doing wrong?
Metadata
Metadata
Assignees
Labels
No labels