相关资讯
本类常用软件
-
福建农村信用社手机银行客户端下载下载量:584204
-
Windows优化大师下载量:416898
-
90美女秀(视频聊天软件)下载量:366961
-
广西农村信用社手机银行客户端下载下载量:365699
-
快播手机版下载量:325855
例1:
设想某一天,某妞将可移动磁盘插入电脑A,电脑A为她的U盘分配了盘符 F: 。该妞使用U盘上的便携软件打开了储存于U盘上的几个文档:
F:\1.doc
F:\2.doc
……
在拔出U盘的时候,她甚至没有为最后一个文件存档,反正所有进度都会自动保存嘛!
过了几日,该妞试图在电脑B继续她的工作,插入U盘以后,电脑B为她的U盘分配了盘符G: 。当她打开便携软件的时候,她会看到“最近文档”列表那里显示着什么呢?
仍然是:
F:\1.doc
F:\2.doc
……
当她试图恢复上一次”自动保存“的文档,却提示“找不到……文件”。于是,她发怒了,发誓再也不来你的网站。
这正常吗?太正常了,上次你就是在F盘打开文件的嘛。可是你还能完美地使用“最近文件”列表、继续上一次的工作吗?
我们干革命,就是要勇于把正常变为不正常。于是,我们需要盘符替换。
什么是盘符替换
所谓盘符替换 (Driver Letter Replacement),就是在检测到盘符相对上一次运行时改变的时候,将某些文件中的旧盘符替换为新盘符,以实现用户数据的完美衔接。以上述例子为例,就是在盘符转变为 G: 的时候,将最近文档列表替换为:
G:\1.doc
G:\2.doc
……
让用户体会不到盘符改变带来的变化,而顺利继续上一次的工作进程。
什么是路径替换
例2:
设想某一个软件,在配置文件中保存了大量包含软件路径的数据,这些数据在软件首次运行时生成,指向软件的插件、模板等目录,假如这些目录设置错误,该软件便无法正常运行。
而某一天,某妞将该便携软件从同盘符的一个目录移动到另一个目录,例如:从 f:\XXXPortable 移动到 f:\PortableApps\XXXPortable 。
那么,如何保证该软件正常运行呢?假如包含路径的设置项不多,我们可以一个个地写入,而假如类似设置很多(例如ACDSee),或者数量不定,难道也要一个个写入吗?所以,我们需要在检测到路径改变时,将所有的 XXXPortable 替换为 PortableApps\XXXPortable 。
目录格式
在 PortableApps.com Launcher 中,提供了四种类型的目录格式,分别是:
%VARIABLE% : 正向单斜杠。例如:%PAL:AppDir% = x:\portableapps\xxxportable\app 。主要应对ini、xml等普通配置文件。
%VARIABLE:ForwardSlash% : 反向单斜杠。例如:%PAL:AppDir:ForwardSlash% = x:/portableapps/xxxportable/app
%VARIABLE:DoubleBackslash% : 正向双斜杠。例如:%PAL:AppDir:DoubleBackslash% = x:\\portableapps\\xxxportable\\app 。主要应用于注册表(.reg)文件。
%VARIABLE:java.util.prefs% : 反向多斜杠。例如: %PAL:AppDir:java.util.prefs% = /X:///Portable/Apps///App/Name/Portable///App 。主要应用于java程序。
我们需要根据替换文件的类型选择相应的目录形式。假如遇到这四种情况以外的目录形式,则要靠 Custom Code 解决。
实现原理与流程
为了兼顾例1与例2的两种情况,避免两种情况同时发生,我们要将盘符替换与路径替换分开,那就是:先替换盘符,再替换不带盘符的路径。
在引导过程中,读取上一次记录的INI文件,判断是否盘符/路径改变。
若改变,则读取上一次的盘符/路径,转换为正确形式。
读取当前的盘符/路径,转换为正确形式。
在文件中替换旧盘符为新盘符。
在文件中替换旧路径为新路径。
将当前的盘符、路径写入INI文件,以便下一次读取。
在 PortableApps.com Launcher 中实现:
以ACDSee Portable为例,我们需要在引导过程中替换注册表文件 HKCU.reg 中的旧盘符\路径为新。
[FileWrite1]
Type=Replace
File=%PAL:DataDir%\settings\HKCU.reg
Find=%PAL:LastDrive%\\
Replace=%PAL:Drive%\\
[FileWrite2]
Type=Replace
File=%PAL:DataDir%\settings\HKCU.reg
Find=%PAL:LastPackagePartialDir:DoubleBackslash%
Replace=%PAL:PackagePartialDir:DoubleBackslash%
效果如下:
x:\\
替换为:
y:\\
\\xxx\\AppNamePortable
替换为:
\\yyy\\AppNamePortable
请注意,在 [FileWrite1] (盘符替换)中,我在 %PAL:LastDrive% 后面加上了双斜杠。这是因为,%PAL:LastDrive% 是不带斜杠的(x:)。可能出现这种情况:替换 D:,把 DWORD: 的最后两个字母也替换了。难道PortableApps.com的人不担心这种情况吗?我认为使用PAL替换盘符的时候都要注意这一点,替换盘符一定要加斜杠。
在 Custom Code 中实现:
PortableApps.com Launcher 是一个死板的网站的死板的程序员做出的死板的工具,在险峻难料的革命事业中,我们要坚决摒弃教条主义思想。许多时候稍有变化,我们就需要用到 Custom Code 。那么,在NSIS语言中怎样实现呢?
例如,一个程序以这样的形式在 Data\File.txt 记录路径:
F__PortableApps_App_Portable
“:”、“\”、“空格”三种符号都转换为下划线。让我们来写一段 Custom Code 来解决它。
${SegmentPrePrimary}
; 替换盘符
; 首先读取Ini文件中的记录
ReadINIStr $0 $DataDirectory\settings\$AppIDSettings.ini $AppIDSettings LastDrive
; 替换三种符号为下划线
${WordReplace} "$0\" "\" "_" "+" "$R0"
${WordReplace} "$R0" ":" "_" "+" "$R0"
${WordReplace} "$R0" " " "_" "+" "$R0"
; 得到当前盘符
StrCpy $R1 "$AppDirectory" 3
; 替换三种符号为下划线
${WordReplace} "$R1" "\" "_" "+" "$R1"
${WordReplace} "$R1" ":" "_" "+" "$R1"
${WordReplace} "$R1" " " "_" "+" "$R1"
; 在文件中替换
${ReplaceInFileCS} "$DataDirectory\File.txt" $R0 $R1
; 替换路径
; 首先读取Ini文件中的记录
ReadINIStr $0 $DataDirectory\settings\$AppIDSettings.ini $AppIDSettings LastDirectory
; 替换两种符号为下划线
${WordReplace} "$0" "\" "_" "+" "$R0"
${WordReplace} "$R0" " " "_" "+" "$R0"
; 得到当前路径(不带盘符)
StrCpy $R1 "$AppDirectory" "" 2
; 替换两种符号为下划线
${WordReplace} "$R1" "\" "_" "+" "$R1"
${WordReplace} "$R1" " " "_" "+" "$R1"
; 在文件中替换
${ReplaceInFileCS} "$DataDirectory\File.txt" $R0 $R1
!macroend
请注意文件的编码,如果是 UTF-16LE 编码,用 ${ReplaceInFileUTF16LECS} 。若需要忽略大小写,取消最后的“CS”。
在原始NSIS脚本中使用,需要另外:
!include "TextReplace.nsh"
!include "ReplaceInFileWithTextReplace.nsh"
注意事项
盘符与路径替换是一种简单地衔接工作环境的方法,但我认为,在应用中需要注意以下几点:
一定要确定你替换的是盘符/路径,而非别的东西。例如,使用PAL的时候,在盘符后加入斜杠,替换 x:\ 而不是 x: 。
自行撰写代码时,注意所替换文件的编码。
在替换大文件或多次替换之间,加入Sleep。否则可能遇到替换失败。
对于重要路径,最好在替换后手动写入一次,以保障无误。盘符替换依赖INI文件中的记录,假如一次记录与实际衔接不上,可能从此都衔接不上了。
本文导航
- 第1页: 首页
- 第2页: 盘符替换与路径替换
- 第3页: 善用DefaultData