代码之家  ›  专栏  ›  技术社区  ›  Mat

如何从现有windows服务启动AspNetCore应用程序

  •  1
  • Mat  · 技术社区  · 6 年前

    我有一个现有的windows服务。目标是有一个REST接口来与此服务通信。我想这可能是一个好主意,只需制作一个ASP.NET核心Web应用程序(见屏幕截图),然后在我现有的服务中简单地启动整个过程。然后他们可以共享同一个IOC容器等等。

    enter image description here

    然后我在 sc create s1 binPath = "pathgoeshere"

    当我启动服务(附加到进程以进行调试)时,在输出窗口中收到一个错误:

    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核心应用程序是否更容易?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Zysce myrtle303    6 年前

    如果希望在服务中包含REST Api,则应将WebApi添加到服务项目中,而不是添加到其他项目中。所以,在这种情况下,我认为你不能使用Asp.Net核心。

    // 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。

        2
  •  2
  •   Kaushik Srinath    6 年前
    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.