【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[].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(, the_rar.Length - );
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 != )
{
//8 内存错误 没有足够的内存进行操作
//7 用户错误 命令行选项错误
//6 打开错误 打开文件错误
//5 写错误 写入磁盘错误
//4 被锁定压缩文件 试图修改先前使用 'k' 命令锁定的压缩文件
//3 CRC 错误 解压缩时发生一个 CRC 错误
//2 致命错误 发生一个致命错误
//1 警告 没有发生致命错误
//0 成功 操作成功
switch (exitCode)
{
case :
throw new Exception("警告 没有发生致命错误");
break;
case :
throw new Exception("致命错误 发生一个致命错误");
break;
case :
throw new Exception("CRC 错误 解压缩时发生一个 CRC 错误");
break;
case :
throw new Exception("被锁定压缩文件 试图修改先前使用 'k' 命令锁定的压缩文件");
break;
case :
throw new Exception("写错误 写入磁盘错误");
break;
case :
throw new Exception("打开错误 打开文件错误");
break;
case :
throw new Exception("用户错误 命令行选项错误");
break;
case :
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>)
{
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:点击下载
其他补充的资料:点击下载
【Winform】Winform 制作一键发布web的更多相关文章
- winform 程序制作自己的数字签名(续)
在上一篇文章<winform 程序制作自己的数字签名>中我们已经可以得到我们程序定制的数字签名了,但是比较讨厌的是每次编译之后,数字签名需要重新手动添加. 我们需要的是在程序编译时自动添加 ...
- 一键发布ASP.NET Web安装程序
转载自:http://www.cnblogs.com/nangong/p/Web.html 前言:最近公司有个Web要发布,但是以前都是由实施到甲方去发布,配置,这几天有点闲,同事让我搞 ...
- [原创*精华]一键发布ASP.NET Web安装程序,搞WebForm的童鞋看过来...
重要更新:鉴于很多小伙伴们说看不到图,我这边换了几个浏览器看了下,都看得到的,估计是网速问题,请耐心等待,另外,为了更好的方便大家学习,特此提供源码以及一个word文档,word文档就是本 ...
- VS2017中使用组合项目_windows服务+winform管理_项目发布_测试服务器部署
前言:作为一名C#开发人员,避免不了常和windows服务以及winform项目打交道,本人公司对服务的管理也是用到了这2个项目的组合方式进行:因为服务项目是无法直接安装到计算器中,需要使用命令借助微 ...
- netcore开发windows普通服务(非Web)并一键发布到服务器
如何开发并一键发布WindowsService项目(netcore普通项目) netcore下开发windows服务如果是web项目的话,由于aspnetcore本身是支持的,把默认的host.Run ...
- 使用C#winform编写渗透测试工具--Web指纹识别
使用C#winform编写渗透测试工具--web指纹识别 本篇文章主要介绍使用C#winform编写渗透测试工具--Web指纹识别.在渗透测试中,web指纹识别是信息收集关键的一步,通常是使用各种工具 ...
- 一键发布部署vs插件[AntDeploy],让net开发者更幸福
一键发布工具(ant deploy tool) 插件下载地址: https://marketplace.visualstudio.com/items?itemName=nainaigu.AntDepl ...
- vs2012 发布web应用程序
Visual Studio 2012 Visual Studio Express 2012 for Web 与 的Visual Studio 2010 Visual Studio Web发布更新 与 ...
- SQL Server 2005中设置Reporting Services发布web报表的匿名访问
原文:SQL Server 2005中设置Reporting Services发布web报表的匿名访问 一位朋友提出个问题:集成到SQL Server 2005中的Reporting Services ...
随机推荐
- Mac终端编译运行C++
1.在编辑器中写好C++代码 2.打开终端打开文件对应的地址 3.用g++命令来编译.cpp文件 4.用./文件名来运行 观察文件的目录可发现 g++ 源文件名 编译源文件,产生a.out ./文件名 ...
- 【大数比较】NYOJ-73
比大小 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 给你两个很大的数,你能不能判断出他们两个数的大小呢? 比如123456789123456789要大于-1234 ...
- TCP/IP详解学习笔记(6)-UDP协议
1.UDP简要介绍 UDP是传输层协议,和TCP协议处于一个分层中,但是与TCP协议不同,UDP协议并不提供超时重传,出错重传等功能,也就是说其是不可靠的协议. 2.UDP协议头 2.1.UDP端口号 ...
- ASP.NET CORE Web浏览器和Web服务器
//web浏览器 //浏览器本质的原理:浏览器向服务器发请求,服务器把请求的内容返回给浏览器,然后浏览器把返回的内容绘制成一个图形化的界面 //Socket一种通讯交流的技术 //qq用户把信息通过s ...
- git push冲突解决
1. 首先,可以试图用git push origin branch-name推送自己的修改:2. 如果推送失败,则因为远程分支比你的本地更新,需要先用git pull试图合并:如果git pull提示 ...
- 关于DatePicker控件在IsEnabled为False视觉效果没有明显辨识度的处理方法
DatePicker控件在IsEnabled为False时界面没有让人看上去不可用(背景为灰色等)的效果.容易让用户迷惑. 可以用下面的代码增加设置透明度的触发器来解决(XAML以及C#方式): &l ...
- Storm-6 Storm的并行度、Grouping策略以及消息可靠处理机制简介
概念: 配置并行度 动态的改变并行度 流分组策略----Stream Grouping 消息的可靠处理机制 概念: Workers (JVMs): 在一个节点上可以运行一个或多个独立的JVM 进程.一 ...
- 编写一个循环将list容器的元素逆序输出
<c++ primer>P270,习题9.9 实现代码如下: #include<iostream> #include<list> using namespace s ...
- strcasecmp在VS2010中提示未定义标识符
分析: strcasecmp(*,*)是用来比较字符串,定义在string.h头文件中,但是在windows下即使添加string.h头文件,依然会报错. 解决: 添加 #if defined(_MS ...
- Redrain仿酷狗音乐播放器开发完毕,发布测试程序
转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...