.net cf 2.0 和 .net cf 3.5 实际上是有一些差异的,MS不厚道。
1:窗体属性:
Form窗体在2.0的基础上设置Form的Font属性是没有问题的。但是2.0的修改Font的Form在3.5上面会在调用this.Close()时发生一个错误:
Exception 'Prefetch Abort' (3): Thread-Id=0672004a(pth=85aabbcc), Proc-Id=0671004a(pprc=85adaca4) 'Calculator.exe', VM-active=0671004a(pprc=85adaca4) 'Calculator.exe'
PC=423e9b98(???+0x423e9b98) RA=4238ce48(mscoree3_5.dll+0x000ace48) SP=000cfd70, BVA=423e9b98
看到这里,不单是程序崩溃了,人都要崩溃了。
解决方法:
.net 2.0的程序不要去设置Form. Font属性,否则在3.5的上面会在关闭的时候报错。用默认的就OK了。不要折腾自己。
2:单个程序实例的运行。
大家基本上都会想到使用Mutex,但是需要注意使用调用Win32 api :GetLastError()会发现得到的不是
public const int ERROR_ALREADY_EXISTS = 183;
使用:
[DllImport("coredll.dll", EntryPoint = "CreateMutex")]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitiaOwner, string lpName);
// CreateMutex(IntPtr.Zero, true, "<Application Name>"); // to be replaced by the name of your application
[DllImport("coredll.dll", EntryPoint = "GetLastError")]
public static extern int GetLastError();
IntPtr hMutex = CreateMutex(IntPtr.Zero, false, @"MutexSampleabc");
int value = GetLastError();
Console.WriteLine("GetLastError Value =" + value.ToString());
if (value != ERROR_ALREADY_EXISTS)
{
Application.Run(new Form1());
CloseHandle(hMutex);
}
else
{
MessageBox.Show("ERROR_ALREADY_EXISTS");
}
上面的代码是不行的。
注意两点:
1:不要使用Win32 api GetLastError()这个函数,使用:
int value = Marshal.GetLastWin32Error();
2:CreateMutex的DllImport的时候请如下声明:
[DllImport("coredll.dll", EntryPoint = "CreateMutex",SetLastError=true)]
public static extern IntPtr CreateMutex(IntPtr lpMutexAttributes, bool bInitiaOwner, string lpName);
这样就可以保证唯一运行了。解释如下:
尽量不要尝试调用Windows GetLastError() API,因为CLR调用本地代码时可能会改变last
error的代码。取而代之的是,使用调用的返回值标记错误代码,再调用
System.Runtime.InteropServices.Marshal.GetLastWin32Error()方法来获得错误代码。
今天就到这里了。