【Winform】Winform 制作一键发布web
前言
最近web网站有个需要,就是打包给客户,客户能够自己手动的进行傻瓜式的安装发布web。找了很多资料,其中涉及到 文件解压 IIS操作 数据库还原 等。
发现现在就主要是两种解决方案:
①:使用Visual studio 中自带的web安装程序进行发布
②:使用winform自制窗体安装程序(本文的主角)
主体
其中的一个程序给力很多感触,上传上来,大家可以参考(下载见下面地址)。 参考地址为:baihongri
效果图如下:
一步一步的使用winform窗体进行发布,思路:安装说明à设置服务器à创建数据库à发布IISà完成给出网站访问。
方法总结
期间碰到了很多问题,总结了一下放到下方作为备用:
1.C#通过文件路径获取文件名
string fullPath = @"\WebSite1\Default.aspx"; string filename = System.IO.Path.GetFileName(fullPath);//文件名 “Default.aspx” string extension = System.IO.Path.GetExtension(fullPath);//扩展名 “.aspx” string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(fullPath);// 没有扩展名的文件名 “Default”
2.C#使用Task创建任务 (详细参考)
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext(); CancellationToken token = new CancellationToken(); Task.Factory.StartNew(new Action(() => { //创建数据库 var sqlHelper = new SqlHelper(); sqlHelper.execfile(address, name, pass, dataName, allSqlList[0].ToString()); } )).ContinueWith(w => { panlLoading.Visible = false; }, token, TaskContinuationOptions.None, scheduler);
3.解压安装类
using System; using System.Collections.Generic; using System.Text; using System.IO; using Microsoft.Win32; using System.Diagnostics; namespace CommonHelper { public class WinrarHelper { /// <summary> /// 是否安装了Winrar /// </summary> /// <returns></returns> public static bool RarExists() { RegistryKey the_Reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"); return !string.IsNullOrEmpty(the_Reg.GetValue("").ToString()); } /// <summary> /// 打包成Rar /// </summary> /// <param name="patch"></param> /// <param name="rarPatch"></param> /// <param name="rarName"></param> public void CompressRAR(string patch, string rarPatch, string rarName) { string the_rar; RegistryKey the_Reg; object the_Obj; string the_Info; ProcessStartInfo the_StartInfo; Process the_Process; try { the_Reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"); the_Obj = the_Reg.GetValue(""); the_rar = the_Obj.ToString(); the_Reg.Close(); the_rar = the_rar.Substring(1, the_rar.Length - 7); Directory.CreateDirectory(patch); //命令参数 //the_Info = " a " + rarName + " " + @"C:Test?70821.txt"; //文件压缩 the_Info = " a " + rarName + " " + patch + " -r"; ; the_StartInfo = new ProcessStartInfo(); the_StartInfo.FileName = the_rar; the_StartInfo.Arguments = the_Info; the_StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //打包文件存放目录 the_StartInfo.WorkingDirectory = rarPatch; the_Process = new Process(); the_Process.StartInfo = the_StartInfo; the_Process.Start(); the_Process.WaitForExit(); the_Process.Close(); } catch (Exception ex) { throw ex; } } /// <summary> /// 解压 /// </summary> /// <param name="unRarPatch">存放路径</param> /// <param name="rarPatch">压缩包位置</param> /// <param name="rarName">压缩包名称</param> /// <returns></returns> public string unCompressRAR(string unRarPatch, string rarPatch, string rarName) { string the_rar; RegistryKey the_Reg; object the_Obj; string the_Info; try { the_Reg = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe"); the_Obj = the_Reg.GetValue(""); the_rar = the_Obj.ToString(); the_Reg.Close(); //the_rar = the_rar.Substring(1, the_rar.Length - 7); if (Directory.Exists(unRarPatch) == false) { Directory.CreateDirectory(unRarPatch); } the_Info = "x " + rarName + " " + unRarPatch + " -y"; ProcessStartInfo the_StartInfo = new ProcessStartInfo(); the_StartInfo.FileName = the_rar; the_StartInfo.Arguments = the_Info; the_StartInfo.WindowStyle = ProcessWindowStyle.Hidden; the_StartInfo.WorkingDirectory = rarPatch;//获取压缩包路径 Process the_Process = new Process(); the_Process.StartInfo = the_StartInfo; the_Process.Start(); the_Process.WaitForExit(); if (the_Process.HasExited) { int exitCode = the_Process.ExitCode; if (exitCode != 0) { //8 内存错误 没有足够的内存进行操作 //7 用户错误 命令行选项错误 //6 打开错误 打开文件错误 //5 写错误 写入磁盘错误 //4 被锁定压缩文件 试图修改先前使用 'k' 命令锁定的压缩文件 //3 CRC 错误 解压缩时发生一个 CRC 错误 //2 致命错误 发生一个致命错误 //1 警告 没有发生致命错误 //0 成功 操作成功 switch (exitCode) { case 1: throw new Exception("警告 没有发生致命错误"); break; case 2: throw new Exception("致命错误 发生一个致命错误"); break; case 3: throw new Exception("CRC 错误 解压缩时发生一个 CRC 错误"); break; case 4: throw new Exception("被锁定压缩文件 试图修改先前使用 'k' 命令锁定的压缩文件"); break; case 5: throw new Exception("写错误 写入磁盘错误"); break; case 6: throw new Exception("打开错误 打开文件错误"); break; case 7: throw new Exception("用户错误 命令行选项错误"); break; case 8: throw new Exception("内存错误 没有足够的内存进行操作"); break; } throw new Exception("致命错误 发生一个致命错误: " + exitCode + " "); } } the_Process.Close(); } catch (Exception ex) { throw ex; } return unRarPatch; } } }
4. Winform 上一步 下一步 实现
/// <summary> /// 上一步的对象 /// </summary> public Setup1 setup1 { get; set; } /// <summary> /// 构造函数 /// </summary> /// <param name="setupWizard">上一步的对象</param> public Step2Setup1 setup1) { this.setup1 = setup1; InitializeComponent(); } /// <summary> /// 上一步 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnLast_Click(object sender, EventArgs e) { this.setup1.Show(); this.Hide(); } /// <summary> /// 下一步 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnNext_Click(object sender, EventArgs e) { var step3= new step3(this); step3.Show(); this.Hide(); }
5. C#检查数据库中是否有同名存在
/// <summary> /// 检测数据库是否存在 /// </summary> /// <param name="conn">连接字符串</param> /// <param name="DatabaseName">数据库名</param> /// <param name="Sql">sql语句</param> /// <returns></returns> public static bool ExistsDataBase(string conn,string Sql) { bool res = true; System.Data.SqlClient.SqlConnection mySqlConnection = new System.Data.SqlClient.SqlConnection(conn); mySqlConnection.Open(); System.Data.SqlClient.SqlCommand Command = new System.Data.SqlClient.SqlCommand(Sql, mySqlConnection); int n = int.Parse(Command.ExecuteScalar().ToString()); if (n>0) { res = true; } else { res = false; } return res; }
6. c#使用osql.exe执行SQL脚本(详细参考)
/// <summary> /// 执行文件 /// </summary> /// <param name="dataSouece">数据源</param> /// <param name="userId">用户名</param> /// <param name="pwd">密码</param> /// <param name="databaseName">数据库名</param> /// <param name="scriptSqlPath">sql脚本地址</param> public void execfile(string dataSouece,string userId,string pwd,string databaseName,string scriptSqlPath) { try { string connStr =string.Format("data source={0};user id={1};password={2};persist security info=false;packet size=4096",dataSouece,userId,pwd); ExecuteSql(connStr, "master", "CREATE DATABASE " + databaseName); //这个数据库名是指你要新建的数据库名称 下同 System.Diagnostics.Process sqlProcess = new System.Diagnostics.Process(); sqlProcess.StartInfo.FileName = "osql.exe"; sqlProcess.StartInfo.Arguments = string.Format("-S {0} -U {1} -P {2} -d {3} -i {4}",dataSouece, userId, pwd, databaseName, scriptSqlPath);//-U 数据库用户名 -P 密码 -d 数据库名 -i 存放sql文本的目录sql.sql sqlProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; sqlProcess.Start(); sqlProcess.WaitForExit(); sqlProcess.Close(); } catch (Exception ex) { throw ex; } } private void ExecuteSql(string conn, string DatabaseName, string Sql) { System.Data.SqlClient.SqlConnection mySqlConnection = new System.Data.SqlClient.SqlConnection(conn); System.Data.SqlClient.SqlCommand Command = new System.Data.SqlClient.SqlCommand(Sql, mySqlConnection); Command.Connection.Open(); Command.Connection.ChangeDatabase(DatabaseName); try { Command.ExecuteNonQuery(); } finally { Command.Connection.Close(); } }
7.C#配置IIS 出现 未知错误(0x80005000) (详细参考)
要解决这个问题就得安装“IIS 元数据库和IIS 6配置兼容性”。
“控制面板”->“程序和功能”->面板左侧“打开或关闭windows功能”->“Internet信息服务”->“Web管理工具”->“IIS 6管理兼容性”->“IIS 元数据库和IIS 6配置兼容性”。
8.C#操作IIS完整解析 (详细参考)
9.非空验证另外一种形式
/// <summary> /// 检查字符串是否合法 /// </summary> /// <param name="parameterString"></param> /// <returns></returns> public static bool checkString(params string[] parameterString) { foreach (var parameterStr in parameterString) { if (string.IsNullOrEmpty(parameterStr)) { return false; } } return true; } 调用:CommonMethod.checkString(txtVirsualPath.Text, txtWebsitPath.Text)
10.C# 文件夹赋值Everyone权限
/// <summary> /// 设置文件夹权限,处理为Everyone所有权限 /// </summary> /// <param name="foldPath">文件夹路径</param> public static void SetFileRole(string foldPath) { DirectorySecurity fsec = new DirectorySecurity(); fsec.AddAccessRule(new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow)); System.IO.Directory.SetAccessControl(foldPath, fsec); }
11.C#对数据库进行备份/还原 BAK操作
/// <summary> /// 对数据库的备份和恢复操作,Sql语句实现 /// </summary> /// <param name="cmdText">实现备份或恢复的Sql语句</param> /// <param name="isBak">该操作是否为备份操作,是为true否,为false</param> public void BakReductSql(string cmdText, bool isBak,string connStr) { SqlCommand cmdBakRst = new SqlCommand(); //SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=master;uid=sa;pwd=;"); SqlConnection conn = new SqlConnection(connStr); try { conn.Open(); cmdBakRst.Connection = conn; cmdBakRst.CommandType = CommandType.Text; if (!isBak) //如果是恢复操作 { string setOffline = "";//"Alter database GroupMessage Set Offline With rollback immediate "; string setOnline = "";//" Alter database GroupMessage Set Online With Rollback immediate"; cmdBakRst.CommandText = setOffline + cmdText + setOnline; } else { cmdBakRst.CommandText = cmdText; } cmdBakRst.ExecuteNonQuery(); if (!isBak) { //MessageBox.Show("恭喜你,数据成功恢复为所选文档的状态!", "系统消息"); } else { //MessageBox.Show("恭喜,你已经成功备份当前数据!", "系统消息"); } } catch (SqlException sexc) { //MessageBox.Show("失败,可能是对数据库操作失败,原因:" + sexc, "数据库错误消息"); throw new Exception("失败,可能是对数据库操作失败,原因:" + sexc); } catch (Exception ex) { //MessageBox.Show("对不起,操作失败,可能原因:" + ex, "系统消息"); throw new Exception("对不起,操作失败,可能原因:"+ex); } finally { cmdBakRst.Dispose(); conn.Close(); conn.Dispose(); } } 使用:string cmdText = @"use master restore database " + BaseInfo.WebName + " from disk='" + path + "' With Replace"; sqlHelper.BakReductSql(cmdText, false, connStr);
下载
网站发布demo:点击下载
Web安装程序说明:点击下载
Web安装程序demo:点击下载
其他补充的资料:点击下载
作者:ruicky
出处:http://www.cnblogs.com/ruicky/
欢迎任何形式的转载,未经作者同意,请保留此段声明!