C#ASP.NET打包安装部署文件一键安装网站,包括IIS站点创建、数据库附加。

news/2024/5/12 23:52:14/文章来源:https://blog.csdn.net/weixin_30328063/article/details/97521885

 

  

最近在开发web网站安装部署,以前从来没有做过web的安装打包没有头绪就开始上网查资料。

查了两天资料发现网上的资料要么不全要么就有错误,我就总结了网上的资料重新整理的一番,经过本人测试可用无错误

一下为借鉴部分资料的原文地址

此链接为打包ASP.NET网站资料(这个资料有问题,在自定义操作哪一步详情看下面文章):http://www.cnblogs.com/fish520/archive/2016/09/22/5882450.html

此链接为创建IIS站点(其中代码不全我还借鉴的部分其他论坛的资料):http://www.cnblogs.com/wujy/archive/2013/02/28/2937667.html

 

首先开始的是文件打包

 

第一步创建安装项目

 

第二步添加主输出(右键安装项目)

选择网站

 

第三步设置用户界面

点击添加对话框

选择许可文件、文本框A、文本框B顺序按下面顺序排列

 

第四步添加许可协议文件

右键安装项目点击视图=》文件系统

选择应用程序文件夹=》右键点击=》文件

选择创建好的*.rtf文件即可,该文件打开wrod另存为rtf格式文件即可

 

我们回到用户界面

右键许可协议=》属性=》设置licenseFile属性选择文件为刚刚添加的文件

 

在安装过程中我们要添加附加数据库和创建IIS站点所以需要用到数据的账号密码和创建IIS的相关信息

我们右键文本框A=》属性

设置下面参数,第四个用不上隐藏了

创建IIS需要的相关信息在文本框B填写

右键文本框B=》属性

用户填写上面创建IIS需要的相关信息,其中添加的默认值是因为不能为空否则会报错

 

接下来我们创建一个安装类库,创建IIS和附加数据库将在该类库中完成

右键解决方案=》添加类库

 

然后右键创建好的该类库=》添加安装程序类

 

 接下里右键安装文件添加项目输出

选择刚刚添加的安装类点确定

 

接下来右键安装项目=》视图=》自定义操作

右键安装=》添加自定义操作=选择web应用程序文件夹

选择刚刚添加的安装类点击确定

 

 然后右键安装下面的主输出文件=》点击属性

 

设置CustomActionData的值

/server=[EDITA1] /user=[EDITA2] /pwd=[EDITA3] /iis=[IISSERVER] /ip=[IP] /port=[PORT] /isname=[isname] /targetdir="[TARGETDIR]\"

 设置这些中括号[]括起来的就是文本框的ID在用户界面中的文本框属性中设置

 我在文章开头写的那个借鉴资料中的一篇文在这里的设置中写错了他用双引号和单引号把后面的值引起来之后在创建IIS站点的时候报错了,这个错误纠结了我一下午的时间去查资料,最后把项目拷出来放在一个aspx页面中错误的那一块一句句的调试才找到原因

 

我们回到那个安装类upLibrary1右键查看安装文件类的代码

 

好了。上面就是文件打包的全部过程了,下面我们接下来就是创建网站的IIS站点和附加网站的数据库

 

创建IIS站点

以下为需要引用的命名空间

 

using System.IO;
using System.Data.SqlClient;
using System.Management;
using System.Security.AccessControl;
using System.DirectoryServices;
using Microsoft.Web.Administration;
using System.Diagnostics;
using System.Windows.Forms;

 

//iis服务器地址下面方法会用到所以定义公共string iis = "";//重写Installpublic override void Install(IDictionary stateSaver){base.Install(stateSaver);//接收参数//数据库服务器地址string databaseServer = Context.Parameters["server"].ToString();//账号string user = Context.Parameters["user"].ToString();//密码string pwd = Context.Parameters["pwd"].ToString();//安装路径string targetdir = Context.Parameters["targetdir"].ToString().Replace(@"\\", @"\");//IIS地址iis = this.Context.Parameters["iis"].ToString();//ipstring ip = this.Context.Parameters["ip"].ToString();//端口string port = this.Context.Parameters["port"].ToString();//网站名string isname = this.Context.Parameters["isname"].ToString();//File.WriteAllText(Path.Combine(targetdir, "log11.txt"), "databaseServer:" + databaseServer + "/n/r" + "user:" + user + "/n/r" + "pwd:" + pwd + "/n/r" + "targetdir:" + targetdir + "/n/r" + "iis:" + iis + "/n/r" + "port:" + port + "/n/r" + "isname" + isname + "/n/r" + "serverID:" + serverID);try{//实例化IIS站点配置信息NewWebSiteInfo nwsif = new NewWebSiteInfo(ip, port, isname.Trim(), (isname.Trim().Length > 0 ? isname : "anjiesigudingzichan"), targetdir);//创建IIS站点
                CreateNewWebSite(nwsif);#region 附加数据库//给文件添加"Authenticated Users,Everyone,Users"用户组的完全控制权限 ,要附加的数据库文件必须加权限否则无法附加if (File.Exists(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf")){FileInfo fi = new FileInfo(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf");System.Security.AccessControl.FileSecurity fileSecurity = fi.GetAccessControl();fileSecurity.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));fileSecurity.AddAccessRule(new FileSystemAccessRule("Authenticated Users", FileSystemRights.FullControl, AccessControlType.Allow));fileSecurity.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));fi.SetAccessControl(fileSecurity);FileInfo fi1 = new FileInfo(Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.ldf");System.Security.AccessControl.FileSecurity fileSecurity1 = fi1.GetAccessControl();fileSecurity1.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow));fileSecurity1.AddAccessRule(new FileSystemAccessRule("Authenticated Users", FileSystemRights.FullControl, AccessControlType.Allow));fileSecurity1.AddAccessRule(new FileSystemAccessRule("Users", FileSystemRights.FullControl, AccessControlType.Allow));fi1.SetAccessControl(fileSecurity1);}string connectionString = GetConnectionString(null);//保存数据连接词,为卸载做准备File.WriteAllText(Path.Combine(targetdir + "\\" + "App_Data\\", "log.txt"), connectionString);try{using (SqlConnection connection = new SqlConnection(connectionString)){connection.Open();//使用数据库文件创建数据库,所以添加的网站项目中需要有App_Data文件夹和数据库文件(ceshi.mdf)和日志文件(ceshi.ldf)string sql = "sp_attach_db 'ceshi','" + Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.mdf','" + Context.Parameters["targetdir"].ToString() + "App_Data\\ceshi.ldf'";ExecuteSQL(connection, sql);connection.Close();//修改config文件连接词string webconfigpath = Path.Combine(this.Context.Parameters["targetdir"].ToString(), "web.config");string webcofnigstring = File.ReadAllText(webconfigpath).Replace("#constring#", GetConnectionString("ceshi"));File.WriteAllText(webconfigpath, webcofnigstring);}}catch (Exception ex){MessageBox.Show("安装出错了1!\n" + ex.ToString(), "出错啦!");}#endregion}catch (Exception exx){MessageBox.Show("安装出错了!2\n" + exx.ToString(), "出错啦!");}}/// <summary>/// 执行SQL语句/// </summary>/// <param name="connection"></param>/// <param name="sql"></param>void ExecuteSQL(SqlConnection connection, string sql){SqlCommand cmd = new SqlCommand(sql, connection);cmd.ExecuteNonQuery();}/// <summary>/// 获取数据库登陆连接字符串/// </summary>/// <param name="databasename"></param>/// <returns></returns>private string GetConnectionString(string databasename){return "server=" + Context.Parameters["server"].ToString() + ";database=" + (string.IsNullOrEmpty(databasename) ? "master" : databasename) + ";User ID=" + Context.Parameters["user"].ToString() + ";Password=" + Context.Parameters["pwd"].ToString();}/// <summary>/// 创建IIS站点/// </summary>/// <param name="siteInfo">新站点配置信息</param>public void CreateNewWebSite(NewWebSiteInfo siteInfo){string entPath = String.Format("IIS://{0}/W3SVC", iis);//SetFileRole();if (!EnsureNewSiteEnavaible(siteInfo.BindString, entPath)){throw new Exception("该网站已存在" + Environment.NewLine + siteInfo.BindString);}DirectoryEntry rootEntry = new DirectoryEntry(entPath);string newSiteNum = GetNewWebSiteID(entPath);DirectoryEntry newSiteEntry = rootEntry.Children.Add(newSiteNum, "IIsWebServer");newSiteEntry.CommitChanges();newSiteEntry.Properties["ServerBindings"].Value = siteInfo.BindString;newSiteEntry.Properties["ServerComment"].Value = siteInfo.CommentOfWebSite;newSiteEntry.Properties["ServerAutoStart"].Value = true;//网站是否启动
            newSiteEntry.CommitChanges();DirectoryEntry vdEntry = newSiteEntry.Children.Add("root", "IIsWebVirtualDir");vdEntry.CommitChanges();string ChangWebPath = siteInfo.WebPath.Trim().Remove(siteInfo.WebPath.Trim().LastIndexOf('\\'), 1);vdEntry.Properties["Path"].Value = ChangWebPath;vdEntry.Invoke("AppCreate", true);//创建应用程序//vdEntry.Properties["ServerAutoStart"].Value = true;//网站是否启动vdEntry.Properties["AccessRead"][0] = true; //设置读取权限vdEntry.Properties["AccessWrite"][0] = true;vdEntry.Properties["AccessScript"][0] = true;//执行权限vdEntry.Properties["AccessExecute"][0] = false;vdEntry.Properties["DefaultDoc"][0] = "Login_gdzc.aspx";//设置默认文档vdEntry.Properties["AppFriendlyName"][0] = "LabManager"; //应用程序名称           vdEntry.Properties["AuthFlags"][0] = 1;//0表示不允许匿名访问,1表示就可以3为基本身份验证,7为windows继承身份验证
            vdEntry.CommitChanges();//操作增加MIME//IISOle.MimeMapClass NewMime = new IISOle.MimeMapClass();//NewMime.Extension = ".xaml"; NewMime.MimeType = "application/xaml+xml";//IISOle.MimeMapClass TwoMime = new IISOle.MimeMapClass();//TwoMime.Extension = ".xap"; TwoMime.MimeType = "application/x-silverlight-app";//rootEntry.Properties["MimeMap"].Add(NewMime);//rootEntry.Properties["MimeMap"].Add(TwoMime);//rootEntry.CommitChanges();#region 针对IIS7DirectoryEntry getEntity = new DirectoryEntry("IIS://" + iis + "/W3SVC/INFO");int Version = int.Parse(getEntity.Properties["MajorIISVersionNumber"].Value.ToString());if (Version > 6){#region 创建应用程序池string AppPoolName = "LabManager";if (!IsAppPoolName(AppPoolName)){DirectoryEntry newpool;DirectoryEntry appPools = new DirectoryEntry("IIS://" + iis + "/W3SVC/AppPools");newpool = appPools.Children.Add(AppPoolName, "IIsApplicationPool");newpool.CommitChanges();}#endregion#region 修改应用程序的配置(包含托管模式及其NET运行版本)ServerManager sm = new ServerManager();sm.ApplicationPools[AppPoolName].ManagedRuntimeVersion = "v4.0";sm.ApplicationPools[AppPoolName].ManagedPipelineMode = ManagedPipelineMode.Classic; //托管模式Integrated为集成 Classic为经典
                sm.CommitChanges();#endregionvdEntry.Properties["AppPoolId"].Value = AppPoolName;vdEntry.CommitChanges();}#endregion//启动aspnet_regiis.exe程序 string fileName = Environment.GetEnvironmentVariable("windir") + @"\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe";ProcessStartInfo startInfo = new ProcessStartInfo(fileName);//处理目录路径 string path = vdEntry.Path.ToUpper();int index = path.IndexOf("W3SVC");path = path.Remove(0, index);//启动ASPnet_iis.exe程序,刷新脚本映射 startInfo.Arguments = "-s " + path;startInfo.WindowStyle = ProcessWindowStyle.Hidden;startInfo.UseShellExecute = false;startInfo.CreateNoWindow = true;startInfo.RedirectStandardOutput = true;startInfo.RedirectStandardError = true;Process process = new Process();process.StartInfo = startInfo;process.Start();process.WaitForExit();string errors = process.StandardError.ReadToEnd();if (errors != string.Empty){throw new Exception(errors);}}#region 判定网站是否存在/// <summary>/// 确定一个新的网站与现有的网站没有相同的。 /// 这样防止将非法的数据存放到IIS里面去 /// </summary>/// <param name="bindStr">网站邦定信息</param>/// <returns>真为可以创建,假为不可以创建</returns>public bool EnsureNewSiteEnavaible(string bindStr, string entPath){DirectoryEntry ent = new DirectoryEntry(entPath);foreach (DirectoryEntry child in ent.Children){if (child.SchemaClassName == "IIsWebServer" && child.Properties["ServerBindings"].Value != null && child.Properties["ServerBindings"].Value.ToString() == bindStr){return false;}}return true;}/// <summary>/// 设置文件夹权限 处理给EVERONE赋予所有权限/// </summary>/// <param name="FileAdd">文件夹路径</param>public void SetFileRole(){string FileAdd = this.Context.Parameters["targetdir"].ToString();FileAdd = FileAdd.Remove(FileAdd.LastIndexOf('\\'), 1);DirectorySecurity fSec = new DirectorySecurity();fSec.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));System.IO.Directory.SetAccessControl(FileAdd, fSec);}#endregion

IIS站点信息类

/// <summary>/// IIS站点配置信息/// </summary>public class NewWebSiteInfo{private string hostIP;   // 主机IPprivate string portNum;   // 网站端口号private string descOfWebSite; // 网站表示。一般为网站的网站名。例如"www.dns.com.cn"private string commentOfWebSite;// 网站注释。一般也为网站的网站名。private string webPath;   // 网站的主目录。例如"e:\ mp"/// <summary>/// 实例化IIS站点配置/// </summary>/// <param name="hostIP">主机IP</param>/// <param name="portNum">网站端口号</param>/// <param name="descOfWebSite">网站表示。一般为网站的网站名。例如"www.dns.com.cn"--【主机名(域名)】</param>/// <param name="commentOfWebSite">网站注释。一般也为网站的网站名。--【iis网站站点名称】</param>/// <param name="webPath">网站的主目录。例如"e:\ mp"</param>public NewWebSiteInfo(string hostIP, string portNum, string descOfWebSite, string commentOfWebSite, string webPath){this.hostIP = hostIP;this.portNum = portNum;this.descOfWebSite = descOfWebSite;this.commentOfWebSite = commentOfWebSite;this.webPath = webPath;}/// <summary>/// 网站标识/// </summary>public string BindString{get{return String.Format("{0}:{1}:{2}", hostIP, portNum, descOfWebSite); //网站标识(IP,端口,主机头值)
            }}/// <summary>/// 网站端口号/// </summary>public string PortNum{get{return portNum;}}/// <summary>/// 网站表示。一般为网站的网站名。例如"www.dns.com.cn"/// </summary>public string CommentOfWebSite{get{return commentOfWebSite;}}/// <summary>/// 网站的主目录。例如"e:\ mp"/// </summary>public string WebPath{get{return webPath;}}}

 

删除应用池还没测试过,可以放在卸载里面。我还没写卸载

/// <summary>/// 删除指定程序池/// </summary>/// <param name="AppPoolName">程序池名称</param>/// <returns>true删除成功 false删除失败</returns>private bool DeleteAppPool(string AppPoolName){bool result = false;DirectoryEntry appPools = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");foreach (DirectoryEntry getdir in appPools.Children){if (getdir.Name.Equals(AppPoolName)){try{getdir.DeleteTree();result = true;}catch{result = false;}}}return result;}

 

这是我从网上资料总结出来整个asp.net安装打包流程,包括的IIS站点的创建和数据库附加。

卸载我还没写,有兴趣的可以写下卸载,删除应用池删除IIS站点,删除数据库等。

转载于:https://www.cnblogs.com/budongjiuchaziliao/p/6866815.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_826587.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器的购买与网站的创建

服务器的购买、配置、以及网站的搭建本文提供全流程&#xff0c;中文翻译。 Chinar 坚持将简单的生活方式&#xff0c;带给世人&#xff01;&#xff08;拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例&#xff09; Chinar —— 心分享、心创新&#xff01;…

网站攻防

1.创建实验后&#xff0c;打开实验网址&#xff1a;192.168.5.13&#xff0c;界面如下&#xff1a; 2.通过在网址后添加常用的后台指令来尝试是否能进入后台&#xff0c;如admin、admin.php等&#xff1a; 3.从上一步可以看出&#xff0c;无法通过admin等方式进入后台&#xff…

.net发布网站步骤

本文章分为三个部分: web网站发布、IIS6 安装方法、ASP.NET v4.0 安装方法 一、web网站发布 1.打开 Visual Studio 2013 编译环境 2.在其解决方案上右击弹出重新生成解决方案,以查看是否有错误 3.如果项目没有错误右击WebUI层发布 4.这样将会看到以下界面 5.在配置文件中新建配…

嵌入式学习路线怎么学?开发嵌入式培训网站推荐

在这个互联网的快速发展的时代&#xff0c;科技不断的创新嵌入式也开始逐渐的越来越火热&#xff0c;随着这一股风波也有越来越多的人投入到嵌入式开发的行列中来&#xff0c;那么想要学习嵌入式&#xff0c;该从哪里入手学习&#xff0c;嵌入式学习路线图怎么学&#xff1f;想…

html手机网页新闻模板,新浪手机新闻网站模板首页html源码

【实例简介】新浪手机html网页模板【实例截图】【核心代码】新浪手机新闻网站模板首页html源码├── css│ ├── add2home.min.css│ ├── blue1.css│ ├── channel.min.js│ ├── common.min.css│ ├── home.min.css│ └── style.min.css├── i…

国外最火的电商网站magento2:系列(一)虚拟机、centos7的安装

能了解什么&#xff1a; 本系列将会带你从0到1学会安装magento2&#xff01; 1.虚拟机的安装&#xff0c;centos7.2镜像的下载安装 2.下载并且配置nginx 3.下载并且配置php 4.让nginx适配magento2 5.下载并且配置magento2 6.安装过程中遇到的报错&#xff0c;问题 其中的整个中…

Java 专业人士必备的书籍和网站列表

对于 Java™ 语言开发人员来说&#xff0c;信息过量是一个真正的问题。每个新入行的程序员都要面临一个令人畏缩的挑战&#xff1a;要进入的行业是一个具有海量知识的行业。要了解的东西简直太多了。对于有经验的老手来说&#xff0c;情况只有些微好转。知识量总在增大&#xf…

优化网站性能 提高网站速度访问速度的14条实践

相信互联网已经越来越成为人们生活中不可或缺的一部分。ajax&#xff0c;flex等等富客户端的应用使得人们越加“幸福”地体验着许多原先只能在C/S实现的功能。比如Google机会已经把最基本的office应用都搬到了互联网上。当然便利的同时毫无疑问的也使页面的速度越来越慢。自己是…

利用Velocity模板引擎制作网站

基于 Java 的网站开发&#xff0c;很多人都采用 JSP 作为前端网页制作的技术&#xff0c;尤其在是国内。这种技术通常有一些问题&#xff0c;我试想一下我们是怎样开发网站的&#xff0c;通常有几种方法1&#xff1a;功能确定后&#xff0c;由美工设计网页的UI&#xff08;界面…

一个Hibernate的HQL转换成各种数据库SQL语句的在线网站很强

项目中经常使用Herbernate写HQL可能写的有问题&#xff0c;但是不知道&#xff0c;哪里错误&#xff0c;经过几番努力终于找到了&#xff0c;可以 一个Hibernate的HQL转换成各种数据库SQL语句的在线网站很强。可以在这个网站测试一下。哈哈a 确实很强&#xff0c;但是如果想拥有…

php 503服务无效,网站打开报错503 Service Unavailable 原因与解决办法

网站无故出现如下错误提示&#xff1a;Service UnavailableThe server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.翻译过来就是&#xff1a;服务不可用由于维护停机或容量问题&#xff0c;服务…

【转】HTML5学习必备的15权威网站

给大家推荐一下学习研究HTML5必备的一些个网站&#xff0c;更加有利于大家对HTML5的学些和研究。如果各位童鞋还有更多的&#xff0c;欢迎投递资源给我们&#xff0c;也可以支持我们&#xff0c;让我们利用大家的力量收集更多的HTML5学习资料&#xff0c;让我们的开发者和HTML5…

【转】8 个移动产品设计必备网站

本文整理了8个移动设计资源丰富的网站&#xff0c;希望对你的开发设计工作有所帮助。 1. Patterns of Design Patterns是一个分享iOS应用UI的网站&#xff0c;专注于分享iOS应用UI的细节&#xff0c;按照设计元素和iOS常用功能进行分类。 2. iOS UI PatternsiOS UI Patterns…

【转】大型高性能网站的十项规则

在我们公司ChinaNetCloud&#xff0c;见 过多种不同类型的网站和系统&#xff0c;有好也有差。其中有些系统拥有良好的服务器/网络架构&#xff0c;并且进行了合理的调整和监控 &#xff1b;然而一般的系统都会有安全和性能上的 问题&#xff0c;不能良好运行&#xff0c;也无法…

云服务器2:小白建站流程,及建站过程中遇到的问题解答

云服务器2&#xff1a;小白建站流程&#xff0c;及建站过程中遇到的问题解答 建站流程 建站所需&#xff1a;域名、服务器、程序源码&#xff08;以下教程以国内最大的云服务器厂商&#xff0c;阿里云的产品为参考&#xff09; 一、服务器环境配置&#xff1a;&#xff08;以…

干货 java教程 面试题 开发常用网站 java视频教程

众所周知&#xff0c;程序员是一个需要不断学习的职业&#xff0c;而幸运的是&#xff0c;在这个互联网时代&#xff0c;知识就在那里&#xff0c;等着我们去获取。 作为一个 收藏从未停止&#xff0c;学习从未开始 的博主 :(doge&#xff0c;秉承着好东西不能独享的态度&…

使用Dreamweaver8对网站文件进行检查和整理

用Dreamweaver8制作好了自己的网站&#xff0c;目的是什么&#xff1f;放到互连网上&#xff0c;也就是最终发布自己的网站&#xff0c;那么自己在制作网页过程中有没有错误呢&#xff1f;所以在发布之前我们要认真的检查一下有没有错误。新教程网 - newCss.cn 在发布网站之前先…

一步步教你为网站开发Android客户端

本文面向Android初级开发者&#xff0c;有一定的Java和Android知识即可。文章覆盖知识点&#xff1a;HttpWatch抓包&#xff0c;HttpClient模拟POST请求&#xff0c;Jsoup解析HTML代码&#xff0c;动态更新ListView背景介绍&#xff1a;客户端&#xff08;Client&#xff09;或…

WordPress地址(URL)修改后打不开网站的解决方法

乖&#xff0c;下次别改了 在后台的设置里&#xff0c;WordPress地址&#xff08;URL&#xff09;是不能随便更改的&#xff0c;只有站点地址&#xff08;URL&#xff09;可以随意动。如果更改了WordPress地址&#xff08;URL&#xff09;&#xff0c;主页面可能就丢失了。 解…

【WordPress建站】1. 代码实现编写文章可以调整字体字号

原有WordPress编辑文章是不可以给文章调整字体字号的 实现方法 把下面代码加入主题编辑器 //tinymce add bottomfunction add_more_buttons($buttons) {$buttons[] hr;$buttons[] del;$buttons[] sub;$buttons[] sup;$buttons[] fontselect;$buttons[] fontsizeselect…