Window Mobile/CE的PC端安裝測試
PDA通過數(shù)據(jù)線同步電腦后,將netcf和SQLCE的CAB文件手動的復(fù)制到PDA里,還得手動的建立目錄,創(chuàng)建快捷方式(麻煩)。現(xiàn)在不止實施人員這么做,連客戶也要這么做(PDA備電沒電了,就還原了),想了想有沒有簡便方式,好像在見過,在網(wǎng)上搜索一番,然后開始動手,不過都得感謝下面“2位”:
1.OpenNETCF.Desktop.Communication
2.Microsoft ActiveSync 4.5
大致原理:利用Rapi對PDA里的文件,目錄創(chuàng)建,復(fù)制的操作,其次就是用 Microsoft ActiveSync 安裝目錄里CEAPPMGR.EXE在PC給PDA安裝CAB。
首先,在網(wǎng)上下載的OpenNETCF.Desktop.Communication的源碼,換個8.0的解決方案,然后編譯成DLL。
然后,創(chuàng)建一個Windows程序項目,引入剛編譯的DLL,然后在CS文件添加:
using System.Collections;
using System.IO;
using System.Threading;
接下來就是實例化RAPI類(主角),然后就是聲明點全局變量來使用:
//源文件目錄 也是程序啟動目錄
private string _loadPath;
//目標(biāo)目錄 也是安裝目錄
private string _newPath = @"\Storage Card\PDA\";
//目標(biāo)數(shù)據(jù)目錄
private string _newDataPath = @"\Storage Card\PDA\Data\";
//目標(biāo)圖片目錄
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
其次,就是弄幾個關(guān)于rapi的復(fù)制文件,刪除一些常用操作的方法:
private bool CopyFileToPDA(string oldFile, string newFile)
{
try
{
_rapi.CopyFileToDevice(oldFile, newFile, true);
LogAdd("復(fù)制文件", newFile);
return true;
}
catch (Exception ex)
{
LogAdd("錯誤", ex.Message);
return false;
}
}
private void ConnectPDA()
{
_rapi.Connect(true, 0);
while (!_rapi.DevicePresent)
{
MessageBox.Show("請確保PDA已經(jīng)與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("創(chuàng)建目錄", 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方法是自定義安裝日志,用于安裝失敗時,叫客戶發(fā)來研究的,呵呵:
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
最后就是界面了,想美化一下界面的,結(jié)果發(fā)現(xiàn)自己沒有藝術(shù)細(xì)胞,哎,經(jīng)常按照游戲的時候,看到別人的安裝程序硬是安逸,不考慮性能,硬是加入播放音樂,還把窗體弄成漸變顯示的效果,還拖了一個皮膚控件。。。
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
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
接下來看看調(diào)用的代碼,比如:安裝。安裝,應(yīng)該是先創(chuàng)建目錄,復(fù)制程序文件,安裝組件,弄個快捷方式等:
private void btnOK_Click(object sender, EventArgs e)
{
if (MesBox.Show("是否開始安裝?\r\n在安裝過程中PC或PDA出現(xiàn)對話框,默認(rèn)請點擊“確定”\r\n請確保PDA已經(jīng)與PC同步!") == DialogResult.No) return;
lstLog.Items.Add("開始安裝...");
ConnectPDA();
//創(chuàng)建安裝目錄
lstLog.Items.Add("創(chuàng)建目錄" + _newPath);
CreateDirectory(_newPath);
//創(chuàng)建目標(biāo)數(shù)據(jù)圖片目錄
lstLog.Items.Add("創(chuàng)建目錄" + _newDataPath);
CreateDirectory(_newDataPath);
lstLog.Items.Add("創(chuàng)建目錄" + _newPhotoPath);
CreateDirectory(_newPhotoPath);
//復(fù)制程序文件到目錄
lstLog.Items.Add("開始復(fù)制文件...");
if (!UpdateData())
{
MesBox.Show("安裝失敗!請查看日志文件!", 0);
return;
}
//安裝CAB
lstLog.Items.Add("開始安裝Cab...");
List<string> tmp = FindCabFile();
foreach (string s in tmp)
{
CabSetup(s);
}
//復(fù)制桌面圖標(biāo)
lstLog.Items.Add("開始安裝圖標(biāo)...");
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
再弄個升級什么忽悠下客戶,呵呵,其實就是把原來的相關(guān)文件給覆蓋了:
private void btnUpdate_Click(object sender, EventArgs e)
{
if (MesBox.Show("是否開始升級?\r\n請確保PDA已經(jīng)與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
關(guān)于卸載的話,因為一時之間還沒想到好的辦法來存儲目錄信息,所以就還沒做的。。。(懶?。?/p>
最后就是測試了,通過公司的硬件資源測試了下,預(yù)期功能都正常,就是還有一些小的細(xì)節(jié)可能需要完善了?,F(xiàn)在貼出來分享下,希望高手進(jìn)來指點一下了,呵呵!
參加測試的有:PT982,MC3000,多普達(dá)S1,PA600

浙公網(wǎng)安備 33010602011771號