Window Mobile/CE的PC端安装测试

PDA通过数据线同步电脑后,将netcf和SQLCE的CAB文件手动的复制到PDA里,还得手动的建立目录,创建快捷方式(麻烦)。现在不止实施人员这么做,连客户也要这么做(PDA备电没电了,就还原了),想了想有没有简便方式,好像在见过,在网上搜索一番,然后开始动手,不过都得感谢下面“2位”:

1.OpenNETCF.Desktop.Communication

2.Microsoft ActiveSync 4.5

 

大致原理:利用Rapi对PDA里的文件,目录创建,复制的操作,其次就是用 Microsoft ActiveSync 安装目录里CEAPPMGR.EXE在PC给PDA安装CAB。

 

首先,在网上下载的OpenNETCF.Desktop.Communication的源码,换个8.0的解决方案,然后编译成DLL。

然后,创建一个Windows程序项目,引入刚编译的DLL,然后在CS文件添加:

 

using  OpenNETCF.Desktop.Communication;
using  System.Collections;
using  System.IO;
using  System.Threading;

 

 

     接下来就是实例化RAPI类(主角),然后就是声明点全局变量来使用:

 

#region  变量
        
// 源文件目录 也是程序启动目录
         private   string  _loadPath;
        
// 目标目录 也是安装目录
         private   string  _newPath  =   @" \Storage Card\PDA\ " ;
        
// 目标数据目录
         private   string  _newDataPath  =   @" \Storage Card\PDA\Data\ " ;
        
// 目标图片目录
         private   string  _newPhotoPath  =   @" \Storage Card\PDA\Photo\ " ;
        
// PDA桌面文件夹路径
         private   string  _newlnkPath  =   @" \Windows\Desktop\ " ;
        
// CEAPPMGR.EXE路径用于PC安装CAB
         private   string  _CabSetuper  =   " C:\\Program Files\\Microsoft ActiveSync\\CEAPPMGR.EXE " ;
        
// 组件目录名
         private   string  _CabPathName  =   " Cab " ;
        
// 主程序目录名
         private   string  _exePathName  =   " Data " ;
        
// rapi
         private  OpenNETCF.Desktop.Communication.RAPI _rapi;
        
// 日志
         private  List < string >  _logData;
        
#endregion

        
#region  窗体加载
        
private   void  frmMain_Load( object  sender, EventArgs e)
        {
            PlaySound();
            FormShow();
            _loadPath 
=  Application.StartupPath;
            _rapi 
=   new  OpenNETCF.Desktop.Communication.RAPI();
            _logData 
=   new  List < string > ();
        }
        
#endregion

 

 

    其次,就是弄几个关于rapi的复制文件,删除一些常用操作的方法:

 

#region  Rapi操作封装
        
private   bool  CopyFileToPDA( string  oldFile,  string  newFile)
        {
            
try
            {
                _rapi.CopyFileToDevice(oldFile, newFile, 
true );
                LogAdd(
" 复制文件 " , newFile);
                
return   true ;
            }
            
catch  (Exception ex)
            {
                LogAdd(
" 错误 " , ex.Message);
                
return   false ;
            }
        }
        
private   void  ConnectPDA()
        {
            _rapi.Connect(
true 0 );
            
while  ( ! _rapi.DevicePresent)
            {
                MessageBox.Show(
" 请确保PDA已经与PC同步! " );
                _rapi.Connect(
true 0 );
            }
        }
        
private   void  CabSetup( string  canfile)
        {
            
try
            {
                System.Diagnostics.ProcessStartInfo info 
=   new  System.Diagnostics.ProcessStartInfo();
                System.Diagnostics.Process p 
=   new  System.Diagnostics.Process();
                info.FileName 
=  _CabSetuper;
                info.Arguments 
=  canfile;
                info.CreateNoWindow 
=   false ;
                p.StartInfo 
=  info;
                p.Start();
                p.WaitForExit();
                LogAdd(
" 安装CAB " , canfile);
                Thread.Sleep(
2000 );
            }
            
catch  (Exception ex)
            {
                LogAdd(
" 错误 " , ex.Message);
            }
        }
        
private   bool  CreateDirectory( string  path)
        {
            
try
            {
                _rapi.CreateDeviceDirectory(path);
                LogAdd(
" 创建目录 " , path);
                
return   true ;
            }
            
catch  (Exception ex)
            {
                LogAdd(
" 错误 " , ex.Message);
                
return   false ;
            }
        }
        
private   bool  DeleteDirectory( string  path)
        {
            
try
            {
                _rapi.RemoveDeviceDirectory(path, 
true );
                LogAdd(
" 删除目录 " , path);
                
return   true ;
            }
            
catch  (Exception ex)
            {
                LogAdd(
" 错误 " , ex.Message);
                
return   false ;
            }
        }
        
private   bool  DeleteFile( string  file)
        {
            
try
            {
                _rapi.DeleteDeviceFile(file);
                LogAdd(
" 删除文件 " , file);
                
return   true ;
            }
            
catch  (Exception ex)
            {
                LogAdd(
" 错误 " , ex.Message);
                
return   false ;
            }
        }
        
#endregion

 

 

    上面代码中的LogAdd方法是自定义安装日志,用于安装失败时,叫客户发来研究的,呵呵:

 

#region  日志操作封装
        
private   void  SaveLog()
        {
            
if  (_logData.Count  ==   0 return ;
            
string  tmp  =   string .Empty;
            
foreach  ( string  s  in  _logData)
            {
                tmp 
+=  s  +   " \r\n " ;
            }
            FileStream fs 
=   new  FileStream( string .Format( " {0}\\LOG{1}.txt " , Application.StartupPath, DateTime.Now.ToString( " yyyyMMddHHmm " ))
                , FileMode.Create, FileAccess.ReadWrite);
            
byte [] t  =  Encoding.Default.GetBytes(tmp);
            fs.Write(t, 
0 , t.Length);
            fs.Close();
        }
        
private   void  LogAdd( string  type,  string  fiex)
        {
            _logData.Add(
string .Format( " {0}{1}--{2} " , type, fiex, DateTime.Now.ToString( " yyyy-MM-dd HH:mm " )));
        }
        
#endregion

 

     最后就是界面了,想美化一下界面的,结果发现自己没有艺术细胞,哎,经常按照游戏的时候,看到别人的安装程序硬是安逸,不考虑性能,硬是加入播放音乐,还把窗体弄成渐变显示的效果,还拖了一个皮肤控件。。。

 

#region  窗体打开关闭效果
        
private   void  FormShow()
        {
            AnimateWindows.AnimateWindow(
this .Handle,  1000 , AnimateWindows.AW_SLIDE  +  AnimateWindows.AW_BLEND);

        }
        
private   void  FromClose()
        {
            AnimateWindows.AnimateWindow(
this .Handle,  1000 , AnimateWindows.AW_SLIDE  +  AnimateWindows.AW_BLEND  +  AnimateWindows.AW_HIDE);
        }
        
#endregion

 

 

#region  播放声音
        
private   void  PlaySound()
        {
            
// System.IO.MemoryStream ms = new MemoryStream(AutoRun.Properties.Resources.Soviet);
             byte [] tmp  =  AutoRun.Properties.Resources.Soviet;
            System.IO.FileStream fs 
=   new  FileStream( @" C:\Program Files\sound.wma " , FileMode.Create, FileAccess.ReadWrite);
            fs.Write(tmp, 
0 , tmp.Length);
            fs.Close();
            axWindowsMediaPlayer1.URL 
=   @" C:\Program Files\sound.wma " ;
            axWindowsMediaPlayer1.Ctlcontrols.play();
        }
        
#endregion

 

 

     接下来看看调用的代码,比如:安装。安装,应该是先创建目录,复制程序文件,安装组件,弄个快捷方式等:

 

#region  安装
        
private   void  btnOK_Click( object  sender, EventArgs e)
        {
            
if  (MesBox.Show( " 是否开始安装?\r\n在安装过程中PC或PDA出现对话框,默认请点击“确定”\r\n请确保PDA已经与PC同步! " ==  DialogResult.No)  return ;
            lstLog.Items.Add(
" 开始安装... " );
            ConnectPDA();
            
// 创建安装目录
            lstLog.Items.Add( " 创建目录 "   +  _newPath);
            CreateDirectory(_newPath);
            
// 创建目标数据图片目录
            lstLog.Items.Add( " 创建目录 "   +  _newDataPath);
            CreateDirectory(_newDataPath);
            lstLog.Items.Add(
" 创建目录 "   +  _newPhotoPath);
            CreateDirectory(_newPhotoPath);
            
// 复制程序文件到目录
            lstLog.Items.Add( " 开始复制文件... " );
            
if  ( ! UpdateData())
            {
                MesBox.Show(
" 安装失败!请查看日志文件! " 0 );
                
return ;
            }
            
// 安装CAB
            lstLog.Items.Add( " 开始安装Cab... " );
            List
< string >  tmp  =  FindCabFile();
            
foreach  ( string  s  in  tmp)
            {
                CabSetup(s);
            }
            
// 复制桌面图标
            lstLog.Items.Add( " 开始安装图标... " );
            Setlnk();
            
// 完成安装
            lstLog.Items.Add( " 安装完成... " );
            LogAdd(
" 安装完成 " "" );
            SaveLog();
            MesBox.Show(
" 安装完成! " 0 );
        }
        
private   void  Setlnk()
        {
            
string  path  =  _loadPath;
            DirectoryInfo dinf 
=   new  DirectoryInfo(path  +   " \\ "   +  _exePathName);
            FileSystemInfo[] fs 
=  dinf.GetFileSystemInfos();
            
for  ( int  i  =   0 ; i  <=  fs.Length  -   1 ; i ++ )
            {
                
if  (fs[i].Extension  ==   " .lnk " )
                {
                    
string  tmp  =  fs[i].FullName;
                    CopyFileToPDA(tmp, _newlnkPath 
+  tmp.Substring(tmp.LastIndexOf( " \\ " )));
                }
            }
        }
        
private  List < string >  FindCabFile()
        {
            List
< string >  tmp  =   new  List < string > ();
            
string  path  =  _loadPath;
            DirectoryInfo dinf 
=   new  DirectoryInfo(path  +   " \\ "   +  _CabPathName);
            FileSystemInfo[] fs 
=  dinf.GetFileSystemInfos();
            
for  ( int  i  =   0 ; i  <=  fs.Length  -   1 ; i ++ )
            {
                
if  (fs[i].Extension  ==   " .ini " )
                {
                    tmp.Add(fs[i].FullName);
                }
            }
            
return  tmp;
        }
        
#endregion

 

 

     再弄个升级什么忽悠下客户,呵呵,其实就是把原来的相关文件给覆盖了:

 

#region  升级
        
private   void  btnUpdate_Click( object  sender, EventArgs e)
        {
            
if  (MesBox.Show( " 是否开始升级?\r\n请确保PDA已经与PC同步! " ==  DialogResult.No)  return ;
            ConnectPDA();
            
if  ( ! UpdateData())
            {
                MesBox.Show(
" 升级失败!请查看日志文件! " 0 );
                
return ;
            }
            LogAdd(
" 升级完成 " "" );
            SaveLog();
            MesBox.Show(
" 升级成功! " 0 );
        }
        
private   bool  UpdateData()
        {
            List
< string >  tmp  =  FindFile();
            
foreach  ( string  s  in  tmp)
            {
                
string  newPath  =  _newPath  +  s.Substring(s.LastIndexOf( " \\ " +   1 );
                
bool  b  =  CopyFileToPDA(s, newPath);
                
if  ( ! b)
                {                    
                    SaveLog();
                    
return   false ;
                }
            }            
            
return   true ;
        }
        
///   <summary>
        
///  找Data目录所有文件
        
///   </summary>
        
///   <returns></returns>
         private  List < string >  FindFile()
        {
            List
< string >  tmp  =   new  List < string > ();
            
string  path  =  _loadPath;
            DirectoryInfo dinf 
=   new  DirectoryInfo(path  +   " \\ "   +  _exePathName);
            FileSystemInfo[] fs 
=  dinf.GetFileSystemInfos();
            
for  ( int  i  =   0 ; i  <=  fs.Length  -   1 ; i ++ )
            {
                tmp.Add(fs[i].FullName);
            }
            
return  tmp;
        }
        
#endregion

 

      关于卸载的话,因为一时之间还没想到好的办法来存储目录信息,所以就还没做的。。。(懒啊)

最后就是测试了,通过公司的硬件资源测试了下,预期功能都正常,就是还有一些小的细节可能需要完善了。现在贴出来分享下,希望高手进来指点一下了,呵呵!

参加测试的有:PT982,MC3000,多普达S1,PA600

你可能感兴趣的:(mobile)