关于软件便携/绿化的更优方案

首先进行定义:

  • 便携化,是指配置文件和所有程序组件在一个文件夹中的软件,并且在一般系统环境下可启动
  • 绿化,是指运行结束后不留下相关信息的软件

目前软件便携化与绿化方案大致分为三种

原生

也就是软件在设计时即支持绿色与便携化
显然,这种软件无需便携化/绿化

附加安装、卸载器

例如大部分绿色软件带的绿化脚本本质上就是安装器,清理脚本本质上就是卸载器

这类方案中,最优秀的代表是portableapps。
它的启动器集成了安装器和卸载器的功能,并且支持备份启动前的原有配置
但是,缺点也很明显:

  1. 软件一旦非正常结束,启动器就不能正常清理
  2. 软件在启动前必须要执行至少两次拷贝(备份原配置,复制新配置)才能启动软件。在软件结束后,同样要执行两次拷贝。而如果配置文件较多,耗时将极大
  3. 不能有同一个软件的不同版本同时读取一个配置文件,否则,部署器和清理器很可能出错

创建虚拟环境

此方案其实是为软件创建一个沙盒
代表有Enigma Virtual Box、VMware Thinapp
缺点就比较多了:

  1. 不支持保存配置,不便于保存文件(这不是方案的缺点,但是目前对该方案具体实现的工具还没有能够支持保存配置文件的)
  2. 兼容性差,这是沙盒的硬伤,沙盒一直都有这个问题
  3. 性能损失大,原因同上

基于对上述方案进行反思,发现软件便携化和绿化最优的解决方案是原生。如果原生不能用,那么在绿化便携化时退而求其次,将软件改成接近原生绿色便携的样子

具体是:

  1. 将注册表写入统一改为文件写入
  2. 将分散到各用户文件夹的组件、配置文件集中到软件所在文件夹中的几个专用文件夹
  3. 驱动和服务的安装暂无更优办法

这样就避开了虚拟化导致的不兼容、避开了软件启动前拷贝到长耗时操作、避开了对部署/清理器的依赖、避开了可能和已存在软件之间的不兼容

再具体一点,我们到代码实现层级。总结一下,只需要对以下三个地方修改即可

  1. 写注册表
  2. 加载其他文件夹的组件
  3. 写入其他文件夹的配置文件

那么,我们可以发现,在Windows中,刚好这三类都有对应的winapi完成任务

  • 写注册表对应Reg系API,实际只有读写查三种会用到
  • 加载组件只有loadlibrary对应
  • 写文件对应File系api,实际只有OpenFile和CreateFile的变形会用到

上面的操作必定调用这些api完成,因此想到了对api进行篡改,利用Hook技术,这个任务是有可能完成的

目前的进度:

  • 使用c++完成任务,通过dll注入,已经实现了在大部分程序打开任意文件前弹窗提示文件名
  • 改用c语言完成任务,基于上,成功重定向配置文件到;另外,重定向操作排除了所有用户手动保存的文件
  • 正在寻找可用的实际软件用于测试…
  • 正在添加对注册表操作的拦截…
  • 待续
4 个赞

原生支持当然最好,也不用讨论。
个人觉得HOOK的方式容易被安全软件拦截,当然可以加白名单。
目前我采用的方式是通过批处理启动,重定向文件路径和写入注册表,结束后删除,其实也不完美,但没更好的办法。

关于被安全软件拦截的事情,应该有方法可以避开。只要保证绿化程序不可能对系统造成威胁,安全软件就不会拦截。另外,具体实现上除了hook还可以用静态修改的办法

好奇的是您怎么通过批处理重定向文件路径的

这个安全软件各家处理都不同,如果文件会释放文件执行,有的安全软件也会报。
批处理调用mklink进行文件路径重定向。

此方案的实际实现中不需要释放文件啦,只需要在程序中插一段代码而已
关于批处理,我之前也是这样做的,但是发现出错的概率很高效率也很慢,并且还是需要先把原来的配置文件改名后才能mklink,与附加安装卸载器的缺点一致

@3_5105 写的很好,就是格式有点小问题,给你修了。你看一眼确认一下,意思应该是没变的

想问下用户端是怎么实现的?比如通过运行程序手动插入,还是启动器或者别的?

这几点我都没理解,因为我都没碰到过,可否具体举例一下。
效率快慢我觉得最多就是黑窗口一闪而过,我现在连启动VM虚拟机都用CMD,当然不是为了便携。

目前的实现大致如下
编写一个DLL,当这个DLL被加载时,会将所有winapi调用重定向到DLL内部的一些预先写好的函数
在被便携化的exe的导入表中插一个DLL加载项,这样在EXE启动后,这个DLL会被立即加载

关于效率,您应该熟悉,mklink要求所创建的软链接不与现有文件(夹)重名。那么,如果需要在不干扰已有配置的情况下使用此方法重定向,则需要:
1,先修改已存在的配置文件夹名称
2,创建软链接
3,运行程序(这时候程序写入文件被软链接重定向)
4,程序运行结束
5,把原来的配置文件夹的名称改回去

效率低是因为之前做某程序绿化时发现共有11个文件夹需要重定向——这个数量其实不算多,但是对这些文件夹进行重定向大概需要花费3到5秒,如果每次程序启动都需要花费这些时间,效率其实是很低的
出错概率高是因为涉及大量写磁盘操作,不知道会有什么其他程序读取同一个文件夹或者权限问题之类的
还有一个问题:这个重定向方案必须先修改已有配置文件夹名称,故不能与已有程序同时运行

我都是配置迁移,确实没考虑这种情况。