dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.26k stars 4.73k forks source link

Worker Service: Windows Service arguments are not picked up #61349

Open vsfeedback opened 3 years ago

vsfeedback commented 3 years ago

This issue has been moved from a ticket on Developer Community.


[severity:It bothers me. A fix would be nice] To reproduce this: Create a Windows Service, created with .NET 5.0 using the "Worker Service" template - inheriting from BackgroundService , after the service is deployed, arguments are not picked up and passed to the service.

e.g. a basic Worker service which prints the args passed to it (to a log file or event log) Run in debug, and the arguments are printed

Publish and application, and install it as a service, and it does not pick up arguments

To create the service from PowerShell, I am using these commands

sc.exe create MyService binpath= "C:\Temp\MyService\MyService.exe" DisplayName= My Test Service" start= auto

I verified that the service exists in the Services App: Then start the service with arguments

sc.exe start MyService arg1 arg2

Arguments are not picked up by the service

Alternative start method

$service = Get-Service MyService
$service. Start(@('arg1','arg2'))

Again arguments are not picked up by the service

However, If I create the service, and add the arguments to the binpath, then the arguments ARE passed correctly

sc.exe create MyService binpath= "C:\Temp\MyService\MyService.exe arg1 arg2" DisplayName= My Test Service" start= auto
sc.exe start MyService

Arguments (from binpath) are picked up - as long as the arguments are within the quotes

This seems to be a problem with Windows passing arguments to a Worker-Style service .
My guess is something the fault lies in Microsoft.Extensions.Hosting.WindowsService

Old-style Windows services can still be created using this version of Visual Studio - and the argument passing works fine. This only affects the new-style Worker Service projects


Original Comments

Feedback Bot on 10/28/2021, 08:29 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

Tratcher commented 2 years ago

I remember there being something strange about the way args flow in a windows service process. I don't think they're passed to Main, you get them later. https://github.com/dotnet/runtime/blob/704f023147b49692cec842427b116e9ee7e64305/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs#L366-L381

davidfowl commented 2 years ago

They aren't and this would need to be opt in if we wanted to support it.

davidfowl commented 2 years ago

Moving to runtime

ghost commented 2 years ago

Tagging subscribers to this area: @eerhardt, @maryamariyan See info in area-owners.md if you want to be subscribed.

Issue Details
_This issue has been moved from [a ticket on Developer Community](https://developercommunity.visualstudio.com/t/Worker-Service:-Windows-Service-argument/1566442)._ --- [severity:It bothers me. A fix would be nice] To reproduce this: Create a Windows Service, created with .NET 5.0 using the "Worker Service" template - inheriting from BackgroundService , after the service is deployed, arguments are not picked up and passed to the service. e.g. a basic Worker service which prints the args passed to it (to a log file or event log) Run in debug, and the arguments are printed Publish and application, and install it as a service, and it does not pick up arguments To create the service from PowerShell, I am using these commands `sc.exe create MyService binpath= "C:\Temp\MyService\MyService.exe" DisplayName= My Test Service" start= auto` I verified that the service exists in the Services App: Then start the service with arguments `sc.exe start MyService arg1 arg2` Arguments are not picked up by the service Alternative start method ``` $service = Get-Service MyService $service. Start(@('arg1','arg2')) ``` Again arguments are not picked up by the service However, If I create the service, and add the arguments to the binpath, then the arguments ARE passed correctly ``` sc.exe create MyService binpath= "C:\Temp\MyService\MyService.exe arg1 arg2" DisplayName= My Test Service" start= auto sc.exe start MyService ``` Arguments (from binpath) are picked up - as long as the arguments are within the quotes This seems to be a problem with Windows passing arguments to a Worker-Style service . My guess is something the fault lies in Microsoft.Extensions.Hosting.WindowsService Old-style Windows services can still be created using this version of Visual Studio - and the argument passing works fine. This only affects the new-style Worker Service projects --- ### Original Comments #### Feedback Bot on 10/28/2021, 08:29 PM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.

--- ### Original Solutions (no solutions)
Author: vsfeedback
Assignees: bradygaster
Labels: `untriaged`, `area-Extensions-Hosting`
Milestone: -
Dragan-Juric commented 2 years ago

I just ran into this issue, and it worked without problems in the earlier Windows Service model in .Net 4.7.x... Just posting here so that you guys know that there may be more people who need this to work :)

davidfowl commented 2 years ago

This still works the way it used to work on .NET Framework. This issue is specifically about Microsoft.Extensions.Hosting.WindowsServices.

Dragan-Juric commented 2 years ago

Oh, I know it works on .Net Framework. Perhaps I was unclear in my first comment. I upgraded a .Net Framework Windows Service project to .Net 6, complete with Microsoft.Extensions.Hosting.WindowsServices and all that... and then it stopped working.

pstrus commented 2 years ago

I'm having same issue .Is there any way/workaround to read these params ?

davidfowl commented 2 years ago
using System.ServiceProcess;
using WorkerService1;

var service = new MyService();
ServiceBase.Run(service);
if (service.TheHost != null)
{
    await service.TheHost.StopAsync();
}

class MyService : ServiceBase
{
    private IHost? _host;

    public IHost? TheHost => _host;

    protected override void OnStart(string[] args)
    {
        _host = Host.CreateDefaultBuilder(args)
        .ConfigureServices(services =>
        {
            services.AddHostedService<Worker>();
        })
        .Build();

        _host.Start();
        base.OnStart(args);
    }
}
davidfowl commented 2 years ago

This will use the args from the start instead.