(转载整理)程序安装流程及如何实现文件在系统后自动重启(windows)

本文主要是介绍(转载整理)程序安装流程及如何实现文件在系统后自动重启(windows),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

软件在安装时,到底做了些什么? 大家每天都在用电脑,可能也经常在自己的电脑上安装软件。就算自己没安装过,至少也看到人家安装过软件。在这里,我不是想教你怎么安装软件,而是想向你展示,软件在安装的过程中,到底都做了些什么动作?为什么有些软件要安装,直接拷贝过去却不能用?为什么一些软件安装或卸载之后要重启。下面要讨论的就是这些问题。

    首先,我们探讨一下软件安装的共通部分,说共通,就是在不同版本的操作系统上,如WINDOWS98,WIN2K和WINXP等上它们都有共同点的地方。这个文章也试图不针对具体的某个操作系统,而对共同的规律来探讨,不过我自己用的是WINDOWS98,所以有时一些例子可能会用WINDOWS98上的实例来说明,而大多数情况下这些特***在WIN2K和WINXP上也是类似的。

    那么,我先来归纳一下,典型的软件安装过程都有可能做哪些事情。由于我们是讨论软件在安装时的行为,所以开始安装前的设置和选项我们就暂不讨论,只说到软件真正开始安装那个时候起的动作:

①文件从安装源位置拷贝到目标位置。

②往系统目录写入一些必要的动态连接库(DLL)。(可选)

③往系统注册表中写入相应的设置项。(可选)

④建立开始菜单里的程序组和桌面快捷方式。(可选)

⑤其他动作。(可选)

     下面我们再详细来分析上面归纳出来的这些动作:

1)拷贝软件本身需要的文件。源位置指软件未安装之前的位置,例如光盘,下载的目录等,目标位置指你指定的安装位置。

这是几乎所有的软件安装过程一定会做的一件事。而如果一个软件,在安装时只要这一步,不需要后面的其他几步,我们可以认为这个软件就是绿色软件。或者反过来说绿色软件就是只要拷贝文件,不需要依赖于某个DLL,或者它依赖的DLL在几乎所有的系统中都一定有的,并且它也不依赖于注册表里面的设置项的软件。

2)这一步,可以说至少有一半软件在安装时都会做,一些软件,需要用到某个DLL,特别是那些软件作者开发的DLL,或者系统中不常用的DLL,一般都会随软件的安装拷到系统目录。所谓系统目录,在WIN98下一般是在WINDOWS/SYSTEM这个目录,而WIN2K是在WINNT/SYSTEM32,WINXP是在WINDOWS/SYSTEM32。还有,一些软件如QQ游戏,中游等,它们也用到一些DLL,由于这些DLL只是这个软件自己用到,别的其他软件不会用到,所以它们并不一定存在于系统目录,而是放在软件安装目录里面,这样的DLL已经在上一步中被拷贝,所以和这一步说的情况不一样。

3)这一步同样至少有一半软件会做,一般在安装前用户的设置和一些选项,在安装时就会把这些设置写到注册表里。另外就是有时在上一步把DLL拷贝到系统目录时,一些DLL需要向系统注册,这些DLL的注册信息也会写在注册表里。还有,一些软件有时可能安装时并不写注册表,而是在第一次运行时才把一些设置写到注册表。

4)这个非常简单,大概不需要怎么解释。建立这些快捷方式一方面是便于用户执行,另外在时也会把卸载的快捷方式放在程序组里。关于卸载后面我们再来讨论。

5)这个就是除了上面说的以外的其他情况。例如有些软件安装时会先把所有文件(或一部分文件)先解压到临时目录,那么安装完之后就要把这些文件删除掉。

    那么我们再总结一下:

一、一个典型的软件在安装过程一般都会执行上面的1-4项。这样可以认为是一个完整的安装过程。

二、除了第1项之外,其他的都不是必要的。只需要第一项的软件,我们可以把它叫做绿色软件。

三、有些软件安装时是执行了1、2、4,有些软件是执行了1、3、4,有些软件是执行了1、4。

四、一个特殊的情况,一般的驱动程序,只会执行2和3,没有1和4。

五、理论上,任何软件,如果你非常确切地知道了它在上面的那几步都具体做了些什么,特别是2和3,那么,理论上你可以把这个软件的安装文件拷贝到另一台机子,把必要的DLL从系统目录拷贝到那一台机子的系统目录,再把注册表里软件写入的项目导出来(必要时还要修改一下)再导入到那台机子的注册表中,那么,就算不是绿色软件,你也能这样把它移植给另一台机。但有时特别是一些共享软件,一般都会有注册表中设置比较隐蔽的项目,不容易查找,所以除非你对系统非常熟悉,否则不是绿色软件的软件要移植还是有一定的难度的。

     那么,下面我们再来看看,为什么一些软件安装后要重启。

在WINDOWS操作系统上,一般一个正在运行中的程序,操作系统是不让你修改它的,修改包括替换,改动和删除。那么有时,一些软件需要向系统目录中写入一个DLL,而系统目录中原来已经有同名的DLL并且这个DLL目前正在被系统使用,因此不能用新版本去替换它,这个时候就需要重启,在重启的过程中,在这个DLL旧的版本被使用之前用新版本替换它。这就是为什么要重启的原因。

你能看到这里,说明你很有耐心,并且对技术的探讨很有兴趣,那么我就再说得更详细些。在WIN98中,上面说的这个替换是由系统的一个工具来实现的,这个工具叫WININIT.EXE。安装程序在检测到需要写入的DLL或其他程序文件正在使用时,会把要写入的DLL文件先定一个临时的文件名,然后在WINDOWS目录中往WININIT.INI写入一个改写项,比如,一个叫ABCD.DLL的动态连接库现在正在使用中,而安装程序要往系统中写入新版本的ABCD.DLL,这时安装程序会把新版本ABCD.DLL先定一个临时文件名,例如AAAA.LLL,然后在WININIT.INI中的[rename]一节中写入这一项: ?篩l罉枓犮
 C:/windows/system/abcd.dll=C:/windows/system/aaaa.lll CX=B)
 这样,在重启时,进入WINDOWS图形界面之前,WININIT.EXE在检测到WINDOWS目录中有WININIT.INI存在时,就执行里面的操作,在上面的例子中,是用C:/windows/system/aaaa.lll去替换掉C:/windows/system/abcd.dll这个文件,并且把WININIT.INI改名为WININIT.BAK。

     另外,有些软件,在安装时,是把所有文件包括SETUP.EXE解压到临时文件里面再执行SETUP.EXE进行安装的,按理来说安装完要把所有的临时文件删除掉,这个操作当然也是由安装程序SETUP.EXE来完成,但它自己正在运行,也删不了它自己,所以也要重启来删除,做法和上面差不多,只是改成类似这样子的: 怦S?vH燁?
 NUL=C:/WINDOWS/TEMP/SETUP.EXE

    在WIN2K和WINXP中,存在类似的机制,不过并不是用WININIT.EXE和WININIT.INI来实现,具体的做法我也不是很清楚,长期以来我大多数时候都是在用WIN98,所以没认真研究过,但软件安装过程要重启的现象在2K和XP上是仍然存在的,原理也是在重启时替换或修改正在使用的文件,只是实现的方式不同。

    最后,我们再来看看有关卸载方面的内容。一般卸载有好几种方式:

1)早期的安装程序,一般会在安装过程记录了上面说的安装过程的1234四个步骤中具体拷贝的文件和DLL以及注册表项,把它保存在INSTALL.LOG之类的文件中,再在软件的安装目录(或WINDOWS目录中)放一个UNINST.EXE之类的卸载程序。然后要么在程序组里为这个UNINST.EXE建一个快捷方式,要么在注册表中为这个UNINST.EXE建一个快捷方式(这诳刂泼姘宓奶砑由境绦蚓湍芸吹饺砑男对叵?,并把INSTALL.LOG做为它的参数,这样就实现卸载了。

2)现在比较多的安装程序是用新版的INSTALLSHIELD生成的,安装时的记录和卸载程序一般是会放在C:/Program Files/InstallShield Installation Information这个文件夹(隐藏属***)里,同样也会在程序组和注册表中建立卸载项。

    另外,在卸载时,也会遇到文件(一般是DLL文件)正在使用的情况。所以有时卸载的时候也要重启,就是要在重启过程中删掉这些正在使用的DLL文件。

非绿色软件的安装一般要修改注册表,而注册表修改后要重启才能生效。
有些软件安装后的运行并不马上需要使用到注册表是的内容,而有些却马上要用到,所以有的软件安装完后要重启,而有些不用!

 

 

 

 

大家都知道有很多的程序(有其是一些杀毒软件)在无法删除某个文件的时候,可以在重启后再删除。。。
其实实现的方法很简单,完全就在MoveFileEx函数身上。。。

具体方法可以参阅MSDN。

其实在重启后删除一个文件早在windows98/me上就有方法了,就是在WININIT.INI文件中的文件都会在系统重新启动后被删除。。。

在2000/xp/2003下就是使用MoveFileEx函数了。。。
代码如下:


Quote:

#include<windows.h>
#include<stdio.h>

voidusage(char*);

intmain(intargc,char*argv[])
{
  HANDLEhfile;
  WIN32_FIND_DATAfindfiledata;

  if(argc!=2)
    usage(argv[0]);

  printf("/t/tDeleteFileOnReboot/n/n");
    printf("/t/t无敌最寂寞@EST/n/n");

  printf("[*]NowChecking%sifitexist..",argv[1]);
  hfile=FindFirstFile(argv[1],&findfiledata);

  if(hfile=INVALID_HANDLE_VALUE)
    {
       printf("ERROR!filemaynotexist!/n");
       return0;
    }

  printf("OK!/n");
 FindClose(hfile);

  printf("[*]Nowtryingtomarkthefile%stodeleteonreboot...",argv[1]);

  if(!MoveFileEx(argv[1],NULL,MOVEFILE_DELAY_UNTIL_REBOOT))
    {
       printf("ERROR!markfilefailed%d/n",GetLastError());
       return0;
    }

    printf("OK!/n");
    printf("/n/n[*]NOWyoucanwaituntilreboottodeleteyourspecifiedfile!/n");

    return0;
  }

  voidusage(char*name)
  {
    printf("/t/t DeleteFileOnReboot/n/n");
    printf("/t/twrittenby无敌最寂寞@EST/n/n");
  printf("/t/tworkonwindows200/xp/2003/n/n");
    printf("Usage:/n");
    printf("/t%s<full-path-file-name>/n",name);
   exit(0);


代码是很简单的。。我就不做解释了。。。

我编译好的程序可以在下面下载。。。

 

 

 

实际上这个函数所做的工作就是将要删除的文件加入到下列注册表项目中:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/PendingFileRenameOperations

这篇关于(转载整理)程序安装流程及如何实现文件在系统后自动重启(windows)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/744522

相关文章

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

Nginx分布式部署流程分析

《Nginx分布式部署流程分析》文章介绍Nginx在分布式部署中的反向代理和负载均衡作用,用于分发请求、减轻服务器压力及解决session共享问题,涵盖配置方法、策略及Java项目应用,并提及分布式事... 目录分布式部署NginxJava中的代理代理分为正向代理和反向代理正向代理反向代理Nginx应用场景

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

Linux挂载linux/Windows共享目录实现方式

《Linux挂载linux/Windows共享目录实现方式》:本文主要介绍Linux挂载linux/Windows共享目录实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录文件共享协议linux环境作为服务端(NFS)在服务器端安装 NFS创建要共享的目录修改 NFS 配

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注