NET WinCE的程序运行中调用别的程序
关键字: Win CE, Pocket PC, .NET compact Framework, Process, 进程通讯
在.NET的PC程序里面,运行的一个程序调用另一个程序很少实现,只要调用System.Diagnostics namespace 下的Process类,新建一个Process对象,配置好其属性后,直接Start(),就行了。但是在移动设备开发中,由于设备的限制和.NET compact Framework的原因,调用一个现成Process类无法实现。
在遇到这个问题的时候,我在看的时候,发现好多人都遇到这个问题。但都没有统一的解决办法。下面这个类使用了P/Invoke, Runtime.InteropServices 解决了这个问题。贴出来和大家共享。
public class ShellExecute
{
public static void Start(string fileName, string parameters)
{
int nSize;
SHELLEXECUTEEX see;
IntPtr pFile;
IntPtr pParams;
{
public static void Start(string fileName, string parameters)
{
int nSize;
SHELLEXECUTEEX see;
IntPtr pFile;
IntPtr pParams;
see = new SHELLEXECUTEEX();
nSize = fileName.Length * 2 + 2;
pFile = localAlloc(MemoryAllocFlags.LPtr, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(fileName), 0, pFile, nSize - 2);
pFile = localAlloc(MemoryAllocFlags.LPtr, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(fileName), 0, pFile, nSize - 2);
nSize = parameters.Length * 2 + 2;
pParams = localAlloc(MemoryAllocFlags.LPtr, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(parameters), 0, pParams, nSize - 2);
pParams = localAlloc(MemoryAllocFlags.LPtr, nSize);
Marshal.Copy(Encoding.Unicode.GetBytes(parameters), 0, pParams, nSize - 2);
see.lpFile = pFile;
see.lpParameters = pParams;
see.lpParameters = pParams;
ShellExecuteEx(see);
LocalFree(pFile);
LocalFree(pParams);
//return see.hProcess;
}
LocalFree(pParams);
//return see.hProcess;
}
public static void Start(string fileName)
{
Start(fileName, "");
}
{
Start(fileName, "");
}
private static IntPtr localAlloc(MemoryAllocFlags uFlags, int uBytes)
{
const int GMEM_FIXED = 0x0000;
const int LMEM_ZEROINIT = 0x0040;
const int LPTR = (GMEM_FIXED | LMEM_ZEROINIT);
{
const int GMEM_FIXED = 0x0000;
const int LMEM_ZEROINIT = 0x0040;
const int LPTR = (GMEM_FIXED | LMEM_ZEROINIT);
IntPtr ptr = LocalAlloc(LPTR, (uint)uBytes);
if (ptr == IntPtr.Zero)
throw new Exception("Out of memory!");
return ptr;
}
if (ptr == IntPtr.Zero)
throw new Exception("Out of memory!");
return ptr;
}
private enum MemoryAllocFlags : int
{
Fixed = 0x00,
ZeroInit = 0x40,
LPtr = ZeroInit | Fixed
}
{
Fixed = 0x00,
ZeroInit = 0x40,
LPtr = ZeroInit | Fixed
}
#region APIs
[DllImport("coredll.dll")]
private static extern IntPtr LocalAlloc(uint uFlags, uint Bytes);
[DllImport("coredll.dll")]
private static extern IntPtr LocalAlloc(uint uFlags, uint Bytes);
[DllImport("coredll")]
private static extern IntPtr LocalFree(IntPtr hMem);
private static extern IntPtr LocalFree(IntPtr hMem);
[DllImport("coredll")]
private extern static int ShellExecuteEx( SHELLEXECUTEEX ex );
private extern static int ShellExecuteEx( SHELLEXECUTEEX ex );
private class SHELLEXECUTEEX
{
public UInt32 cbSize= 60;
public UInt32 fMask= 0;
public IntPtr hwnd= IntPtr.Zero;
public IntPtr lpVerb= IntPtr.Zero;
public IntPtr lpFile= IntPtr.Zero;
public IntPtr lpParameters= IntPtr.Zero;
public IntPtr lpDirectory= IntPtr.Zero;
public int nShow= 0;
public IntPtr hInstApp= IntPtr.Zero;
public IntPtr lpIDList= IntPtr.Zero;
public IntPtr lpClass= IntPtr.Zero;
public IntPtr hkeyClass= IntPtr.Zero;
public UInt32 dwHotKey= 0;
public IntPtr hIcon= IntPtr.Zero;
public IntPtr hProcess= IntPtr.Zero;
}
#endregion
}
{
public UInt32 cbSize= 60;
public UInt32 fMask= 0;
public IntPtr hwnd= IntPtr.Zero;
public IntPtr lpVerb= IntPtr.Zero;
public IntPtr lpFile= IntPtr.Zero;
public IntPtr lpParameters= IntPtr.Zero;
public IntPtr lpDirectory= IntPtr.Zero;
public int nShow= 0;
public IntPtr hInstApp= IntPtr.Zero;
public IntPtr lpIDList= IntPtr.Zero;
public IntPtr lpClass= IntPtr.Zero;
public IntPtr hkeyClass= IntPtr.Zero;
public UInt32 dwHotKey= 0;
public IntPtr hIcon= IntPtr.Zero;
public IntPtr hProcess= IntPtr.Zero;
}
#endregion
}