用C#写程序安装包 Joe

摘要:
前段日子由于团队开发需要,写了一个用C#代码写的安装包!还有将该系统部署到其他电脑上选择路径和写入注册表。

前段日子由于团队开发需要,写了一个用C#代码写的安装包!首先说一下背景,之所以写这个,是因为我们在完成一个winform程序之后,需要部署到其他电脑上时发现:部署需要搭建的环境例如系统用到的外设驱动,数据库环境。还有将该系统部署到其他电脑上选择路径和写入注册表。有点类似于QQ安装程序。

1.初始界面如下:

用C#写程序安装包 Joe第1张

用C#写程序安装包 Joe第2张

当然,界面有点丑,还没有LOGO之类的美化。

2.环境检测安装(即安装外设的驱动和搭建好数据库环境)

这里的安装外设驱动说白了就是用C#代码实现调用一个.exe程序并执行安装,搭建数据库环境也就是系统需要用到本地数据库作为服务器存放数据(因为需要部署的系统是一个单机版的程序)。

(1)用C#代码调用exe程序

(2)安装一个数据库实例(搭建数据库环境)

代码如下:

privatevoidDetect()
{
//复制文件到C盘根目录下
stringsourcePath=@"文件名";
stringtargetPath=@"C:\文件名";
boolisrewrite=true;//true=覆盖已存在的同名文件,false则反之
File.Copy(sourcePath,targetPath,isrewrite);
//以上提供了把指定文件复制到某个目录下的方法
//在调用exe文件安装该应用程序之前先检测一下电脑中是否已经安装了该程序,由于正规的程序安装时都会将程序信息写入注册表,因此我们可以通过检测注册表来判断电脑中
//是否已经安装了该程序。
RegistryKeyidCard=Registry.LocalMachine.OpenSubKey("SOFTWARE",true).OpenSubKey(@"SDTtelecom",true); if(idCard==null) {
Install("XXXX.exe"); //需要安装的XXXX.exe程序应该放在与安装向导程序同一个目录下
idCard=Registry.LocalMachine.OpenSubKey("SOFTWARE",true).OpenSubKey(@"SDTtelecom",true);
//再次检测,如果为null说明前面安装不成功,则退出安装向导程序 if(idCard==null) { System.Environment.Exit(0); } }
//在这里我直接安装了一个简化的数据库环境SQL server,以下参数是采用静默安装方法是创建的一个数据库实例。
Install("SQLEXPR32_x86_ENU.exe",@"/qbINSTANCENAME=""VeinDBInstance""ADDLOCAL=ALLSECURITYMODE=SQLSAPWD=""123456""SQLAUTOSTART=1"); } privatevoidInstall(stringfile,stringparam=null) { ProcessmyProcess=newProcess(); stringfileName=@file; ProcessStartInfomyProcessStartInfo=newProcessStartInfo(fileName); if(!string.IsNullOrEmpty(param))myProcessStartInfo.Arguments=param; myProcessStartInfo.UseShellExecute=false; myProcess.StartInfo=myProcessStartInfo; myProcess.Start(); myProcess.WaitForExit();//关键,等待外部程序退出后才能往下执行 }

2.安装(环境搭建好之后把winform程序部署到电脑上并写入注册表)

///<summary>写入注册表函数
///写入注册表
///</summary>
///<paramname="name">版本</param>
///<paramname="tovalue">1.0</param>
privatevoidWTRegedit(stringname,stringtovalue)
{
RegistryKeyhklm=Registry.LocalMachine;
RegistryKeysoftware=hklm.OpenSubKey("SOFTWARE",true);
RegistryKeyaimdir=software.CreateSubKey("写入注册表的公司命名,例如Tencent");
RegistryKeysoft=aimdir.CreateSubKey("写软件名,例如Intergration");
soft.SetValue(name,tovalue);
soft.SetValue("Path",this._installPath+"\\Intergration");
soft.SetValue("DBName","数据库名");
}
///
///创建VBS代码
///
///
privatestringCreateVBS(stringname,stringstrexe)
{
stringvbs=string.Empty;
vbs+=("setWshShell=WScript.CreateObject(\"WScript.Shell\")\r\n");
vbs+=("strDesktop=WshShell.SpecialFolders(\"Desktop\")\r\n");
vbs+=("setoShellLink=WshShell.CreateShortcut(strDesktop&\"\\"+name+".lnk\")\r\n");
//目标路径,也就是我们程序所在的路径
vbs+=("oShellLink.TargetPath=\""+this._installPath+"\\"+"Intergration"+"\\"+strexe+"\"\r\n");
vbs+=("oShellLink.WindowStyle=1\r\n");
vbs+=("oShellLink.Description=\""+name+"\"\r\n");
vbs+=("oShellLink.WorkingDirectory=\""+this._installPath+"\\"+"Intergration"+"\"\r\n");
vbs+=("oShellLink.Save");
returnvbs;
}
///
///写入临时文件
///
privatestaticstringWriteToFile(stringvbs)
{
if(string.IsNullOrEmpty(vbs))returnnull;
//临时文件
stringtempFile=Environment.CurrentDirectory+"\\"+DateTime.Now.Ticks+"emp.vbs";
//写入文件
FileStreamfs=newFileStream(tempFile,FileMode.Create,FileAccess.Write);
try
{
//这里必须用UnicodeEncoding.因为用UTF-8或ASCII会造成VBS乱码
System.Text.UnicodeEncodinguni=newUnicodeEncoding();
byte[]b=uni.GetBytes(vbs);
fs.Write(b,0,b.Length);
fs.Flush();
fs.Close();
}
catch(Exceptionex)
{
//Console.WriteLine("写入临时文件出错");
}
finally
{
//释放资源
fs.Dispose();
}
returntempFile;
}
///
///执行VBS中的代码
///
privatestaticvoidRunProcess(stringfile)
{
stringtempFile=file;
if(File.Exists(tempFile))
{
//执行VBS
Process.Start(tempFile);
}
}
///<summary>安装过程
///安装过程
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
privatevoidInstall_Shown(objectsender,EventArgse)
{
//复制到安装目录,这里的this._installPath变量存的就是界面上选择的安装路径
stringinstallPath=this._installPath;
//这里的Intergration就是一个部署文件夹,里面包含exe和dll文件

stringsourcePath=@"Intergration";
CopyFolder(sourcePath,installPath); //运行数据库脚本 RunSQLScriptrunSql=newRunSQLScript(); runSql.Run(); //写注册表 WTRegedit("Version","1.0"); //以下均为创建桌面快捷键 //生成VBS代码 stringvbs=CreateVBS("XX系统","XX.exe"); //以文件形式写入临时文件夹 stringfile=WriteToFile(vbs); //调用Process执行 RunProcess(file); } ///<summary> ///实现从一个目录下完整拷贝到另一个目录下。这里其实就是一个拷贝一个部署包,里面包括可执行文件exe和dll文件之类的。 ///</summary> ///<paramname="strFromPath">源地址</param> ///<paramname="strToPath">目标地址</param> publicstaticvoidCopyFolder(stringstrFromPath,stringstrToPath) { //取得要拷贝的文件夹名 stringstrFolderName=strFromPath.Substring(strFromPath.LastIndexOf("\\")+ 1,strFromPath.Length-strFromPath.LastIndexOf("\\")-1); //如果目标文件夹中没有源文件夹则在目标文件夹中创建源文件夹 if(!Directory.Exists(strToPath+"\\"+strFolderName)) { Directory.CreateDirectory(strToPath+"\\"+strFolderName); } //创建数组保存源文件夹下的文件名 string[]strFiles=Directory.GetFiles(strFromPath); //循环拷贝文件 for(inti=0;i<strFiles.Length;i++) { //取得拷贝的文件名,只取文件名,地址截掉。 stringstrFileName=strFiles[i].Substring(strFiles[i].LastIndexOf("\\")+1,strFiles[i].Length-strFiles[i].LastIndexOf("\\")-1); //开始拷贝文件,true表示覆盖同名文件 File.Copy(strFiles[i],strToPath+"\\"+strFolderName+"\\"+strFileName,true); } //创建DirectoryInfo实例 DirectoryInfodirInfo=newDirectoryInfo(strFromPath); //取得源文件夹下的所有子文件夹名称 DirectoryInfo[]ZiPath=dirInfo.GetDirectories(); for(intj=0;j<ZiPath.Length;j++) { //获取所有子文件夹名 stringstrZiPath=strFromPath+"\\"+ZiPath[j].ToString(); //把得到的子文件夹当成新的源文件夹,从头开始新一轮的拷贝 CopyFolder(strZiPath,strToPath+"\\"+strFolderName); } }

至此,一个简易安装向导程序的核心代码都在这了。新手刚学,代码乱,还请指正!

总结一下以上代码能实现什么功能:

1.将指定文件或指定文件夹拷贝到某一个指定的目录下

2.拷贝完之后能将软件信息写入注册表,完成注册

3.调用exe文件,运行

4.创建桌面快捷方式

免责声明:文章转载自《用C#写程序安装包 Joe》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇第二次实验报告终于装好了集成网卡RTL8111/8160B的驱动,mark一下~下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Office软件64位和32位注册表

某些时候,安装Office软件的时候,会出现报错,或者即便安装成功了,电脑上存在的Office软件的版本不同,都可能在使用的时候有点问题。 相关错误: 1-安装Office2016的设备上还存在Office的残留注册表 2-安装Office2016(64位)的设备上还存在32位Office的注册表 3-Outlook2016无法搜索邮件,即便确认Windo...

win10 .net3.5的问题及解决方案

近日有网友反映在windows10_64位系统电脑上安装Net framework3.5,操作时总失败,怎么办呢?小编下面就介绍win10 64位系统无法安装Net framework3.5的两种解决方案吧 在Windows10中,当我们安装某些软件的时候会提示“你的电脑上的应用需要使用以下Windows功能:.NET Framework 3.5(包括....

C#客户端(WinForm)开机自动启动实现

/// <summary> ///修改程序在注册表中的键值 /// </summary> /// <param name="isAuto">true:开机启动,false:不开机自启</param> private voi...

ANOMALY: use of REX.w is meaningless (default operand size is 64)问题处理-已解决

转载于:https://www.aix2.com/605.html,亲测有效,在此记录一下 尝试的解决方案 1:针对所有程序 注册表中增加项 计算机HKEY_LOCAL_MACHINESOFTWARETECOcular.3agentconfig 下 新建 [字符串值]  hookapi_disins,数值数据: 1 2:针对特定程序 注册表中增加项 计算机...

微服务-服务注册与发现

1.服务注册与发现基础架构 注册中心: 接受服务提供者的注册、存储服务提供者的服务信息 ,比如ip 端口号 服务名这些信息; 并且与微服务保持心跳,如果心跳不能保持则注销该实例。 所以注册中心主要提供服务提供者信息的存储,另外与服务提供者保持心跳以监控服务提供者的存活。 服务提供者: 向注册中心提供服务信息,以及一些健康状态。 服务消费者: 定期向注册中...

安装多个ORACLE导致多个Oracle HOME的情况!

Oracle由于版本的不同,在注册表中产生的注册表信息也有所不同,但主要的键值信息还是一样的,例如Oracle10g比oracle9i在注册表中表现的更为“简洁”,在未知的情况下,获取Oracle10g的相关信息,需要模糊查询一下键值  SOFTWAREORACLEKey_* Key_后面跟着是OracleHomeName的信息,默认情况如 KEY_Ora...