yunxizfj

等待...

导航

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(
true0);
            
while (!_rapi.DevicePresent)
            {
                MessageBox.Show(
"请确保PDA已经与PC同步!");
                _rapi.Connect(
true0);
            }
        }
        
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 == 0return;
            
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

posted on 2010-03-08 14:22  yunxizfj  阅读(1324)  评论(2编辑  收藏  举报