首页 > 编程语言 >C#自行实现安装卸载程序(不使用官方组件)

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

时间:2023-03-11 09:33:43浏览次数:54  
标签:exe string U8FileTransfer C# System 卸载 组件 using

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

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

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

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

如图

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

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

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


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

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

安装器

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

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();
        }

    }
}

 

卸载器

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

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;
            }

        }
    
    }
}

 

标签:exe,string,U8FileTransfer,C#,System,卸载,组件,using
From: https://www.cnblogs.com/jsper/p/17205288.html

相关文章

  • GenericAPIView的9个视图子类
    1.基于GenericAPIView下的9个视图子类功能关系梳理fromrest_framework.genericsimportCreateAPIView,ListAPIView,UpdateAPIView,RetrieveAPIView,DestroyAPIView,......
  • 富文本组件中图片间空白处理小技巧
    今天在网上搜索了一下,处理富文本空白的方法,各种各样的都有有一个是对富文本组件设置font-size:0的,我试了一下,唉,还真的好使,空白间隔果然没了。可是看这个设置,fontsize,一......
  • 关于Windows下-目录文件数量变化-造成资源管理器对cpu的高消耗问题分析
    今天笔者写了一个py脚本去处理Windows下一个目录Upload的文件,也就是将文件按照一些规则进行分类移动管理文件的数量近20万,笔者发现在处理过程中cpu几乎一直99%~100%,如下......
  • Vue实现div可拖动组件 并可操纵盒子大小
    Vue实现div可拖动组件并可操纵盒子大小借鉴文章:https://blog.csdn.net/qq_46103732/article/details/128902192场景:在pc端项目中会碰到弹框后多个页面重叠的场景,类似......
  • CS61A Fall 2020 Homework 2 Recursion 我的思路
    HW2Description:https://inst.eecs.berkeley.edu/~cs61a/fa20/hw/hw02/我会把题目倒着放,因为通常后面的题能带给我的思考更多(也更可能做不出来......
  • 前端面试基础cheatsheet
    1.继承2.判断数组console.log(Array.isArray(arr));//trueconsole.log(arrinstanceofArray);//trueconsole.log(arr.constructor===Array);//trueconsol......
  • Nacos2.2.0安装启动报错
    安装Nacos2.2.0版本后,通过单机模式启动,startup.cmd-mstandalone,报如下错误:2023-03-1108:29:58,627ERRORApplicationrunfailedorg.springframework.beans.facto......
  • 01-C语言概述
    C语言概述1.什么是C语言C语言就是人和计算机交流的一种语言语言是用来交流沟通的。有一方说,有另一方听,必须有两方参与,这是语言最重要的功能:说的一方传递信息,听的一方......
  • mac安装bee提示 zsh: command not found: bee
    无论是.bash_profile还是.zshrc文件都配置了环境变量exportGOROOT=/usr/local/goexportGOPATH=/Users/xxxx/Documents/Project/GoexportGOBIN="$GOPATH/bin"expo......
  • A. Computer Game【dfs诈骗】
    A.ComputerGame代码点击查看代码#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue......