C#自行实现安装卸载程序(不使用官方组件)

  • C#自行实现安装卸载程序(不使用官方组件)已关闭评论
  • 103 次浏览
  • A+
所属分类:.NET技术
摘要

正规软件建议还是使用官方的标准安装程序组件,因为官方的标准安装/卸载组件能更好的与操作系统衔接,安装和卸载流程更加规范。

正规软件建议还是使用官方的标准安装程序组件,因为官方的标准安装/卸载组件能更好的与操作系统衔接,安装和卸载流程更加规范。

今天提供一种野路子,全用代码实现安装卸载器。

需要写一个程序,包含安装器、卸载器、主程序。

在visual studio中创建一个解决方案,解决方案里创建3个项目分别对应安装器、卸载器、主程序。

如图

C#自行实现安装卸载程序(不使用官方组件)

制作安装包目录时,将三个项目全部生成可执行程序。然后按下方文件结构组织安装包,复制最终程序文件到相应位置。

U8FileTransferIntaller
+-- U8FileTransfer
| +-- main
| |-- U8FileTransfer.exe
| |-- ...
| +-- uninstall.exe
+-- intall.exe

* Installer生成install.exe,用于拷贝U8FileTransfer目录到用户选择的安装路劲,注册表添加开机自启,启动U8FileTransfer.exe
* UnInstaller生成uninstall.exe,用于卸载程序(退出主程序,取消开机自启,删除main目录)
* U8FileTransfer是主程序。

卸载时会删除main目录,uninstall.exe无法自己删除自己,需手动删除。

下面只讲安装和卸载器的实现,不讲主程序。

安装器

C#自行实现安装卸载程序(不使用官方组件)

功能:复制目录及文件,注册表添加开启自启,启动程序,关闭自身

Intaller.cs 代码:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO; using Microsoft.Win32; using System.Reflection; // using System.Diagnostics;  namespace Installer {     public partial class Intaller : Form     {         private string appDirName = "U8FileTransfer";          public Intaller()         {             InitializeComponent();         }            /// <summary>         /// 复制目录(包括子目录及所有文件)到另一个地方         /// </summary>         /// <param name="sourceDirName"></param>         /// <param name="destDirName"></param>         /// <param name="copySubDirs"></param>         private void directoryCopy(string sourceDirName, string destDirName, bool copySubDirs)         {             // Get the subdirectories for the specified directory.             DirectoryInfo dir = new DirectoryInfo(sourceDirName);              if (!dir.Exists)             {                 throw new DirectoryNotFoundException(                     "Source directory does not exist or could not be found:"                     + sourceDirName);             }              DirectoryInfo[] dirs = dir.GetDirectories();              // If the destination directory doesn't exist, create it.                    Directory.CreateDirectory(destDirName);              // Get the files in the directory and copy them to the new location.             FileInfo[] files = dir.GetFiles();             foreach (FileInfo file in files)             {                 string tempPath = Path.Combine(destDirName, file.Name);                 file.CopyTo(tempPath, true);             }              // If copying subdirectories, copy them and their contents to new location.             if (copySubDirs)             {                 foreach (DirectoryInfo subdir in dirs)                 {                     string tempPath = Path.Combine(destDirName, subdir.Name);                     directoryCopy(subdir.FullName, tempPath, copySubDirs);                 }             }         }          // 文件浏览按钮事件         private void folderBrowserButton_Click(object sender, EventArgs e)         {             DialogResult dr = folderBrowserDialog.ShowDialog();             if (dr == System.Windows.Forms.DialogResult.OK)             {                 folderPathTextBox.Text = folderBrowserDialog.SelectedPath + "\" + appDirName;             }          }          // 确认按钮事件         private void okButton_Click(object sender, EventArgs e)         {             /**              * 1.复制目录及文件              */             string sourceDirName = Application.StartupPath + "\" + appDirName;             string destDirName = @folderPathTextBox.Text;             directoryCopy(sourceDirName, destDirName, true);               /**              * 2.注册表添加开启自启              */             RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);             if(key == null)//如果该项不存在的话,则创建该子项             {                 key = Registry.LocalMachine.CreateSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run");             }             key.SetValue(appDirName, destDirName + "\main\U8FileTransfer.exe");             key.Close();              /**              * 3.启动程序              */             string start = @folderPathTextBox.Text + "\main\U8FileTransfer.exe";             System.Diagnostics.Process.Start(start);              //关闭自身             Application.Exit();         }      } }

 

卸载器

C#自行实现安装卸载程序(不使用官方组件)

功能:退出运行中的主程序,删除注册表开机自启项,删除安装目录,弹出提示,退出自身

Uninstall.cs 代码:

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Diagnostics; using Microsoft.Win32; using System.IO;  namespace Uninstaller {     public partial class Uninstall : Form     {         public Uninstall()         {             InitializeComponent();         }          private void cancelButton_Click(object sender, EventArgs e)         {             Application.Exit();         }          private void confirmButton_Click(object sender, EventArgs e)         {             // 退出运行中的主程序             Process[] process = Process.GetProcesses();             foreach (Process prc in process)             {                 // ProcessName为exe程序的名称,比如叫main.exe,那么ProcessName就为main                 if (prc.ProcessName == "U8FileTransfer")                 {                     prc.Kill();                     break;                 }             }               // 删除注册表开机自启项             // 打开注册表子项             RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true);             if (key != null)             {                 try                 {                     key.DeleteValue("U8FileTransfer");                 }                 catch (Exception ex)                 {                     MessageBox.Show(ex.Message);                 }             }             key.Close();              // 删除目录             DeleteDir(Application.StartupPath + "\main");              // 弹出提示             MessageBox.Show("以卸载完成,Uninstall.exe需要手动删除");              // 退出自身             Application.Exit();                      }          /// <summary>         /// 删除文件夹         /// </summary>         /// <param name="file">需要删除的文件路径</param>         /// <returns></returns>         public bool DeleteDir(string file)         {             try             {                 //去除文件夹和子文件的只读属性                 //去除文件夹的只读属性                 System.IO.DirectoryInfo fileInfo = new DirectoryInfo(file);                 fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;                 //去除文件的只读属性                 System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal);                 //判断文件夹是否还存在                 if (Directory.Exists(file))                 {                     foreach (string f in Directory.GetFileSystemEntries(file))                     {                         if (File.Exists(f))                         {                             //如果有子文件删除文件                             File.Delete(f);                             //Console.WriteLine(f);                         }                         else                         {                             //循环递归删除子文件夹                             DeleteDir(f);                         }                     }                     //删除空文件夹                     Directory.Delete(file);                 }                 return true;             }             catch (Exception) // 异常处理             {                 return false;             }          }          } }