点晴MIS问题教程区 加入收藏
问题搜索
 您的位置:点晴MIS系统问题答疑『 经验分享&问题答疑 』浏览当前教程  
  

  网站搜索
  搜索范围: 搜索方式: 关键词(可用空格分开)  

  作者及文章信息: 本文热度:80 % 
admin

积分:72590
等级:网站管理员
文数:14124
注册:2004-7-20

 信息   主页   编辑     

楼 顶 

 C# IIS一键部署完整参数版(微软类库)


前言:

在我们开发一个Web项目的时候,我们需要把项目打包发布到IIS,大概流程是这样的打包项目放到一个目录下,IIS管理器添加项目指定打包好的项目路径等一系列操作,这样会是不是会让大家感觉到很烦?这一系列操作给我的感觉肯定是很烦的点来点去,能不能就是说我点一下能能把我想发布的路径发布出去。答案:能!

在这篇纹章中给大家带来一个IIS一键部署的小工具的实现以及个人的开发思路告诉大家,好了话不多说准备开干!

 

一、思路:

在本章节中,小编想到的是做成一个配置化发布工具,也就是说通过一个配置文件(json,config)配置好发布的信息,控制台程序运行一下就可以发布出去!


直接上代码和操作图:

打开IIS - 应用程序池 - 右键一个程序池 - 高级设置

打开了之后是不是又很多参数可以配置应用程序池的信息,每个网站都要对应一个程序池这个步骤很关键!

红色箭头是表示,可以在类库中找到对应项的参数配置,方便我们开发!

直接上核心代码了:

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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
usingMicrosoft.Web.Administration;
usingNewtonsoft.Json;
usingNewtonsoft.Json.Linq;
usingoneKeyDeployment.Common.config;
usingoneKeyDeployment.Model;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Configuration;
usingSystem.IO;
usingSystem.Linq;
usingSystem.Security.Cryptography.X509Certificates;
usingSystem.ServiceProcess;
usingSystem.Text;
usingSystem.Threading.Tasks;
 
namespaceoneKeyDeployment.Common
{
    /// <summary>
    /// 网站发布帮助类
    /// </summary>
    publicclassPublishWebHelper
    {
        /// <summary>
        /// 执行一键部署(单个网站部署)
        /// </summary>
        /// <returns></returns>
        publicstaticvoidexecute()
        {
            //IIS 配置信息
            varconfig = GetIISConfig();
            varvDir = config.VDir;
            varapp = config.Applications;
            //程序池配置信息
            varpoolsConfig = config.ApplicationPools;
            variismanager = createServerManager(config);
 
            //创建虚拟目录
            if(vDir !=null&& vDir.Count() > 0)
            {
                foreach(vardirinvDir)
                {
                    createVDir(config.WebName, dir.DirName, dir.PhysicalPath, iismanager);
                }
            }
            //创建子程序虚拟目录
            foreach(variteminapp)
            {
                foreach(vardirinitem.VDir)
                {
                    createSubitemVDir(config.WebName, item.Path, dir.DirName, dir.PhysicalPath, iismanager);
                }
            }
            Console.WriteLine("---------------- 程序池 Start ----------------");
            //创建程序池
            foreach(variteminpoolsConfig)
            {
                createApplicationPool(item, iismanager);
            }
            Console.WriteLine("---------------- 程序池 End ----------------");
            //提交保存
            CommitChanges(iismanager);
        }
 
        /// <summary>
        /// 创建应用程序
        /// </summary>
        /// <param name="config"></param>
        /// <returns></returns>
        privatestaticServerManager createServerManager(IISConfig config)
        {
            varApplicationsConfig = config.Applications;
 
            ServiceController service = ServiceController.GetServices("127.0.0.1").FirstOrDefault(x => x.ServiceName =="W3SVC");
 
            if(serviceisnull)
            {
                Console.WriteLine("服务器尚未安装 IIS 服务模块!");
                returnnull;
            }
 
            if(!System.IO.Directory.Exists(config.WebsiteDirectory))
            {
                Console.WriteLine("指定目录不存在!");
                returnnull;
            }
            ServerManager iismanager =newServerManager();
            //判断web应用程序是否存在
            if(iismanager.Sites[config.WebName] !=null)
            {
                ///移除应用程序
                iismanager.Sites.Remove(iismanager.Sites[config.WebName]);
            }
            //建立web应用程序(第二个参数为安装文件的地址)
            varsite = iismanager.Sites.Add(config.WebName, config.WebsiteDirectory, config.Port);
 
            Console.WriteLine("---------------- 主应用程序 Start ----------------");
            Console.WriteLine($"网站名称:{config.ServerDomainName}");
            Console.WriteLine($"端口:{config.Port}");
            Console.WriteLine($"服务器域名:{config.ServerDomainName}");
            Console.WriteLine($"网站目录:{config.WebsiteDirectory}");
            Console.WriteLine($"程序池名称:{config.ApplicationPoolName}");
            Console.WriteLine("---------------- 主应用程序 End ----------------");
 
            Console.WriteLine("---------------- 子程序 Start ----------------");
            //设置子程序 - 应用程序池
            foreach(variteminApplicationsConfig)
            {
                varapplication = site.Applications.Add("/"+ item.Path, item.PhysicalPath);
                application.ApplicationPoolName = item.ApplicationPoolName;
                Console.WriteLine("****************************** ↓");
                Console.WriteLine($"子程序路径名称:/{item.Path}");
                Console.WriteLine($"物理路径:{item.PhysicalPath}");
            }
            Console.WriteLine("---------------- 子程序 End ----------------");
            //设置web网站的应用程序池
            varwebsite = iismanager.Sites[config.WebName];
            website.Applications["/"].ApplicationPoolName = config.ApplicationPoolName;
            if(!string.IsNullOrEmpty(config.ServerDomainName))
            {
                stringstr = website.Bindings[0].Host.Split(newchar[] {'.'})[0];
                stringbindingInformation = $"*:{config.Port}:{str}{config.ServerDomainName}";
                website.Bindings.Add(bindingInformation,"http");
            }
            returniismanager;
        }
 
        /// <summary>
        /// 提交更改
        /// </summary>
        /// <param name="iismanager"></param>
        privatestaticvoidCommitChanges(ServerManager iismanager)
        {
            //提交更改
            iismanager.CommitChanges();
        }
 
 
        /// <summary>
        /// 创建程序池
        /// </summary>
        /// <param name="pool"></param>
        privatestaticvoidcreateApplicationPool(Model.ApplicationPool poolConfig, ServerManager iismanager)
        {
            //判断应用程序池是否存在
            if(iismanager.ApplicationPools[poolConfig.Name] !=null)
            {
                //移除应用程序池
                iismanager.ApplicationPools.Remove(iismanager.ApplicationPools[poolConfig.Name]);
            }
 
            //cpu
            varcpuConfig = poolConfig.Cpu;
            //回收
            varrecyclingConfig = poolConfig.Recycling;
            //定期重启
            varperiodicRestartConfig = poolConfig.Recycling.PeriodicRestart;
            //进程孤立
            varfailureConfig = poolConfig.Failure;
            //进程模型
            varprocessModelConfig = poolConfig.ProcessModel;
 
            Microsoft.Web.Administration.ApplicationPool pool = iismanager.ApplicationPools.Add(poolConfig.Name);
            pool.Name = poolConfig.Name;// 程序池名字
            pool.StartMode = poolConfig.StartMode;//启动模式
            pool.QueueLength = poolConfig.QueueLength;//队列长度
            pool.ManagedRuntimeVersion = poolConfig.ManagedRuntimeVersion;
            pool.Enable32BitAppOnWin64 = pool.Enable32BitAppOnWin64;
            pool.ManagedPipelineMode = ManagedPipelineMode.Integrated;//托管管道模式
            pool.Cpu.Limit = cpuConfig.Limit;//限制最大CPU 50%
            pool.Cpu.Action = cpuConfig.Action;//竞争cpu时限制使用最大cpu 百分比
            pool.Cpu.ResetInterval =newTimeSpan(00, cpuConfig.ResetInterval, 00);//时隔5分钟
            pool.Cpu.SmpAffinitized = cpuConfig.SmpAffinitized ??false;
            //回收
            pool.Recycling.DisallowRotationOnConfigChange = recyclingConfig.DisallowRotationOnConfigChange ??true;//发生配置更改时禁止回收
            pool.Recycling.DisallowOverlappingRotation = recyclingConfig.DisallowOverlappingRotation ??true;//禁用重叠回收
            RecyclingLogEventOnRecycle logEventOnRecycle = RecyclingLogEventOnRecycle.None;
            foreach(variteminrecyclingConfig.LogEventOnRecycle)
            {
                logEventOnRecycle = logEventOnRecycle | item;
            }
            if(recyclingConfig.LogEventOnRecycle !=null&& recyclingConfig.LogEventOnRecycle.Count() > 0)
                pool.Recycling.LogEventOnRecycle = logEventOnRecycle;
            foreach(variteminperiodicRestartConfig.Schedule)
            {
                pool.Recycling.PeriodicRestart.Schedule.Add(item);//定时回收资源
            }
            pool.Recycling.PeriodicRestart.PrivateMemory = periodicRestartConfig.PrivateMemory;
            pool.Recycling.PeriodicRestart.Time =newTimeSpan(00, periodicRestartConfig.Time, 00);
            pool.Recycling.PeriodicRestart.Requests = periodicRestartConfig.Requests;
            pool.Recycling.PeriodicRestart.Memory = periodicRestartConfig.Memory;
            //进程孤立
            pool.Failure.OrphanActionParams = failureConfig.OrphanActionParams;
            pool.Failure.OrphanActionExe = failureConfig.OrphanActionExe;
            pool.Failure.OrphanWorkerProcess = failureConfig.OrphanWorkerProcess ??false;
            //模型
            pool.ProcessModel.PingInterval =newTimeSpan(00, 00, processModelConfig.PingInterval);
            pool.ProcessModel.PingResponseTime =newTimeSpan(00, 00, processModelConfig.PingResponseTime);
            pool.ProcessModel.IdentityType = processModelConfig.IdentityType;
            pool.ProcessModel.UserName = processModelConfig.UserName;
            pool.ProcessModel.Password = processModelConfig.Password;
            pool.ProcessModel.ShutdownTimeLimit =newTimeSpan(00, 00, processModelConfig.ShutdownTimeLimit);
            pool.ProcessModel.LoadUserProfile = processModelConfig.LoadUserProfile ??false;
            pool.ProcessModel.IdleTimeoutAction = IdleTimeoutAction.Terminate;
            pool.ProcessModel.StartupTimeLimit =newTimeSpan(00, 00, processModelConfig.StartupTimeLimit);
            pool.ProcessModel.PingingEnabled = processModelConfig.PingingEnabled ??false;
            pool.ProcessModel.LogEventOnProcessModel = processModelConfig.LogEventOnProcessModel;
            pool.ProcessModel.IdleTimeout =newTimeSpan(00, processModelConfig.IdleTimeout, 00);
            pool.ProcessModel.MaxProcesses = processModelConfig.MaxProcesses;
            Console.WriteLine("****************************** ↓");
            Console.WriteLine($"程序池名称:{poolConfig.Name}");
            Console.WriteLine($"队列长度:{poolConfig.QueueLength}");
            Console.WriteLine($"启动模式:{poolConfig.StartMode}");
            Console.WriteLine($"启用32位应用程序:{poolConfig.Enable32BitAppOnWin64}");
            Console.WriteLine($"托管管道模式:{poolConfig.ManagedPipelineMode}");
        }
 
        /// <summary>
        /// 获取IIS配置
        /// </summary>
        /// <returns></returns>
        privatestaticIISConfig GetIISConfig()
        {
            varpath = System.Environment.CurrentDirectory + Config._IISConfigPath;
            using(System.IO.StreamReader file = System.IO.File.OpenText(path))
            {
                using(JsonTextReader reader =newJsonTextReader(file))
                {
                    varo = (JObject)JToken.Readfrom(reader);
                    returno.ToObject<IISConfig>();
                }
            }
        }
 
 
        /// <summary>
        /// 添加虚拟目录
        /// </summary>
        /// <param name="siteName">网站名</param>
        /// <param name="vDirName">目录名</param>
        /// <param name="physicalPath">对应的文件夹路径</param>
        /// <param name="iismanager"></param>
        privatestaticvoidcreateVDir(stringsiteName,stringvDirName,stringphysicalPath, ServerManager iismanager)
        {
 
            Site site = iismanager.Sites[siteName];
            if(site ==null)
            {
                return;
            }
            site.Applications["/"].VirtualDirectories.Add("/"+ vDirName, physicalPath);
        }
 
        /// <summary>
        /// 添加虚拟目录
        /// </summary>
        /// <param name="siteName">网站名</param>
        /// <param name="vDirName">目录名</param>
        /// <param name="physicalPath">对应的文件夹路径</param>
        /// <param name="iismanager"></param>
        privatestaticvoidcreateSubitemVDir(stringsiteName,stringsubitemSiteName,stringvDirName,stringphysicalPath, ServerManager iismanager)
        {
 
            varapp = iismanager.Sites[siteName].Applications["/"+ subitemSiteName];
            if(app ==null)
            {
                return;
            }
            app.VirtualDirectories.Add("/"+ vDirName, physicalPath);
        }
    }
}


小编用的是json文件配置IIS发布的所以这里上个json的结构给到大家

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
{
  "WebName":"testName",//网站名称
  "Port": 8020,//端口
  "ServerDomainName":"",//服务器域名
  "WebsiteDirectory":"D:\\IIS\\TLSC.Admin",//网站目录
  "ApplicationPoolName":"File",//程序池名称
  //虚拟目录没有就默认[]
  "VDir": [],
  //子节点
  "Applications": [
    {
      "Path":"File",//路径名称
      "PhysicalPath":"D:\\IIS\\TLSC.Admin",//物理路径
      "ApplicationPoolName":"File",//程序池名称
      //虚拟目录没有就默认[]
      "VDir": []
    },
    {
      "Path":"Admin",//路径名称
      "PhysicalPath":"D:\\IIS\\TLSC.Admin",//物理路径
      "ApplicationPoolName":"Admin",//程序池名称
      //虚拟目录没有就默认[]
      "VDir": []
    }
  ],
  "ApplicationPools": [
    {
      "ManagedRuntimeVersion":"v4.0",//版本编号
      "QueueLength": 1000,//队列长度
      "StartMode": 1,//启动模式
      "Enable32BitAppOnWin64":false,//启用32位应用程序
      "Name":"File",//程序池名称
      "ManagedPipelineMode": 0,//托管管道模式 0 Integrated / 1 Classic
      //CPU
      "Cpu": {
        "Limit": 0,//Limit = 50000 限制最大CPU 50% , 默认为0
        "Action": 3,//限制操作 0 NoAction / 1 KillW3wp / 2 Throttle / 3 ThrottleUnderLoad
        "ResetInterval": 5,//时间间隔(分钟)
        "SmpAffinitized":false//已启用处理器关联
      },
      //回收
      "Recycling": {
        "DisallowRotationOnConfigChange":false,//发生配置更改时禁止回收
        "DisallowOverlappingRotation":false,//禁用重叠回收
        //生成和回收时间日志条目 0 None (所有为false)/ 1 Time / 2 Requests / 4 Schedule / 8 Memory / 16 IsapiUnhealthy / 32 OnDemand/ 64 ConfigChange / 128 PrivateMemory /[] 默认所有true
        "LogEventOnRecycle": [ 2, 3, 4, 5 ],
        "PeriodicRestart": {
          "Time": 50,//固定时间间隔(分钟)
          "Requests": 0,//请求限制 默认为零
          "Memory": 0,//虚拟内存限制(KB)
          "PrivateMemory": 1024000,//专用内存限制(KB)
          //特定时间
          "Schedule": [
            "03:00:00",
            "02:00:00"
          ]
        }
      },
      //进程孤立
      "Failure": {
        "OrphanActionExe":"",//可执行文件
        "OrphanActionParams":"",//可执行文件参数
        "OrphanWorkerProcess":false//已启用
      },
      //进程模型
      "ProcessModel": {
        "PingInterval": 30,//Ping间隔(秒)
        "PingResponseTime": 90,//Ping最大响应时间(秒)
        "IdentityType": 0,//标识 0 LocalSystem , 1 LocalService , 2 NetworkService, 3 SpecificUser, 4 ApplicationPoolIdentity
        "UserName":"",//标识 账号
        "Password":"",//标识 密码
        "ShutdownTimeLimit": 90,//关闭时间限制(秒)
        "LoadUserProfile":true,//加载用户配置文件
        "IdleTimeoutAction": 0,//空闲超时操作 0 Terminate / 1 Suspend
        "StartupTimeLimit": 90,//启动时间限制(秒)
        "PingingEnabled":true,//启用 Ping
        "LogEventOnProcessModel": 1,//生成进程模型事件日志条目-空闲超时已到
        "IdleTimeout": 20,//闲置超时(分钟)
        "MaxProcesses": 1//最大工作进程数
      }
    }
  ]
}

json的文件路径也是可配置的,在app.config配置读取json文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"encoding="utf-8"?>
<configuration>
    <startup>
        <supportedRuntime version="v4.0"sku=".NETFramework,Version=v4.6.1"/>
    </startup>
  <appSettings>
    <add key="IISConfigPath"value="..\..\..\json\TempConfig.json"/>
  </appSettings>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Reflection.TypeExtensions"publicKeyToken="b03f5f7f11d50a3a"culture="neutral"/>
        <bindingRedirect oldVersion="0.0.0.0-4.1.2.0"newVersion="4.1.2.0"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

该文章在 2023/1/19 0:47:35 编辑过

  离 线  2023/1/19 0:47:34 
  本文章共有 0 页, 0 张回文,每页有 10 张回文 >> [ ]
页码:  
Copyright 2010-2023 ClickSun All Rights Reserved