在一些cf开发的WM项目中,除了安装应用程序之外,有时还需要安装应用程序所依赖的插件或者CF运行库!
WinForm部署的安装程序自带了检查fw的功能,Wm貌似没有(有的话麻烦指点一下^_^),不过可以通过自己写的程序控制安装Cab包的基本流程。
思路:创建CF1.0的应用程序MSetup(支持PPC 2003),把要安装的Cab包作为资源文件嵌入到MSetup中,这个应用程序MSetup.exe将会作为安装程序来运行。当运行MSetup.exe后,程序 把所嵌入的Cab包资源输出到“Temp\MSetup”目录下,然后执行连续安装操作。
在一些cf开发的WM项目中,除了安装应用程序之外,有时还需要安装应用程序所依赖的插件或者CF运行库!
WinForm部署的安装程序自带了检查fw的功能,Wm貌似没有(有的话麻烦指点一下^_^),不过可以通过自己写的程序控制安装Cab包的基本流程。
思路:创建CF1.0的应用程序MSetup(支持PPC 2003),把要安装的Cab包作为资源文件嵌入到MSetup中,这个应用程序MSetup.exe将会作为安装程序来运行。当运行MSetup.exe后,程序 把所嵌入的Cab包资源输出到“Temp\MSetup”目录下,然后执行连续安装操作。
相关代码如下:
Code
Const#region Const
private const int STILL_ACTIVE = 0x103;
#endregion
P/Invoke#region P/Invoke
[DllImport("coredll.dll", EntryPoint = "CreateProcess", SetLastError = true)]
private static extern bool CreateProcess(string pszImageName, string pszCmdLine, IntPtr psaProcess, IntPtr psaThread, int fInheritHandles, int fdwCreate, IntPtr pvEnvironment, IntPtr pszCurDir, IntPtr psiStartInfo, ProcessInfo pi);
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool GetExitCodeProcess(int hProcess, ref int lpExitCode);
#endregion
public sealed class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public int dwProcessID = 0;
public int dwThreadID = 0;
}
/**//// <summary>
/// 安装指定目录下多Cab包
/// </summary>
/// <param name="SetupDir">Cab包目录路径</param>
public void SetupFiles(string SetupDir)
{
if (System.IO.Directory.Exists(SetupDir) == true)
{
ProcessInfo pi = new ProcessInfo();
DirectoryInfo DirInfo = new DirectoryInfo(SetupDir);
FileInfo[] Files = DirInfo.GetFiles("*.cab");
foreach (FileInfo file in Files)
{
bool rc = CreateProcess("windows\\wceload.exe", "\"" + file.FullName + "\" /nodelete",
IntPtr.Zero, IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, pi);
int lpExitCode = STILL_ACTIVE;
int ErrorCode = 0;
while ((rc == true) && (lpExitCode == STILL_ACTIVE))
{
Application.DoEvents();
rc = GetExitCodeProcess(pi.hProcess.ToInt32(), ref lpExitCode);
if (rc == true)
{
if (lpExitCode == STILL_ACTIVE)
System.Threading.Thread.Sleep(1000);
}
else
{
ErrorCode = Marshal.GetLastWin32Error();
}
}
}
}
}
/**//// <summary>
/// 检查系统安装CF版本
/// </summary>
/// <param name="version">版本</param>
/// <returns></returns>
private bool HaveNETCF2(char version)
{
RegistryKey NETCFKey=null;
try
{
bool Result = true;
NETCFKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\.NETCompactFramework", false);
if (NETCFKey == null)
return Result;
string[] valueNames = NETCFKey.GetValueNames();
if (valueNames == null)
{
NETCFKey.Close();
return Result;
}
for (int i = 0; i < valueNames.Length; i++)
{
//枚举注册表Software\\Microsoft\\.NETCompactFramework\CF版本值
if ((valueNames[i] != null) && (valueNames[i].Length > 0) && (valueNames[i][0] == version))
{
Result = true;
break;
}
else
{
Result = false;
}
}
return Result;
}
catch
{
return false;
}
finally
{
if(NETCFKey!=null)
NETCFKey.Close();
}
}
Const#region Const
private const int STILL_ACTIVE = 0x103;
#endregion
P/Invoke#region P/Invoke
[DllImport("coredll.dll", EntryPoint = "CreateProcess", SetLastError = true)]
private static extern bool CreateProcess(string pszImageName, string pszCmdLine, IntPtr psaProcess, IntPtr psaThread, int fInheritHandles, int fdwCreate, IntPtr pvEnvironment, IntPtr pszCurDir, IntPtr psiStartInfo, ProcessInfo pi);
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool GetExitCodeProcess(int hProcess, ref int lpExitCode);
#endregion
public sealed class ProcessInfo
{
public IntPtr hProcess = IntPtr.Zero;
public IntPtr hThread = IntPtr.Zero;
public int dwProcessID = 0;
public int dwThreadID = 0;
}
/**//// <summary>
/// 安装指定目录下多Cab包
/// </summary>
/// <param name="SetupDir">Cab包目录路径</param>
public void SetupFiles(string SetupDir)
{
if (System.IO.Directory.Exists(SetupDir) == true)
{
ProcessInfo pi = new ProcessInfo();
DirectoryInfo DirInfo = new DirectoryInfo(SetupDir);
FileInfo[] Files = DirInfo.GetFiles("*.cab");
foreach (FileInfo file in Files)
{
bool rc = CreateProcess("windows\\wceload.exe", "\"" + file.FullName + "\" /nodelete",
IntPtr.Zero, IntPtr.Zero, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, pi);
int lpExitCode = STILL_ACTIVE;
int ErrorCode = 0;
while ((rc == true) && (lpExitCode == STILL_ACTIVE))
{
Application.DoEvents();
rc = GetExitCodeProcess(pi.hProcess.ToInt32(), ref lpExitCode);
if (rc == true)
{
if (lpExitCode == STILL_ACTIVE)
System.Threading.Thread.Sleep(1000);
}
else
{
ErrorCode = Marshal.GetLastWin32Error();
}
}
}
}
}
/**//// <summary>
/// 检查系统安装CF版本
/// </summary>
/// <param name="version">版本</param>
/// <returns></returns>
private bool HaveNETCF2(char version)
{
RegistryKey NETCFKey=null;
try
{
bool Result = true;
NETCFKey = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\.NETCompactFramework", false);
if (NETCFKey == null)
return Result;
string[] valueNames = NETCFKey.GetValueNames();
if (valueNames == null)
{
NETCFKey.Close();
return Result;
}
for (int i = 0; i < valueNames.Length; i++)
{
//枚举注册表Software\\Microsoft\\.NETCompactFramework\CF版本值
if ((valueNames[i] != null) && (valueNames[i].Length > 0) && (valueNames[i][0] == version))
{
Result = true;
break;
}
else
{
Result = false;
}
}
return Result;
}
catch
{
return false;
}
finally
{
if(NETCFKey!=null)
NETCFKey.Close();
}
}
关于WceLoad.exe的参数说明可查看http://msdn.microsoft.com/en-us/library/bb158700.aspx