如何从现有 windows 服务启动 AspNetCore 应用程序
How to start a AspNetCore App from an existing windows service
我有一个现有的 windows 服务。目标是有一个 REST 接口来与此服务通信。我认为只制作一个 ASP.NET 核心 Web 应用程序(参见屏幕截图)并在我现有的服务中启动整个应用程序可能是个好主意。然后他们可以共享相同的 IOC 容器等等。
然后我用sc create s1 binPath = "pathgoeshere"
注册了服务
当我启动服务(附加到调试进程)时,我在输出中收到错误 window:
Exception thrown: 'System.DllNotFoundException' in Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll
The thread 0x5250 has exited with code 0 (0x0).
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
'WindowsService1.exe' (CLR v4.0.30319: WindowsService1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ServiceProcess.resources\v4.0_4.0.0.0_de_b03f5f7f11d50a3a\System.ServiceProcess.resources.dll'. Module was built without symbols.
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
The thread 0x4fa0 has exited with code 0 (0x0).
Microsoft.AspNetCore.Server.Kestrel: Warning: Unable to bind to http://localhost:5000 on the IPv4 loopback interface: 'Die DLL "libuv": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.'.
Exception thrown: 'System.DllNotFoundException' in Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll
The thread 0x58c4 has exited with code 0 (0x0).
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Microsoft.AspNetCore.Server.Kestrel: Warning: Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Die DLL "libuv": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.'.
Exception thrown: 'System.IO.IOException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Microsoft.AspNetCore.Server.Kestrel: Critical: Unable to start Kestrel.
我把整个例子放在GitHub:
https://github.com/SuperSludge/aspnetcoreService
有人做过这样的事吗?我完全走错了路吗?将整个 windows 服务重写为 ASP.NET 核心应用程序是否更容易?
如果你想在你的服务中使用 REST Api,你应该在服务项目中添加 WebApi,而不是在不同的项目中。因此,在这种情况下,我认为您不能使用 Asp.Net Core。
使用 Owin 在服务中启动 Rest Api 并在另一个线程中启动服务 运行。
// declare baseUrl in confing file by ex
// Startup is your Startup class
using (WebApp.Start<Startup>(baseUrl))
{
System.Console.WriteLine($"Listening on {baseUrl}");
Thread.Sleep(Timeout.Infinite);
}
Imo,你应该有另一个服务 运行 这个 API,这样你就可以使用 Asp.Net.Core.
Windows 服务执行一些逻辑,WebApi 使用相同的业务 Api 来干扰相同的 Db。
Do you need ASP.NET core application or just expose REST endpoints ? I am thinking you are trying to use it for the benefits of the library. If latter is true,
I have done a similar thing where we have exposed some REST endpoints hosted in our legacy Windows service through "Microsoft.Owin.Hosting". This looks exactly like the ASP.NET WEPAPI
1) In your windows service, you can start the WebApp like
//WEBAPI URL
private const string WEBAPI_BASEADDRESS = "https://+:{port number}/";
// declare a Idisposable variable
private IDisposable webAPI;
//Use Microsoft Owin's library to start it up
webAPI = WebApp.Start<Startup>(url: WEBAPI_BASEADDRESS);
//above "Startup" is a class you would declare in your other class library (see below number 2)
2) You can create a new C# class library with a class named "Startup" and use the system.Web.Http "Httpconfiguration" class as below
/// <summary>
/// Web API startup method
/// </summary>
public class Startup
{
private const string TOKEN_URL = "/api/token";
private const string BASE_URL = "/api/{controller}/{id}";
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: BASE_URL,
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(TOKEN_URL),
Provider = new CustomAuthorizationServerProvider()
});
appBuilder.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
//Swagger support
SwaggerConfig.Register(config);
//appBuilder.UseCors(CorsOptions.AllowAll);
appBuilder.UseWebApi(config);
}
}
3) Above code has a CustomAuthorizationProvider where you can declare your own Custom OAuth Authorization and do any kind of authentication you want as below
public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider
and override the "`public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)`"
4) Then you can just spin up WebAPI controllers
[Authorize]
public class XXXController : ApiController
{
}
Hope this helps . Let me know if something is not clear.
我有一个现有的 windows 服务。目标是有一个 REST 接口来与此服务通信。我认为只制作一个 ASP.NET 核心 Web 应用程序(参见屏幕截图)并在我现有的服务中启动整个应用程序可能是个好主意。然后他们可以共享相同的 IOC 容器等等。
然后我用sc create s1 binPath = "pathgoeshere"
当我启动服务(附加到调试进程)时,我在输出中收到错误 window:
Exception thrown: 'System.DllNotFoundException' in Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll
The thread 0x5250 has exited with code 0 (0x0).
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
'WindowsService1.exe' (CLR v4.0.30319: WindowsService1.exe): Loaded 'C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.ServiceProcess.resources\v4.0_4.0.0.0_de_b03f5f7f11d50a3a\System.ServiceProcess.resources.dll'. Module was built without symbols.
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
The thread 0x4fa0 has exited with code 0 (0x0).
Microsoft.AspNetCore.Server.Kestrel: Warning: Unable to bind to http://localhost:5000 on the IPv4 loopback interface: 'Die DLL "libuv": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.'.
Exception thrown: 'System.DllNotFoundException' in Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll
The thread 0x58c4 has exited with code 0 (0x0).
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Exception thrown: 'System.DllNotFoundException' in mscorlib.dll
Microsoft.AspNetCore.Server.Kestrel: Warning: Unable to bind to http://localhost:5000 on the IPv6 loopback interface: 'Die DLL "libuv": Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E) kann nicht geladen werden.'.
Exception thrown: 'System.IO.IOException' in Microsoft.AspNetCore.Server.Kestrel.Core.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Exception thrown: 'System.IO.IOException' in mscorlib.dll
Microsoft.AspNetCore.Server.Kestrel: Critical: Unable to start Kestrel.
我把整个例子放在GitHub:
https://github.com/SuperSludge/aspnetcoreService
有人做过这样的事吗?我完全走错了路吗?将整个 windows 服务重写为 ASP.NET 核心应用程序是否更容易?
如果你想在你的服务中使用 REST Api,你应该在服务项目中添加 WebApi,而不是在不同的项目中。因此,在这种情况下,我认为您不能使用 Asp.Net Core。
使用 Owin 在服务中启动 Rest Api 并在另一个线程中启动服务 运行。
// declare baseUrl in confing file by ex
// Startup is your Startup class
using (WebApp.Start<Startup>(baseUrl))
{
System.Console.WriteLine($"Listening on {baseUrl}");
Thread.Sleep(Timeout.Infinite);
}
Imo,你应该有另一个服务 运行 这个 API,这样你就可以使用 Asp.Net.Core.
Windows 服务执行一些逻辑,WebApi 使用相同的业务 Api 来干扰相同的 Db。
Do you need ASP.NET core application or just expose REST endpoints ? I am thinking you are trying to use it for the benefits of the library. If latter is true,
I have done a similar thing where we have exposed some REST endpoints hosted in our legacy Windows service through "Microsoft.Owin.Hosting". This looks exactly like the ASP.NET WEPAPI
1) In your windows service, you can start the WebApp like
//WEBAPI URL
private const string WEBAPI_BASEADDRESS = "https://+:{port number}/";
// declare a Idisposable variable
private IDisposable webAPI;
//Use Microsoft Owin's library to start it up
webAPI = WebApp.Start<Startup>(url: WEBAPI_BASEADDRESS);
//above "Startup" is a class you would declare in your other class library (see below number 2)
2) You can create a new C# class library with a class named "Startup" and use the system.Web.Http "Httpconfiguration" class as below
/// <summary>
/// Web API startup method
/// </summary>
public class Startup
{
private const string TOKEN_URL = "/api/token";
private const string BASE_URL = "/api/{controller}/{id}";
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: BASE_URL,
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString(TOKEN_URL),
Provider = new CustomAuthorizationServerProvider()
});
appBuilder.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
//Swagger support
SwaggerConfig.Register(config);
//appBuilder.UseCors(CorsOptions.AllowAll);
appBuilder.UseWebApi(config);
}
}
3) Above code has a CustomAuthorizationProvider where you can declare your own Custom OAuth Authorization and do any kind of authentication you want as below
public class CustomAuthorizationServerProvider : OAuthAuthorizationServerProvider
and override the "`public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)`"
4) Then you can just spin up WebAPI controllers
[Authorize]
public class XXXController : ApiController
{
}
Hope this helps . Let me know if something is not clear.