当前位置:   article > 正文

.NET WebService \ WCF \ WebAPI 部署总结 以及 window 服务 调试,webservice 的安全验证 认证_wcf web api iis

wcf web api iis

一、webservice 部署只能部署IIS上,
比较简单,就不做说明了
安全验证:

  1. Form
  2. window身份
  3. 加个参数,token 定时更新
  4. 可以Soapheader
    在这里插入图片描述

》》》soapheader验证
首先要新建一个类
且这个类必须继承SoapHeader类
且这个类型必须有一个无参的构造函数

 public class CustomSoapHeader:System.Web.Services.Protocols.SoapHeader
    {
     public string UserName{ get; set; }
        public string PassWord{ get; set; }
       // 必须有一个无参的构造函数
       public CustomSoapHeader()
       {}
       
       public CustomSoapHeader( string userName,string passWord)
       {
       this.UserName=userName;
       this.PassWord=passWord;
       }
       public  bool Validate()
       {
          // 要从数据库取数 判断的 
           if(this.UserName = xxx && this.PassWord == xxxx)
           return true;
           else
           {
           }
       }
    }
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

然后再 webService中

       public CustomSoapHeader custheader;
         //在需要的方法上添加SoapHeader 特性
        [WebMethod]
        // 定义SoapHeader传递的方向
        //SoapHeaderDirection.In;只发送SoapHeader到服务端,该值是默认值
         //SoapHeaderDirection.Out;只发送SoapHeader到客户端
        //SoapHeaderDirection.InOut;发送SoapHeader到服务端和客户端
         //SoapHeaderDirection.Fault;服务端方法异常的话,会发送异常信息到客户端      
        [SoapHeader("custheader"),Direction = SoapHeaderDirection.InOut)
        public bool UserLoad()
        {
          if(custheader.Validate())
          {
            if (custheader.Name == "admin" && custheader.Pwd == "123")
            {
                return true;
            }
            else
            {
                return false;
            }
           }else {
           throw new SoapException("身份验证失败",SoapHeaderException.ServerFault.Code)
           }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在上面代码中需要注意的是,Web Servies中的Web方法需要抛出SoapExcetion异常才能被客户端捕获到,如果在Debug模式下调试运行的话,还需要在异常设置里把这个异常勾选掉,即编译器不对该异常进行捕获。

要调用这个web Service中的UserLoad 方法,需要传递 CustomSoapHeader 对象参数,客户端使用服务端的UserLoad方法,需要传递CustomSoapHeader

//客户端
        WebServiceClient  client = new WebServiceClient ();//web引用
        CustomSoapHeader  Header = new CustomSoapHeader ();//web引用创建soap头对象  
        //设置soap头变量  
        Header.UserName = "zen";  
        Header.PassWord = "123456";  
        client.custheader= Header;  
        //调用web 方法  
        Response.Write(client.UserLoad()); 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

》》》

添加 token 校验安全

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、 WCF 部署 1

在这里插入图片描述

 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="metadataBehavior">
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="metadataBehavior" name ="Services.HelloWorldService">
        <endpoint binding="wsHttpBinding"
                  contract="Contract.IHelloWorld"/>
      </service>
    </services>
  </system.serviceModel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

wcf 重载

》》每个Operation由一个operation XML Element表示,而每个Operation还应该具有一个能够唯一表示该Operation的ID,这个ID则是通过name属性来定义。Operation元素的Name属性通常使用方法名来定义,所以,如果WCF服务契约中,包含两个相同的操作方法名时,此时就违背了WSDL的规定,这也是WCF不可以使用操作重载的原因。
在这里插入图片描述
》》》 d

namespace xxx
{
    [ServiceContract]
    public interface IHelloWorld
    {
        [OperationContract(Name = "GetHelloWorldWithoutParam")]
        string GetHelloWorld();

        [OperationContract(Name = "GetHelloWorldWithParam")]
        string GetHelloWorld(string name);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

》》》》 wcf 配置信息

<?xml version="1.0" encoding="utf-8"?>
 <configuration>
   <system.serviceModel>

     <!--配置服务和终结点开始-->
     <services>
       <service>
         <endpoint></endpoint>
       </service>
     </services>
     <!--配置服务和终结点结束-->

     <!--配置绑定开始-->
     <bindings>
       <netTcpBinding>
         <binding>
         </binding>
       </netTcpBinding>
     </bindings>
     <!--配置绑定结束-->

     <!--配置行为开始-->
     <behaviors>
       <serviceBehaviors>
         <behavior>
         </behavior>
       </serviceBehaviors>
     </behaviors>
     <!--配置行为结束-->

   </system.serviceModel>
 </configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

在这里插入图片描述

  <system.serviceModel>
    <!--服务-->
    <services>
      <!--name:名称空间.类型名-->
      <!--behaviorConfiguration:behavior的名称,请看behavior配置节的名称-->
      <service name="WCFLibrary.User" behaviorConfiguration="MyBehavior">
        <host>
          <baseAddresses>
            <!-- 每种传输协议的baseAddress,用于跟使用同样传输协议Endpoint定义的相对地址组成完整的地址,
                 每种传输协议只能定义一个baseAddress。HTTP的baseAddress同时是service对外发布服务说明页面的URL -->
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFLibrary/Service/"/>
          </baseAddresses>
        </host>
        <!-- 除非完全限定,否则地址将与上面提供的基址相关,每个服务可以有多个Endpoint -->
        <!-- Address:指定这个Endpoint对外的URI,这个URI可以是个绝对地址,也可以是个相对于baseAddress的
                      相对地址。如果此属性为空,则这个Endpoint的地址就是baseAddress-->
        <!--bindingConfiguration:binding的名称,请看binding配置节的名称-->
        <endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser" bindingConfiguration="myHttpBinding">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
      </service>
    </services>


    <!--绑定-->
    <bindings>
      <wsHttpBinding>
        <binding name="myHttpBinding">
          <security mode="None">
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>


    <!--行为-->
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyBehavior">
          <!-- httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据 -->
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

using System.ServiceModel; //服务契约
using System.Runtime.Serialization; //数据契约
》》》 服务契约

 [ServiceContract]
    public interface ISayHi
    {
        [OperationContract]
        string ToSayHi();
        /// <summary>
        /// 自我介绍
        /// </summary>
        /// <param name="person">个人信息</param>
        /// <returns>返回个人介绍</returns>
        [OperationContract]
        string Introduce(Person person);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

》》》》 数据契约

  [DataContract]
    public class Person
    {
        [DataMember(Name="ShortName")] //定义别名
        public string Name { get; set; }
        [DataMember]
        public int Age { get; set; }
        [DataMember]
        public string Country { get; set; }
 
        public string Introduce()
        {
            return string.Format("Hello,my name is {0}.I am {1} years old.I am from {2}.", Name, Age, Country);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

注意DataMember属性,可以控制字段的可见性。默认是都可见,如果DataMember属性在类中出现,则没有添加该属性的字段不可见。

部署到IIS 跟部署 webservice 部署方法一样的
wcf 部署2
部署到控制台 要以管理员运行vs,或者 管理员运行 控制台的exe
在控制器项目中
创建IUserInfoService 接口

》》》Abort( ) 方法不会抛出异常, 而 Close( )方法则可能抛出 TimeoutException 和 CommunicationException。
在这里插入图片描述

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    [ServiceContract]
    public interface  IUserInfoService
    {
        [OperationContract]
        int Add(int a, int b);
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述
实现接口
在这里插入图片描述
在app.config中增加
在这里插入图片描述

 <system.serviceModel>
    <services>

      <service name="ConsoleApp1.UserInfoService" behaviorConfiguration="behaviorConfiguration">
        <!--服务的对象-->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/"/>
            <!--服务的IP和端口号-->
          </baseAddresses>
        </host>
        <endpoint address="" binding="basicHttpBinding" contract="ConsoleApp1.IUserInfoService"></endpoint>
        <!--contract:服务契约-->
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="behaviorConfiguration">
          <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

《《《启动服务
在这里插入图片描述
在这里插入图片描述

》》》验证是否有效
在这里插入图片描述
》》》如果不放在配置文件中
在这里插入图片描述
》》》

 using (ServiceHost host = new ServiceHost(typeof(UserInfoService)))
            {
                向宿主中添加终结点
                host.AddServiceEndpoint(typeof(IUserInfoService), new WSHttpBinding(), "http://localhost:8686/userinfoservice");
                 if (Host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                {
	                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
	                behavior.HttpGetEnabled = true;
	                behavior.HttpGetUrl = new Uri("http://localhost:8686/userinfoservice/metadata");
	                host.Description.Behaviors.Add(behavior);
	                host.Opened +=delegate
	                { 
	                    Console.WriteLine("服务已启动");
	                };
	                host.Open();             
	                Console.ReadKey();
	                host.Close();
                }
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

或者

           //创建宿主的基地址
            Uri baseAddress = new Uri("http://localhost:8080/User");
            //创建宿主
            using (ServiceHost host = new ServiceHost(typeof(User), baseAddress))
            {
                //向宿主中添加终结点
                host.AddServiceEndpoint(typeof(IUser), new WSHttpBinding(), "");
                //将HttpGetEnabled属性设置为true
                ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
                smb.HttpGetEnabled = true;
                //将行为添加到Behaviors中
                host.Description.Behaviors.Add(smb);
                //打开宿主
                host.Open();
                Console.WriteLine("WCF中的HTTP监听已启动....");
                Console.ReadLine();
                host.Close();
            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

》》》 校验是否成功

在这里插入图片描述
在这里插入图片描述

部署到winform

在这里插入图片描述

 private void button1_Click(object sender, EventArgs e)
        {
            ServiceHost Host = new ServiceHost(typeof(WCF.Student));
            

                //绑定
                System.ServiceModel.Channels.Binding httpBinding = new BasicHttpBinding();
                //终结点
                Host.AddServiceEndpoint(typeof(IWCF.IStudent), httpBinding, "http://localhost:8002/");
                if (Host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
                {
                    //行为
                    ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                    behavior.HttpGetEnabled = true;

                    //元数据地址
                    behavior.HttpGetUrl = new Uri("http://localhost:8002");
                    Host.Description.Behaviors.Add(behavior);

                    //启动
                    Host.Open();

                
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

》》》验证
在这里插入图片描述
app.config 配置


      <service name="WCF.Student" behaviorConfiguration="behaviorConfiguration">
        <!--//服务的对象-->
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:5678"/>
           <!--// 服务的IP和端口号-->
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" contract="IWCF.IStudent"></endpoint>
        <!--//contract:服务契约-->
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior name="behaviorConfiguration">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这里插入图片描述

》》》》验证
在这里插入图片描述

WCF 宿主 服务中

在这里插入图片描述
在这里插入图片描述
》》》 app.config 或者写作code 都行
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
LocalService:充当本地计算机上非特权用户的帐户,该帐户将匿名凭据提供给所有远程服务器。

NetworkService:提供广泛的本地特权的帐户,该帐户将计算机的凭据提供给所有远程服务器。

LocalSystem:服务控制管理员使用的帐户,它具有本地计算机上的许多权限并作为网络上的计算机。

User:由网络上特定的用户定义的帐户。如果为 ServiceProcessInstaller.Account 成员指定 User,则会使系统在安装服务时提示输入有效的用户名和密码,除非您为 ServiceProcessInstaller 实例的 Username 和 Password 这两个属性设置值。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

删除服务

sc delete 服务名称
在这里插入图片描述
在这里插入图片描述

window 服务调试
正常是无法调试的,可以在window服务中做调整
如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  <connectionStrings>
    <!--服务开启时间-->
    <add name="ServiceStart" connectionString="9:00"/>
    <!--服务执行间隔()-->
    <add name="ServiceInterval" connectionString="60"/>
    <!--服务停止时间-->
    <add name="ServiceEnd" connectionString="17:00"/>
    <!--服务是否开启(1开启、0关闭)-->
    <add name="ServiceIsOn" connectionString="0"/>
  </connectionStrings>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

 public partial class Service1 : ServiceBase
    {
 
        //服务配置项
        private static string ServiceStart = ConfigurationManager.ConnectionStrings["ServiceStart"].ConnectionString;
        private static int ServiceInterval = Convert.ToInt32(ConfigurationManager.ConnectionStrings["ServiceInterval"].ConnectionString);
        private static string ServiceEnd = ConfigurationManager.ConnectionStrings["ServiceEnd"].ConnectionString;
        private static string ServiceIsOn = ConfigurationManager.ConnectionStrings["ServiceIsOn"].ConnectionString;
 
        //服务定时器
        private System.Timers.Timer timer = new System.Timers.Timer();
 
        public Service1()
        {
            InitializeComponent();
        }
 
        /// <summary>
        /// 开启服务
        /// </summary>
        /// <param name="args"></param>
        protected override void OnStart(string[] args)
        {
            if (ServiceIsOn == "1")
            {
                timer.Enabled = true;
                timer.Interval = ServiceInterval * 1000;//执行间隔时间,单位为毫秒; 这里实际间隔为1秒钟  
                timer.Start();
                timer.Elapsed += new System.Timers.ElapsedEventHandler(Procedure_Timer);
                Procedure_Timer(null, null);
            }
        }
 
 
        /// <summary>
        /// 定时器执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Procedure_Timer(object sender, System.Timers.ElapsedEventArgs e)
        {
            timer.Enabled = false;
            TestClass service = new TestClass();
 
            DateTime newDate = DateTime.Now;
 
            //获取当前时间
            int intHour = newDate.Hour;
            int intMinute = newDate.Minute;
 
            //开始时间
            string[] startStamp = ServiceStart.Split(':');
            int startHour = Convert.ToInt32(startStamp[0]);
            int startMinute = Convert.ToInt32(startStamp[1]);
 
            //结束时间
            string[] endStamp = ServiceEnd.Split(':');
            int endHour = Convert.ToInt32(endStamp[0]);
            int endMinute = Convert.ToInt32(endStamp[1]);
 
            int newTime = (intHour * 100) + intMinute;
            int startTime = (startHour * 100) + startMinute;
            int endTime = (endHour * 100) + endMinute;
        
            // 每天定点在一个时间段内执行
            if (newTime >= startTime && newTime <= endTime)
            {
                //执行业务代码
                //
            }
 
            timer.Enabled = true;
  
        }
 
 
 
        /// <summary>
        /// 关闭服务
        /// </summary>
        protected override void OnStop()
        {
            timer.Stop();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

》》》wcf 宿主到 服务中 调试方法
在这里插入图片描述

window 服务 卸载

》》》1 在cmd中 录入 sc delete 服务名称 注意注意 是服务名称 不是显示名称

这种方法 不需要 停车服务,可以直接干掉

》》》2、 代码实现
卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑。代码无法停止服务时,使用services.msc来停止。
获取系统所有window 服务
ServiceController[] services = ServiceController.GetServices();

》》》》“Service1.cs”的代码,增加服务启动日志和停止日志。

using CommonUtils;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace ADemoWinSvc
{
    public partial class Service1 : ServiceBase
    {
        public Service1()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
            GLog.WLog("服务已启动");
        }

        protected override void OnStop()
        {
            GLog.WLog("服务已停止");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

》》》》 工具类

using System;
using System.IO;

namespace CommonUtils
{
     
    public static class GLog
    {
        static object _lockObj = new object();

        public static void WLog(string content)
        {
            lock (_lockObj)
            {
                string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
                string logDir = "Logs";
                string logDirFullName = Path.Combine(curPath, logDir);

                try
                {
                    if (!Directory.Exists(logDirFullName))
                        Directory.CreateDirectory(logDirFullName);
                }
                catch { return; }

                string fileName = "Logs" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                string logFullName = Path.Combine(logDirFullName, fileName);

                try
                {
                    using (FileStream fs = new FileStream(logFullName, FileMode.Append, FileAccess.Write))
                    using (StreamWriter sw = new StreamWriter(fs))
                        sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + content);
                }
                catch { return; }

            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

========= 上面代码都是 服务中的

下面代码 是winForm程序中的==
在这里插入图片描述

using CommonUtils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Windows服务操作
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// windows服务名
        /// </summary>
        static string _winSvcName = "ADemoWinSvc";

        /// <summary>
        /// windows服务对应的exe 名
        /// </summary>
        static string _winSvcExeName = "ADemoWinSvc.exe";

        private void btnSetup_Click(object sender, EventArgs e)
        {
            try
            {
                //是否存在服务
                if (ServiceUtil.ServiceIsExisted(_winSvcName))
                {
                    //已存在,检查是否启动
                    if (ServiceUtil.IsRun(_winSvcName))
                    {
                        //服务是已启动状态
                        lblMsg.Text = "[001]服务是已启动状态";
                    }
                    else
                    {
                        //未启动,则启动
                        ServiceUtil.StarService(_winSvcName);
                        lblMsg.Text = "[002]服务是已启动状态";
                    }
                }
                else
                {
                    //不存在,则安装
                    IDictionary mySavedState = new Hashtable();
                    string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
                    string apppath = Path.Combine(curPath, _winSvcExeName);
                    ServiceUtil.InstallService(mySavedState, apppath);

                    lblMsg.Text = "[003]服务是已启动状态";

                    //安装后并不会自动启动。需要启动这个服务
                    ServiceUtil.StarService(_winSvcName);

                    lblMsg.Text = "[004]服务是已启动状态";
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnUninstall_Click(object sender, EventArgs e)
        {
            //** 卸载服务最重要的是先停止,否则电脑需要重启或注销 **
            try
            {
                //是否存在服务
                if (!ServiceUtil.ServiceIsExisted(_winSvcName))
                {
                    MessageBox.Show("服务不存在,不需要卸载");
                    return;
                }

                //如果服务正在运行,停止它
                if (ServiceUtil.IsRun(_winSvcName))
                {
                    ServiceUtil.StopService(_winSvcName);
                }
                //再检查一次是否在运行
                if (ServiceUtil.IsRun(_winSvcName))
                {
                    MessageBox.Show("服务无法停止,请手动停止这个服务");
                    return;
                }
                //卸载
                ServiceUtil.UnInstallServiceByName(_winSvcName);

                lblMsg.Text = "[005]服务已卸载";

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

》》》》》
AssemblyInstaller 帮助文件
https://learn.microsoft.com/zh-cn/dotnet/api/system.configuration.install.assemblyinstaller?view=netframework-4.8.1

》》》》 工具类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration.Install;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace CommonUtils
{
    /// <summary>
    /// windows服务操作工具类
    /// </summary>
    public static class ServiceUtil
    {
        /// <summary>
        /// 服务是否正在运行
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool IsRun(string name)
        {
            bool IsRun = false;
            try
            {
                if (!ServiceIsExisted(name)) return false;
                var sc = new ServiceController(name);
                if (sc.Status == ServiceControllerStatus.StartPending || sc.Status == ServiceControllerStatus.Running)
                {
                    IsRun = true;
                }
                sc.Close();
            }
            catch
            {
                IsRun = false;
            }
            return IsRun;
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool StarService(string name)
        {
            try
            {
                var sc = new ServiceController(name);
                if (sc.Status == ServiceControllerStatus.Stopped || sc.Status == ServiceControllerStatus.StopPending)
                {
                    sc.Start();
                    sc.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));
                }
                else
                {

                }
                sc.Close();
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 停止服务(有可能超时)
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool StopService(string name)
        {
            try
            {
                var sc = new ServiceController(name);
                if (sc.Status == ServiceControllerStatus.Running || sc.Status == ServiceControllerStatus.StartPending)
                {
                    sc.Stop();
                    //停止服务超时时间:56秒。
                    sc.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0, 0, 56));
                }
                else
                {

                }
                sc.Close();
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static bool ServiceIsExisted(string serviceName)
        {
            ServiceController[] services = ServiceController.GetServices();
            foreach (ServiceController s in services)
                if (s.ServiceName.ToLower() == serviceName.ToLower())
                    return true;
            return false;
        }

        /// <summary>
        /// 安装
        /// </summary>
        /// <param name="stateSaver"></param>
        /// <param name="filepath"></param>
        public static void InstallService(IDictionary stateSaver, string filepath)
        {
            try
            {
                AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();
                myAssemblyInstaller.UseNewContext = true;
                myAssemblyInstaller.Path = filepath;
                myAssemblyInstaller.Install(stateSaver);
                myAssemblyInstaller.Commit(stateSaver);
                myAssemblyInstaller.Dispose();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 使用路径卸载(有时候不便于用路径来卸载,则使用SC DELETE 名称来卸载)
        /// </summary>
        /// <param name="filepath"></param>
        public static void UnInstallService(string filepath)
        {
            try
            {
                AssemblyInstaller myAssemblyInstaller = new AssemblyInstaller();
                myAssemblyInstaller.UseNewContext = true;
                myAssemblyInstaller.Path = filepath;
                myAssemblyInstaller.Uninstall(null);
                myAssemblyInstaller.Dispose();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 使用windows服务名卸载
        /// </summary>
        /// <param name="WinServiceName"></param>
        public static void UnInstallServiceByName(string WinServiceName)
        {
            ProcessStartInfo pStart = new ProcessStartInfo("sc.exe");
            Process pRoc = new Process();

            pStart.Arguments = " delete " + WinServiceName;
            pStart.UseShellExecute = false;
            pStart.CreateNoWindow = false;

            pRoc.StartInfo = pStart;
            pRoc.Start();
            pRoc.WaitForExit();
        }





        

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
wcf 服务 部署之后,测试

在这里插入图片描述

在这里插入图片描述
》》》或者通过SvcUtil.exe 生成代理类

会生成 两个文件
》xxxx.cs 类
》 xxx.config
将 xxx.config 中的内容copy到 程序目录下 App.config
同时将这个xxx.cs 类添加到 项目中
添加引用 System.Runtime.Serialization、System.ServiceModel ;
这个项目就可以使用wcf的服务啦

WebAPI 部署

部署 IIS

跟wcf 、webservice 一样。

部署 控制台

安装
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

 static void Main(string[] args)
        {
           
            RegisterWebApi("http://localhost:4554");
        }

        private static void RegisterWebApi(string url)
        {
          
                var config = new HttpSelfHostConfiguration(url);

                config.Routes.MapHttpRoute(
                    "API Default", 
                    "api/{controller}/{action}/{id}",
                    new { id = RouteParameter.Optional });

                using (HttpSelfHostServer server = new HttpSelfHostServer(config))
                {
                    server.OpenAsync().Wait();
                    Console.WriteLine("Press Enter to quit.");
                    Console.ReadLine();
                }
         

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

在这里插入图片描述

webapi 路由 一般没有 action 符合 RESETFUL 风格
在这里插入图片描述
》》》》》 部署到 winForm
安装如下:
在这里插入图片描述

在这里插入图片描述
添加控制器》》》
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

window 服务 也一样的

上面都说 selfhost

下面介绍》》》》 OwinSelfHost

OwinSelfHost

安装

注意注意 注意
是 Microsoft.AspNet.WebApi.oWinSelfHost
在这里插入图片描述

》》》添加Owin启动类
在这里插入图片描述
》》创建好 Owin Startup 如下

// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
            // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
            HttpConfiguration config = new HttpConfiguration();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{Controller}/{action}/{id}",
                defaults: new
                {
                    id = RouteParameter.Optional
                });

            app.UseWebApi(config);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述
》》》》 新建控制器

在这里插入图片描述

》》》在Program中写入如下代码
在这里插入图片描述

 static void Main(string[] args)
        {

            string baseAddress = "http://localhost:9527/";
            using (WebApp.Start(url: baseAddress))
            {
                Console.WriteLine("请开始您的表演");
                Console.ReadLine();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

》》》 验证
在这里插入图片描述

webapi 部署到 window 服务

首先 新建 window服务程序

在这里插入图片描述

步骤跟上面一样的
至少 服务启动 要 OnStart

在这里插入图片描述

》》》》安装 服务
在这里插入图片描述
在这里插入图片描述

》》》 window Form 部署方法一样

优缺点

Web Services SOAP、UDDI、WSDL
优点:
跨平台:Web Services完全基于XML(可扩展标记语言)、XSD(XMLSchema)等与平台无关的行业标准。
自描述:Web Service使用WSDL进行自我描述,包括服务的方法、参数、类型和返回值等相关信息。
跨防火墙:Web Service使用http协议进行通信,可以穿越防火墙。
缺点:
效率低下,不适合做单应用系统的开发。
安全问题:Web Services没有自身的安全机制,必须借助Http协议或IIS等宿主程序实现信息安全加密。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/996384
推荐阅读
相关标签
  

闽ICP备14008679号