论坛首页
论坛首页 开发者论坛 PortableApps开发 如何处理需要写入到系统文件夹的文件?

如何处理需要写入到系统文件夹的文件?

讨论关于便携软件开发的技术与问题,包括PAL、NSIS、VMware ThinApp及其他。
paulhybryant 头像
分舵香主
分舵香主

帖子: 56
如果要便携化的软件在安装过程中把一些文件写到系统文件夹
(比如一些dll文件到system32下,或者common files),这样的情况通常如何处理?
可否通过设置某些环境变量?

如果这些dll还需要用regsvr32来注册呢?

谢谢

paulhybryant 头像
分舵香主
分舵香主

帖子: 56
看了一下portableapps.com的文档,有这么一段

HKLM\Software\Classes\CLSID\XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX¶(Where X is a hexadecimal digit.)
These are DLL servers and need registering. For the moment, this will block an app from being properly portable. Code to deal with this is due in version 2.2.

似乎对于这些dll的处理的代码正在被开发。

David Pi 头像
建寨老工
建寨老工

帖子: 213

  1. 一般很少有软件真正需要把一些东西放到Windows目录或者CommonFiles才能运行。VC库,程序的一部分,可以试试放到程序根目录,看能不能运行。如果程序不能找到它们,还可以设置PATH变量。只有实在没办法,才应该拷到系统中去,因为这样增加启动时间,非正常退出留下的东西也比较多。

    PAL的DirecotriesMove或者FilesMove可以用来移动文件夹。但是:
    • 只能移动 Data 目录中的文件夹
    • 结束时会把文件复制回来,对于程序文件这是没必要的

    所以只能用 Custom Code 。
    例如需要把 App\CommonFiles 复制到 %CommonFiles%\AppName
    首先在 Launcher.ini 中把%CommonFiles%\AppName保护起来:
    代码: 全选
    [DirectoriesMove}
    -=%CommonFiles%\AppName

    然后在 Custom.nsh 写:
    代码: 全选
    ${SegmentFile}
    ${SegmentPreExecPrimary}
       CreateDirectory "$COMMONFILES\AppName"
       CopyFiles /Silent "$AppDirectory\CommonFiles\*.*" $COMMONFILES\AppName
    !macroend

    就可以了。

  2. PortableApps.com Launcher 因为是一个通用的启动器,比较保守。注册DLL需要根据不同的软件采取不同策略,无法用通用的方法完成。在PAL中注册DLL同样要用到Custom Code,另外为了不破坏本地安装,还应该把该DLL修改的注册表都备份起来。

    首先用 Total Uninstall 或者 RegShot 监视一个 Dll 注册对注册表的修改。全部导出,删减掉重复部分。在 Launcher.ini 中备份这些键值,可能有上百条:
    代码: 全选
    [RegistryKeys]
    -=HKCU\Software\Classes\AliFileCheck.File
    -=HKCU\Software\Classes\AppID\AliIMX.DLL
    -=HKCU\Software\Classes\AppID\{4BBFA195-E7B2-4DD5-977E-C8576ABEE80E}
    -=HKCU\Software\Classes\CLSID\{017CE1A6-416F-4684-AE6A-02064420B30A}
    ......


    然后在Custom.nsh中注册DLL:
    代码: 全选
    ${SegmentPreExecPrimary}
       SetOutPath "$AppDirectory\AliWangWang"
       ExecWait 'regsvr32 /s "$AppDirectory\AliWangWang\AliIMX.dll"'
    !macroend


    结束时反注册:
    代码: 全选
    ${SegmentPostExecPrimary}
       SetOutPath "$AppDirectory\AliWangWang"
       ExecWait 'regsvr32 /s /u "$AppDirectory\AliWangWang\AliIMX.dll"'
    !macroend


    如果确信修改的注册表全部都备份了,不反注册也无所谓,需要多次监视验证。
    可以参考阿里旺旺便携版。

paulhybryant 头像
分舵香主
分舵香主

帖子: 56
非常感谢David的回复。用Custom code的方法做了一个WinCHM的便携版。
WinCHM一定要把dll放在system32和%commonprogramfiles%下。不过只有4个很小的文件(dll和ocx),
所以运行前copy和结束时清除不会太花时间。

paulhybryant 头像
分舵香主
分舵香主

帖子: 56
上面提到用custom.nsh中注册dll
使用了regsvr32, NSIS里有一个内置的RegDll命令,
使用这个命令和用regsvr32有什么不同么?

jooseng 革命同志
革命同志

帖子: 3474
Hi paulhybryant ,

PAF 格式我还没开始学,帮不了你。不过我学过一点WinPenPack 格式(http://www.winpenpack.com) 的做法。我做了一个,
在制作的过程中,我发现只要把那4个dll/ocx 丢到它所要的地方就可以了,不用注册。它一定要在那个地方,所以它会自己去找。

David Pi 头像
建寨老工
建寨老工

帖子: 213

paulhybryant 写道:
上面提到用custom.nsh中注册dll
使用了regsvr32, NSIS里有一个内置的RegDll命令,
使用这个命令和用regsvr32有什么不同么?


在我的经验中,最好是调用regsvr32.exe而不要用内置的regdll命令。在某些情况下,regdll命令会占用dll文件,即使反注册后,launcher也无法将之删除。另外,在某些机器上,regdll可能造成launcher崩溃或卡死。用regsvr32.exe唯一的缺点是用户会看到一个小“沙漏”。

jooseng 写道:
PAF 格式我还没开始学,帮不了你。不过我学过一点WinPenPack 格式( http://www.winpenpack.com ) 的做法。我做了一个,
在制作的过程中,我发现只要把那4个dll/ocx 丢到它所要的地方就可以了,不用注册。它一定要在那个地方,所以它会自己去找。


如果仅仅是程序需要找到某个dll文件的话,可以试着放到程序根目录,或者设置path变量。如果一定要拷到系统目录,那么就必须要管理员权限了。

paulhybryant 头像
分舵香主
分舵香主

帖子: 56
jooseng 写道:
Hi paulhybryant ,

PAF 格式我还没开始学,帮不了你。不过我学过一点WinPenPack 格式(http://www.winpenpack.com) 的做法。我做了一个,
在制作的过程中,我发现只要把那4个dll/ocx 丢到它所要的地方就可以了,不用注册。它一定要在那个地方,所以它会自己去找。


谢谢jooseng的回复。我觉得可能dll和ocx被winpenpack格式里的程序注册了。dll和ocx应该要被注册才能使用,否则程序应该是找不到的吧。

jooseng 革命同志
革命同志

帖子: 3474
paulhybryant 写道:
...我觉得可能dll和ocx被winpenpack格式里的程序注册了。dll和ocx应该要被注册才能使用,否则程序应该是找不到的吧。

winpenpack 的 launcher 是不会自动注册的。有一些软件我是用bat file 来注册的。
但这个不必。

achung 两把菜刀
两把菜刀

帖子: 12
我是一个刚要开始学的新手
想请教如何设置PATH变量

paulhybryant 头像
分舵香主
分舵香主

帖子: 56
在launcher.ini里面使用[Environment]
详见http://portableapps.com/manuals/PortableApps.comLauncher/ref/launcher.ini/environment.html

jooseng 革命同志
革命同志

帖子: 3474
刚学处理 Common Files 文件夹。发现 Common Files 的 Windows 环境变量是 %CommonProgramFiles% 不是 %CommonFiles%。


回到 PortableApps开发