建立3个项目,分别是类库WebSite、控制台TestWebSite、win服务WinService,目标框架均为.NET Framework 4.8.1。

其中控制台方便开发调试,win服务作为宿主服务,类库为自定义webservice的主体代码。

TestWebSite和WinService 引用nuget包 Microsoft.Owin.Host.HttpListener  4.2.2,不然启动的时候会提示错误消息:

The server factory could not be located for the given input

WebSite引用nuget包:

Microsoft.AspNet.Cors
Microsoft.AspNet.WebApi.Core
Microsoft.Owin
Microsoft.AspNet.WebApi.Owin
Microsoft.AspNet.WebApi.Cors
Microsoft.AspNet.WebApi.WebHost
Microsoft.AspNet.WebApi.SelfHost
Microsoft.Owin.Host.HttpListener
Microsoft.Owin.Hosting
Newtonsoft.Json

在WebSite中增加目录Controllers和wwwroot

using System;
using System.Web.Http;

namespace ConfigTool.WebSite.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : ApiController
    {
        [HttpGet]
        [Route("Time")]
        public string Time()
        {
            return DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
        }

    }
}

在wwwroot下放入index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
</script>
</head>
<body>
    <p>
        <input type="text" id="curtime" value="1"/>
        <button id="submit">从api接口获取当前服务器时间</button>
    </p>
    <p>
        <image src="images/1.jpg" alt="验证静态资源" width="300" height="300"/>
    </p>
</body>

<script>
    $("#submit").click(function(){
        $.get("api/Values/Time",function(data,status){    
            $("#curtime").val(data);
        });
    });
</script>
</html>

新增Startup类文件

using Microsoft.Owin;
using Owin;
using System;
using System.IO;
using System.Net.Http.Formatting;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Cors;


namespace ConfigTool.WebSite
{
    internal class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = InitWebApiConfig();
            app.UseWebApi(config);
            //静态文件
            app.Use((context, fun) =>
            {
                return StaticFileHandler(context, fun);
            });
        }

        /// <summary>
        /// 路由初始化
        /// </summary>
        HttpConfiguration InitWebApiConfig()
        {
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "Default",
                routeTemplate: "api/{controller}/{action}",
                defaults: new { id = RouteParameter.Optional }
            );

            var cors = new EnableCorsAttribute("*", "*", "*");//跨域允许设置
            config.EnableCors(cors);

            config.Formatters
               .XmlFormatter.SupportedMediaTypes.Clear();
            //默认返回json
            config.Formatters
                .JsonFormatter.MediaTypeMappings.Add(
                new QueryStringMapping("datatype", "json", "application/json"));

            config.Formatters
                .XmlFormatter.MediaTypeMappings.Add(
                new QueryStringMapping("datatype", "xml", "application/xml"));

            config.Formatters
                .JsonFormatter.SerializerSettings = new
                Newtonsoft.Json.JsonSerializerSettings()
                {
                    DateFormatString = "yyyy-MM-dd HH:mm:ss"
                };
            return config;
        }

        /// <summary>
        /// 客户端请求静态文件处理
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public Task StaticFileHandler(IOwinContext context, Func<Task> next)
        {
            //获取物理文件路径
            var path = GetFilePath(context.Request.Path.Value);
            //验证路径是否存在
            if (!File.Exists(path) && !path.EndsWith("html"))
            {
                path += ".html";
            }
            if (File.Exists(path))
            {
                return StaticFileResponse(context, path);
            }
            //不存在,返回下一个请求
            return next();
        }

        static string GetFilePath(string path)
        {
            var basePath = AppDomain.CurrentDomain.BaseDirectory;
            var filePath = path.TrimStart('/').Replace('/', '\\');
            return Path.Combine(basePath, "wwwroot", filePath);
        }

        Task StaticFileResponse(IOwinContext context, string path)
        {
            /*
                .txt text/plain
                RTF文本 .rtf application/rtf
                PDF文档 .pdf application/pdf
                Microsoft Word文件 .word application/msword
                PNG图像 .png image/png
                GIF图形 .gif image/gif
                JPEG图形 .jpeg,.jpg image/jpeg
                au声音文件 .au audio/basic
                MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
                RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
                MPEG文件 .mpg,.mpeg video/mpeg
                AVI文件 .avi video/x-msvideo
                GZIP文件 .gz application/x-gzip
                TAR文件 .tar application/x-tar
                任意的二进制数据 application/octet-stream
             */
            var perfix = Path.GetExtension(path);
            if (perfix == ".html")
                context.Response.ContentType = "text/html; charset=utf-8";
            else if (perfix == ".txt")
                context.Response.ContentType = "text/plain";
            else if (perfix == ".js")
                context.Response.ContentType = "application/x-javascript";
            else if (perfix == ".css")
                context.Response.ContentType = "text/css";
            else
            {
                if (perfix == ".jpeg" || perfix == ".jpg")
                    context.Response.ContentType = "image/jpeg";
                else if (perfix == ".gif")
                    context.Response.ContentType = "image/gif";
                else if (perfix == ".png")
                    context.Response.ContentType = "image/png";
                else if (perfix == ".svg")
                    context.Response.ContentType = "image/svg+xml";
                else if (perfix == ".woff")
                    context.Response.ContentType = "application/font-woff";
                else if (perfix == ".woff2")
                    context.Response.ContentType = "application/font-woff2";
                else if (perfix == ".ttf")
                    context.Response.ContentType = "application/octet-stream";
                else
                    context.Response.ContentType = "application/octet-stream";

                return context.Response.WriteAsync(File.ReadAllBytes(path));
            }
            return context.Response.WriteAsync(File.ReadAllText(path));
        }

    }
}

新增WebServer类文件

using Microsoft.Owin.Hosting;
using System;

namespace ConfigTool.WebSite
{
    public class WebServer : IDisposable
    {
        IDisposable server;
        int port = 8080;
        public WebServer(int port)
        {
            this.port = port;
        }

        public void Start()
        {
            Console.WriteLine("WebServer Starting");
            var host = "*";
            var addr = $"http://{host}:{port}";
            server = WebApp.Start<Startup>(url: addr);
            Console.WriteLine($"WebServer Started @ {addr}");
        }


        public void Stop()
        {
            Console.WriteLine("WebServer Stopping");
            server.Dispose();
            Console.WriteLine("WebServer Stopped");
        }


        public void Dispose()
        {
            server?.Dispose();
        }

    }
}

修改控制台程序TestWebSite的Program.cs文件代码如下:

using ConfigTool.WebSite;
using System;

namespace ConfigTool.TestWebSite
{
    internal class Program
    {
        static void Main(string[] args)
        {
            WebServer server = new WebServer(8080);
            server.Start();

            Console.ReadLine();
        }
    }
}

修改win服务程序WinService的MainService.cs(默认Service1.cs)文件代码如下:

using ConfigTool.WebSite;
using System.Configuration;
using System.ServiceProcess;

namespace ConfigTool.WinService
{
    public partial class MainService : ServiceBase
    {
        public MainService()
        {
            InitializeComponent();
        }
        WebServer server;
        protected override void OnStart(string[] args)
        {
            var port = ConfigurationManager.AppSettings.Get("PORT");
            if (!int.TryParse(port, out int iport))
            {
                iport = 5000;
            }
            server = new WebServer(iport);
            server.Start();
        }

        protected override void OnStop()
        {
            server?.Stop();
        }
    }
}

编写服务安装卸载脚本

echo.service installing......  
echo off  
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe "ConfigTool.WinService.exe"
@sc config ConfigTool.WinService start= auto
@net Start ConfigTool.WinService
echo on  
echo.service started
pause
echo.uninstall service......  
echo off  
@net Stop ConfigTool.WinService
%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe /u "ConfigTool.WinService.exe"
echo on
echo.service uninstalled 
pause

 

 posted on 2024-06-04 18:59  Lucien.Bao  阅读(11)  评论(0编辑  收藏  举报