symbian 2nd如何绕过程序管理器的限制

本文介绍了一种绕过Symbian系统程序管理器限制的方法,通过自制程序管理器实现程序的后台静默安装与更新,使应用脱离系统管理器控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

symbian 2nd如何绕过程序管理器的限制

 

北京理工大学  20981  陈罡

 

symbian开发中我们经常会用到手机系统自带的程序管理这个软件。 这个软件的功能在于它会忠实地把程序的安装操作记录下来,在删除 程序的时候它也会忠实地把程序给删除。这种做法对于symbian来说, 无疑是最好的选用第三方软件的选择,既可以安装到手机上,又可以 无条件的将软件卸载掉。

 

但是这个所谓的程序管理,也有很多弊端。例如,每次都需要把程序 的安装包拷贝到手机存储上去,这样安装包一旦大于2M,对于多数s60 手机来说,这个程序极有可能引起手机内存不足,请关闭一些程序这样 的错误提示,最终导致安装失败。再有就是程序的升级,有的时候不需要 整个将sis包重新安装一遍,只是覆盖掉几个dll文件即可,但是很多情况 下,开发者都是选择将程序全部重新安装一遍,如果打包的时候升级过sis 包的版本,那么将在程序管理中看到多个安装记录。另外目前很多公司 都在寻找手机程序预装的方法,其实从其本质来说就是希望程序安装到 用户的手机上以后,无法被用户使用普通的程序管理程序卸载。

 

在这里我要讨论一种方式,可以绕过程序管理器的限制,在程序管理 里面没有记录,也无法把程序从程序管理器里面卸载,这种方式虽然比较 有效,但是程序的卸载操作就需要使用其它的单独的卸载程序才能卸载了。

绕过程序管理器的方法其实很简单,自己编写一个程序管理器即可。很多 朋友会想编写一个程序管理器多么多么的复杂,需要熟悉sis文件格式之类 的内容。其实一点也不复杂,sis本身就是s60自带的程序管理器支持的文件 格式,只有nokia的程序管理器才能够识别。既然我们自己编写程序管理器 的话,就不必拘泥于sis格式了。自己的程序可以读取的文件格式就可以自己 说得算了。

 

我们知道在创建pkg文件的时候,在需要安装后立即运行的程序后面通常只要 指定一个RI,FI,就可以保证程序在安装后可以立即执行,例如: "marm/myapp.exe"-"!:/System/Apps/MyApp/Myapp.exe",RI,FI

这样就提供了一个方法摆脱当前的程序管理器的方法,大致的思路如下: 编写一个exe文件,该文件可以将某个.zip或者.dat的包解压缩到手机的 e:/system/apps目录下面即可。

 

整体的写下来,大概是这个样子的: "marm/my.zip"-"!:/System/Apps/MyApp/my.zip" "marm/myapp.exe"-"!:/System/Apps/MyApp/myapp.exe",RI,FI myapp.exe运行的时候,可以给它加入适当的1秒至3秒的延时,用来确保 手机的程序管理器已经把zip包释放到某个目录下面去了,然后再开始运行 myapp.exe,它的作用在于直接把my.zip包中的文件解压缩到system/apps目录 或者希望可以开机自动运行的可以把相关的mdl文件考入c:/system/recogs目录。

注意: 利用mdl在手机启动的时候自动载入的特性实现的所谓开机自动运行,在 symbian 3rd平台中已经不再适用,以下是官方的issues说明:

这样一来,只有my.zipmyapp.exe这两个文件是纳入手机的应用程序管理器 的控制范畴的,可以很容易地通过应用程序管理器删除,但是通过myapp.exe my.zip中解压缩出来的,放入system/apps里面的目录则成功的逃脱了程序 管理器的限制,保留了下来。这样就基本上实现了,程序脱离应用程序管理器 的限制了。如果在my.zip中加入自动运行的mdl,然后调用自动登陆、下载zip 自动解压缩的程序的话,就可以实现程序的自动更新了。每次让开机自动运行 的程序,在收到更新短信时启动,联网,下载更新包,然后解压缩安装。这 一切都是以后台的方式运行的,不会对用户产生困扰,也不需要用户每次都通过 nokia pc套件来下载,安装程序的繁琐过程。

 

对用户来说,只是某天突然发现不知道什么时候手机中多了一个应用程序的 图标 :),或者发现某个程序的图标不见了(可以通过网络自动删除手机中的某个 无效的应用)。相当于自己实现了一个OTA了。

 

相关实验我已经完全测试成功,呵呵。但是这种OTA是一把双刃剑 不希望落入某些居心不良的人的手中,扰乱这个技术的发展。所以就暂时不开放 代码了,只是把解压缩my.zipmyapp.exe代码开放一下,希望对有兴趣的朋友 有用:

// -------------------------------------------------------------------------- // zagzip.cpp // // programmer : wayne // (1)get zip file exactly pathname // (2)set path where package need to be extracted // (3)check whether the object directory exists // (4)if directory exists, perform extract operaion // (5)if not exists, create one, then, goto step (4) // (6)call outer command, delete zip file and quit smoothly // --------------------------------------------------------------------------

#include <e32base.h> #include <e32std.h> #include <f32file.h>  // RFs and RFile #include <zipfile.h>  // CZipFile #include <apacmdln.h> // CApaCommandLine #include <EikDll.h>   // EDll::StartApp(...) #include <apgcli.h> #include <apgtask.h> #include <s32file.h>    // RFileReadStream, RFileWriteStream

 

// use 4k buffer size #define BUF_SIZE  1024 * 4

 

// the specified zip config file name #ifndef __WINS__ _LIT(KZipPathnameC,  "c://my.zip") ; _LIT(KZipPathnameE,  "e://my.zip") ; _LIT(KExtractPath,   "c://system//apps//abc//") ; _LIT(KSrcPathname,   "c://system//apps//abc//abc.mdl") ; _LIT(KObjPathname,   "c://system//recogs//abc.mdl") ; _LIT(KOutCmd,   "c://system//apps//abc//abc.app") ; #else _LIT(KZipPathnameC,  "c://my.zip") ; _LIT(KZipPathnameE,  "c://my.zip") ; _LIT(KExtractPath,   "c://system//apps//abc//") ; _LIT(KSrcPathname,   "c://system//apps//abc//abc.mdl") ; _LIT(KObjPathname,   "c://recogs//abc.mdl") ; _LIT(KOutCmd,    "c://system//apps//abc//abc.app") ; #endif

 

TBuf8<BUF_SIZE>  g_buf ; TBuf<100>   g_zip_pathname ; TBuf<100>   g_target_path ; TBuf<100>   g_copy_src_pathname ; TBuf<100>   g_copy_obj_pathname ; TBuf<100>   g_run_command ;

 

// Constants LOCAL_C TBool check_file_exist(const TDesC & path_name) ; LOCAL_C TBool check_dir_exist(const TDesC & dir_name) ; LOCAL_C TBool extract_zipfile(const TDesC & zip_pathname, const TDesC & target_path) ; LOCAL_C TBool extract_single(RFs& fs,         CZipFile * zip_file,         const TDesC& target_path,         const TDesC& file_name) ; LOCAL_C TBool run_command(TDesC& preset_command) ; LOCAL_C TBool copy_file(TDesC& obj_pathname, TDesC& src_pathname) ; LOCAL_C TBool get_const_string(TDes & res_str,const TDesC & const_str) ; LOCAL_C TBool main_proc() ;

 

//检查文件是否存在 LOCAL_C TBool check_file_exist(const TDesC & path_name) {  RFs fs ;  RFile f ;  TInt res ;  User::LeaveIfError(fs.Connect()) ;  res = f.Open(fs, path_name, EFileRead) ;  f.Close() ;  fs.Close() ;  return (res == KErrNone) ? ETrue : EFalse ;  }

 

// 检查目录是否存在 LOCAL_C TBool check_dir_exist(const TDesC & dir_name) {  RFs  fs ;  RDir dir ;  TInt res ;  User::LeaveIfError(fs.Connect()) ;  res = dir.Open(fs, dir_name, KEntryAttNormal) ;  dir.Close() ;  fs.Close() ;  return (res == KErrNone) ? ETrue : EFalse ; }

 

// 解压缩zip包了 LOCAL_C TBool extract_zipfile(const TDesC& zip_pathname, const TDesC& target_path) {  // Connect to the file server.  RFs fs ;  User::LeaveIfError(fs.Connect()) ;

 // Create an instance of CZipFile.  CZipFile* zip_file = CZipFile::NewL(fs, zip_pathname) ;  CleanupStack::PushL(zip_file) ;    // Iterate all the files inside the .zip file and then decompress it  CZipFileMemberIterator* members = zip_file->GetMembersL();  CZipFileMember* member = NULL ;  CleanupStack::PushL(members);

 // 这里是确保解压缩的目的目录存在,如果不存在就创建一个  if(!check_dir_exist(target_path)) {   // target path doesn't exist, create one   fs.MkDir(target_path) ;  }

 // iterator one by one  while ((member = members->NextL()) != 0) {   // extract the compressed file into the specified directory   if(check_file_exist(*member->Name())) {    TParse parse ;    parse.Set(*member->Name(), NULL, NULL) ;    // 如果有被占用的rsc,则跳过,继续运行    // 这一点主要针对程序正在运行中的情况,rsc不可写    if(parse.Ext().Find(_L("rsc")) != KErrNotFound) continue ;   }   extract_single(fs, zip_file, target_path, *member->Name()) ;   delete member;  }  CleanupStack::PopAndDestroy(); // members  CleanupStack::PopAndDestroy(); // zip_file  fs.Close();  return 0 ; }

 

// 解压缩一个文件 LOCAL_C TBool extract_single(RFs& fs,         CZipFile * zip_file,         const TDesC& target_path,         const TDesC& file_name) {   TInt total_size = 0 ;  TUint uncompressed_size = 0 ;    // Get the input stream of aFileName.  CZipFileMember* member = zip_file->CaseInsensitiveMemberL(file_name);  CleanupStack::PushL(member);  RZipFileMemberReaderStream* stream;  zip_file->GetInputStreamL(member, stream);  CleanupStack::PushL(stream);

 // Extracts file_name to a buffer.  TFileName target_pathname ;  RFile file ;  target_pathname.Append(target_path) ;  target_pathname.Append(file_name) ;  User::LeaveIfError(file.Replace(fs, target_pathname, EFileWrite));  CleanupClosePushL(file);    total_size = member->UncompressedSize() ;  while(total_size > 0) {   // if the file is quite huge, then read the file in streaming mode.   // use 4KB buffer and save binary raw data into uncompressed file   // 这里使用了4K的缓冲区去分段解压缩大的zip文件   g_buf.SetLength(0) ;      if(total_size >= BUF_SIZE) uncompressed_size = BUF_SIZE ;   else uncompressed_size = total_size ;   User::LeaveIfError(stream->Read(g_buf, uncompressed_size)) ;   User::LeaveIfError(file.Write(g_buf)) ;   total_size -= uncompressed_size ;  }  // Release all the resources.  file.Flush() ;  CleanupStack::PopAndDestroy(3); // file, stream, member  return 0 ; }

 

// 这是执行外部命令了 LOCAL_C TBool run_command(TDesC& preset_command) {  if(check_file_exist(preset_command)) {   CApaCommandLine * command_line = CApaCommandLine::NewLC();   command_line->SetLibraryNameL(preset_command) ;   command_line->SetCommandL(EApaCommandRun);   User::LeaveIfError(EikDll::StartAppL(*command_line));   CleanupStack::PopAndDestroy(command_line) ;   return ETrue ;  }  return EFalse ; }

 

// 复制文件,貌似应该有更好的方法,这里自己写了一个了 // 应对recogs目录不存在的情况 LOCAL_C TBool copy_file(TDesC& obj_pathname, TDesC& src_pathname) {  RFs     fs ;  RFile    fsrc ;  RFile    fobj ;  TInt    total_bytes ;  TInt    used_bytes ;  TParse    pathname_parse ;  TBuf<50>   copy_dir ;  

 User::LeaveIfError(fs.Connect()) ;

 // check whether the object dir is exist  pathname_parse.Set(obj_pathname, NULL, NULL) ;  copy_dir = pathname_parse.DriveAndPath() ;  if(!check_dir_exist(copy_dir)) {   fs.MkDir(copy_dir) ;    }    fsrc.Open(fs, src_pathname, EFileStream | EFileRead) ;  fobj.Replace(fs, obj_pathname, EFileStream | EFileWrite) ;    fsrc.Size(total_bytes) ;    while(total_bytes > 0) {   if(total_bytes >= BUF_SIZE) used_bytes = BUF_SIZE ;   else used_bytes = total_bytes ;   fsrc.Read(g_buf) ;   fobj.Write(g_buf) ;   total_bytes -= used_bytes ;    }  fs.Close() ;  return ETrue; }

 

LOCAL_C TBool get_const_string(TDes & res_str,const TDesC & const_str) {  res_str.SetLength(0) ;  if(check_file_exist(const_str)) {   res_str.Copy(const_str) ;   return ETrue ;  }  return EFalse ; }

LOCAL_C TBool main_proc() {  TBool    has_running_app = EFalse ;  RFs     fs ;  RFile    f ;  TBuf8<10>   s ;

 // 检查文件  if(check_file_exist(KOuterCmd)) has_running_app = ETrue ;

 User::LeaveIfError(fs.Connect()) ;  f.Replace(fs, KQuitFile, EFileWrite) ;  s.Format(_L8("quit")) ;  f.Write(s) ;  f.Flush() ;  f.Close() ;  fs.Close() ;

 // 确定zip文件存在在C盘还是E,把路径存入g_zip_pathname  if(!get_const_string(g_zip_pathname, KZipPathnameE)) {   get_const_string(g_zip_pathname, KZipPathnameC) ;  }

 // 解压缩后文件的目标存放路径  g_target_path.Copy(KExtractPath) ;     // 解压缩后mdl文件的存放路径  g_copy_src_pathname.Copy(KSrcPathname) ;

 // 解压缩后将mdl文件拷贝到的目标路径  g_copy_obj_pathname.Copy(KObjPathname) ;

 // 这是都执行完毕后需要运行的外部命令,类似FI,RI的功能     g_run_command.Copy(KOuterCmd) ;    // 这就是解压的过程了  extract_zipfile(g_zip_pathname, g_target_path) ;

 // 这里主要是为了把mdl文件拷贝到c://system//recogs这个目录下而加入的  copy_file(g_copy_obj_pathname, g_copy_src_pathname) ;

 // 最后运行常驻内存的那个exeapp  if(!has_running_app) run_command(g_run_command) ;

 // 删除zip文件和mdl文件  User::LeaveIfError(fs.Connect()) ;  fs.Delete(g_zip_pathname) ;  fs.Delete(g_copy_src_pathname) ;  fs.Close() ;  return 0 ; }

 

//  从这里跑到自己定义的那个函数里面去 LOCAL_C void MainL(const TDesC& /*aArgs*/)  {   main_proc() ;  }

 

LOCAL_C void DoStartL()  {  // 没法子,在exe中要使用活动对象,只能自己创建调度器  CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();  CleanupStack::PushL(scheduler);  CActiveScheduler::Install(scheduler);

 // 调用MainL函数,开始解压缩  TBuf<256> cmdLine;  RProcess().CommandLine(cmdLine);  MainL(cmdLine);

 // 删除调度器  CleanupStack::PopAndDestroy(scheduler);  }

// 这个是整个程序的入口点了 GLDEF_C TInt E32Main()  {  // 连异常处理栈都要自己创建  __UHEAP_MARK;  CTrapCleanup* cleanup = CTrapCleanup::New();  // Run application code inside TRAP harness, wait keypress when terminated  TRAPD(mainError, DoStartL());    delete cleanup;  __UHEAP_MARKEND;  return KErrNone;  }

// End of File

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值