转自http://wiki.forum.nokia.com/index.php

概述

有多款免费或商用S60应用程序支持“蓝牙分享”功能, 例如广受欢迎的免费软件Paint Pad就有一个“分享应用程序”菜单项,当选择该菜单项时它能通过蓝牙向配对设备发送一份安装包。通过观察能发现,该应用程序在安装过程中将安装包备份到了系统盘(C:盘)。本文(附以一个完整的示例程序)展示如何实现这个功能。
方案

总的方案可以用一句话阐明:我们需要开发一个在安装时执行的程序,该程序可以找到包含它的sis文件并将该文件拷贝到指定位置。这句话的前半部分可以通过包文件的高级选项 FR、RI和RW等实现。(注意:这些选项对于自签名的安装包不起作用),所以我们将注意力放在后半部分上。

在讨论如何查找正在被安装的sis文件之前,让我们先提两个假设,以简化我们的调查过程。

假设一:sis文件在被安装的过程中处于打开状态

该假设可以通过以下测试用例确认,

第1步:使用S60文件管理器打开一个sis文件

第2步:使用另一个文件管理器删除该文件,删除失败并报错“已被使用!”,这表示sis文件处于打开状态(即正在被安装程序使用)

假设二:同一时间只能安装一个sis文件

该假设可以通过以下测试用例确认,

第1步:使用S60文件管理器打开一个sis文件,并按安装程序的提示操作,直到出现盘符选择对话框

第2步:使用另一个文件管理器打开该文件,操作失败并报错“安装程序已经在运行,无法再次启动”,这说明安装程序是单实例的。

在这两个假设下,刚才的问题可以被简化成:如何查找一个打开的sis文件?(当然可以用sis文件的其它特性进一步确认,例如文件的UID)。一个显而易见的答案是遍历整个文件系统逐一对比查找文件,它可以作为备选方案一,

备选方案一:通过遍历整个文件系统查找所需要的文件。

这个方案可以用File Server client APIs实现,例如TFindFile和CDirScan,但是在系统盘和大容量存储器上可能有几十个目录和几百个文件,为了避免安装时长时间的等待,最好能减小文件查找的范围。值得庆幸的是,有一个系统APITOpenFileScan能获取所有处于打开状态的文件 - 这正是我们想要的!

备选方案二:使用TOpenFileScan,通过遍历所有打开的文件查找所需要的文件。

在使用这个方案时小心两个“陷阱”:一是每次调用TOpenFileScan::NextL()只会创建某个特定的文件服务器会话打开的文件列表,所以必须循环调用该函数,只到它返回NULL或者找到所需要的文件;二是通过这个API获取的文件名不带盘符,例如是"//data//HelloWorld.sis"而不是"C://data//HelloWorld.sis"。

...
    _LIT(KExtSis, ".sis");
    _LIT(KExtSisx, ".sisx");
    RFs fs;
    TInt err = fs.Connect();
    User::LeaveIfError(err);
    CleanupClosePushL(fs);
        TFileName filename;
        TOpenFileScan ofs(fs);
        TBool done = EFalse;
        while(!done)
            {
            CFileList* fl = NULL;
            ofs.NextL(fl);s
            if (fl==NULL) /** NextL()应该被反复调用,直到它返回NULL */
                {
                done = ETrue;
                }
            else
                {
                CleanupStack::PushL(fl);
                    TInt count = fl->Count();
                    for (TInt i= 0; (i<count)&&(!done); i++) /** 对于每一个处于打开状态的文件 */
                        {
                        TEntry entry = (*fl)[i];
                        TParsePtrC parse(entry.iName);
                        if((parse.Ext()==KExtSis)||(parse.Ext()==KExtSisx)) /** 查找第一个类型是sis的文件 */
                            {
                            filename = entry.iName;
                            done = ETrue;
                            }
                        }
                CleanupStack::PopAndDestroy(fl);
                }
            }
        if(filename!=KNullDesC)
            {
            /** 找到了!注意:文件名不含盘符 */
            }
    CleanupStack::PopAndDestroy(&fs);
...

文件名找到了,但在支持Data caging的系统中程序并不总能在所有目录之间拷贝文件,因此在执行拷贝操作之前让我们看一下文件可能保存在哪些目录中,
目录     说明
信息应用程序的私有目录     即文件是通过蓝牙、红外或其它协议发送到手机上的,这种情况下必须使用Messaging APIs获取文件
其它私有目录     不太可能,因此忽略这种情况
/resource目录     不太可能,而且任何应用程序都能读取资源文件下的文件
/sys目录     不太可能,因此忽略这种情况

了解了这些情况就能继续编码了。如果文件位于信息应用程序的私有目录,那么必须使用Messaging API获取它。Messaging API的使用不是本文的重点,因此这里不再赘述。本文的示例程序能够提取处理蓝牙信息的附件,如果感兴趣的话可以看一下CSmsHandler::ExportInboxToFileL()的实现。

如之前提到的,我们获取的文件名没有盘符,因此我们必须使用RFs::DriveList()列出所有可用的盘符,然后逐一检查文件是否存在,如果存在还要进一步检查该文件是否处于打开状态(即无法被修改)。如果一切顺利的话最终我们能用盘符补全文件名,然后就能将文件拷贝到指定位置(例如本文的示例程序将文件拷贝到c:/sisback目录)

...
_LIT(KSisBackup, "c://sisbackup//backup.sis");
_LIT(KMessagingPrivateFolder, "//private//1000484b//");
_LIT(KPrivateFolder, "//private//");
_LIT(KSysFolder, "//sys//");
...
        if(filename!=KNullDesC)
            {
            /** 续上,找到了! */
 
            BaflUtils::EnsurePathExistsL(fs, KSisBackup); /** 确保目标目录存在 */
 
            filename.LowerCase(); /** 将所有字符转换成小写以方便比较 */
 
            if(filename.Find(KMessagingPrivateFolder)==0)
                {
                /** 文件位于信息应用程序的私有目录,无法直接获取,但可以尝试用Messaging API获取 */
                }
            else if(filename.Find(KPrivateFolder)==0)
                {
                /** 文件位于其它私有目录,无法直接获取 */
                }
            else if(filename.Find(KSysFolder)==0)
                {
                /** 文件位于系统目录,无法直接获取 */
                }
            else
                {
                /** 文件位于其它目录(包括资源文件),可以直接获取 */
 
                _LIT(KDriveC, "c:");
                filename.Insert(0, KDriveC); /** 文件名无盘符,因此添加占位符 */
                TBool found = EFalse;
                TDriveList driveList;
                err = fs.DriveList(driveList);
                User::LeaveIfError(err);
                for(TInt driveNumber=EDriveA; (driveNumber<EDriveZ)&&(!found); driveNumber++)
                    {
                    if (driveList[driveNumber]) /** 遍历所有可用盘符 */
                        {
                        TChar driveLetter;
                        err = fs.DriveToChar(driveNumber,driveLetter);
                        User::LeaveIfError(err);
                        filename[0] = driveLetter;
                        TEntry entry;
                        err = fs.Entry(filename, entry);
                        if(err==KErrNone) /** 检查文件是否在该盘上 */
                            {
                            err = fs.SetModified(filename, entry.iModified); /** 如果存在则检查它是否打开 */
                            if(err!=KErrNone) /** KErrInUse。 或KErrPermissionDenied,如果文件位于资源文件 */
                                {
                                found = ETrue;
                                }
                            }
                        }
                    }
                if(found)
                    {
                    /** 终于找到了!将文件拷贝到指定位置 */
                    err = BaflUtils::CopyFile(fs, filename, KSisBackup);
                    User::LeaveIfError(err);
                    }
                }
            }
...

看上去“任务”完成了,但在结束讨论之前还必须考虑以下两个问题:

(1) 在卸载时要删除备份文件。这一点可以通过在.pkg文件中添加一行带“FN”标记的指令实现。

...
""  -  "c:/sisbackup/backup.sis", FN
...

(2) 如果安装被中途撤销则不应该有备份文件。本文的示例程序没能正确地处理这一点,希望有人解决这个问题并更新wiki。
示例

完整的示例程序: HelloWorld(SisBackup).zip

该示例程序在S60 5th Edition SDK上构建通过,在一台S60 5th Edition手机上测试通过。

如何使用:

1. 为目标设备构建/SisBackup程序

2. 为目标设备构建/HelloWorld应用程序,并制做sis文件

3. 用SymbianSigned签名签署该sis文件

4. 将签名后的sis文件拷贝到手机上(或通过蓝牙发送到手机上)

5. 安装签名后的sis文件,然后启动HelloWorld应用程序,然后选择“选项”->“Share”,如果能看到显示“c:/sisbackup/backup.sis”的提示就说明sis文件已经成功地被备份到系统盘上了。

symbian 如何在安装时备份sis文件相关推荐

  1. android 应用更新安装时出现《 文件包与具有同一名称的现有文件包冲突》小记录

    前言:实现应用自动下载更新时,在安装时出现"文件包与具有同一名称的现有文件包冲突"的错误. 因为适配7.0以上获取内置路径的适配,添加了配置一些配置: <provideran ...

  2. oracle 安装时的日志文件,oracle10g安装的日志文件 Oracle10g怎么查看操作日志

    如何查看oracle 10g 的操作日志 归档模式下怎么查询oracle 10g归档日志存放的路径? SQL> select name from v$archived_log; NAME /u0 ...

  3. java安装时无法写入文件_Java - 无法写入第二个文件

    我一直在尝试从服务器向客户端发送文件时遇到了一些麻烦.我似乎无法将相同的文件从服务器发送到客户端到两个SEPERATE文件.相反,它只是附加到第一个文件的末尾!任何帮助,将不胜感激.Java - 无法 ...

  4. oracle安装时创建应答文件,12c 应答方式安装 (二) 创建cdb+pdb+netca

    上一篇已经用应答文件安装了数据库软件,这一篇博客接着安装12c新推出的CDB和PDB. 一,配置netca 1. 复制并修改netca配置文件 [oracle@snow response]$ cp - ...

  5. android app安装时检测本地文件,天天模拟器怎么安装本地APK文件 天天模拟器安装本地APK图文教程...

    天天模拟器是目前比较好用的一款安卓模拟器软件,国内首款支持游戏游戏手柄.天天模拟器兼容性好,支持市面上99%以上的安卓游戏和软件,优越的性能,是Windows平台首选的安卓模拟器软件. 本文将为大家列 ...

  6. linux 下载文件放哪里,请问是用Yum install命令安装时下载的文件包放在哪里了?...

    ly_chaojilong 于 2010-12-07 14:25:52发表: 自己解决一下: 通过网上看到的办法实验了一下,可以解决这个问题. 网上资料: 怎样使用yum只下载一个包而不安装呢? 解决 ...

  7. mysql 64位 安装1045_MySql 安装时的1045错误

    MySql 安装到最后一步遇到1045错误Access denied for user 'root'@'localhost' (using password:YES) 解决方案一:卸载MySQL,重新 ...

  8. mysql安装时1045错误_MySql 安装时的1045错误

    解决方案一:卸载MySQL,重新安装 1, 卸载MySQL 2, 删除目录 C:\Documents and Settings\All Users\Application Data\MySQL,还要删 ...

  9. 数据库备份 Mysql table '' doesn`t exist .(mysql数据库复制迁移时除了复制文件夹外还要复制data目录下的ibdata1文件)

    今天在整理一个网站的时候,操作系统由于系统自动更新导致一直出现系统蓝屏死机,唉,悲剧了,于是重新安装了系统 windows server 2008 enterprise 32bit. 详情: 系统安装 ...

  10. SQL安装时出现“以前的某个程序安装已在安装计算机上创建挂起的文件操作。运作安装程序之前必须重新启动计算机”...

    SQL安装时出现"以前的某个程序安装已在安装计算机上创建挂起的文件操作.运作安装程序之前必须重新启动计算机",但是重启了N次也没用. .net 2003安装问题-安装程序检测到另一 ...

最新文章

  1. javascript 手势缩放 旋转 拖动支持:hammer.js
  2. phpcms v9整合Ueditor
  3. CTFshow php特性 web134
  4. 【赠书】图神经网络基础与前沿最新书籍,赠5本学习
  5. 数据库性能检查指导方案
  6. thinkphp传递参数
  7. ssl1104-USACO 2.1城堡(foodfill)【图论,广搜】
  8. android过滤html标签,Android中处理TextView带超链接HTML标签的点击事件处理方法
  9. 上周热点回顾(5.26-6.1)
  10. html禁止输入字符,javascript – 如何限制在html表中使用的contenteditable中的字符输入...
  11. linux交叉编译jpeg,libjpeg的交叉编译以及jpeg图片的缩放(缩略图)
  12. 再见2006,奋斗2007
  13. 关于GraphEasy的简单捣腾
  14. 【吴恩达深度学习】Residual Networks(PyTorch)
  15. win10 SVN图标不显示 已解决
  16. APP开发项目团队成员要求及职责
  17. win10系统更新后底部状态栏经常无响应
  18. 用python画小猪佩奇代码_用Python画小猪佩奇
  19. 在线语音转文字如何进行在线转换的
  20. Android Studio 配置翻译工具

热门文章

  1. HTML炫彩按钮,PS打造炫彩的开始图标按钮
  2. std::decay 类型萃取
  3. 天猫小黑盒从发布新品到影响供应链
  4. h5网页版字母消除游戏制作,html+jquery
  5. 车载注册蓝牙服务器,车载蓝牙怎么用
  6. 微信开发工具安装写入失败
  7. macOS、Shimo下载使用及路由配置
  8. 什么是视频编码 编解码技术及压缩技术
  9. 员工管理系统————员工添加模块
  10. 宜搭自建费控应用如何与金蝶云星空对接打通