学习如何获得程序执行的当前目录。在Embedded Visual Basic中,程序执行的当前目录可以通过App.Path属性获得。执行程序的目录可以通过程序集的AssemblyName对象的获得,AssemblyName对象包含了程序集的所有描述:
http://msdn.microsoft.com/library/en-us/dncfhowto/html/HOWTOExecutingAppPath.asp
这篇快速入门教程告诉您如何获得您的程序集和数据文件所在的目录。Windows CE .NET本身不支持应用程序的当前目录的设置:
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/getappdir.aspx
7.2. 如何计算精确的时间间隔?
一个应用程序有四种方法得到时间间隔:
System.Environment.TickCount
获得一个带符号的整型值,表示从机器启动到调用时经过的豪秒数。在.NET精简框架下,这个值的误差在0.5秒内,大多情况下会比0.5秒小。
GetTickCount()
属性Environment.TickCount就是调用GetTickCount函数的,所以没有必要再调用本地代码中的这个方法。
Performance Monitor
可以作为压力测试用途,但不是为最终使用的应用程序而设计的。如需更多信息,请查看本问答的 "7.5. 如何使用性能监视器? " 章节
Timers
使用System.Threading.Timer类,可以在线程内设定计时器,用委托(delegate)指向应用程序 。
Performance Counter
如果OEM厂商支持的话,QueryPerformanceCounter函数能提供最高精度的计时功能。
请查看本问答的"6.9. 如何使用性能计数器功能? "章节。
7.3. 如何把嵌入式资源当作一个流(Stream)?
为了能够访问嵌入资源,应用程序只须简单地引用相关的程序集(assembly)并调用GetManifestResourceStream方法。下面这个例子岩石了如何从嵌入资源中建立一个位图:
//C#
using System.Reflection;
Assembly asm = Assembly.GetExecutingAssembly();
Bitmap bmpSprite = new Bitmap(asm.GetManifestResourceStream("AssemblyName.FileName"));
'VB
Imports System.Reflection
Dim asm As [Assembly] = [Assembly].GetExecutingAssembly()
Dim bmpSprite As New Bitmap(asm.GetManifestResourceStream("AssemblyName.FileName"))
上面代码中, 字符串AssemblyName部分可以在运行时通过调用asm.GetName().Name得到。
注意:如果AssemblyName中有空格,它将被下划线代替,而且必须这样访问。
7.4. 为什么得到一个"An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll"的错误?
这是.net精简框架的BUG。这是由于Windows CE底层的Secure Sockets Layer (SSL)的限制造成的。但是,也偶避免的方法,如果设置 req.AllowWriteStreamBuffering为true,不要设置req.ContentLength属性,那就不会在发生这个错误了。
7.5. 如何使用性能监视器?
性能计数器通过编辑设备注册表建立:
建立注册表键:"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETCompactFramework\PerfMonitor"
新建双字节项,值就是计数器的名字。
把Counters的值设置为1表示允许计数器,设置为0表示禁止使用。 设置了性能计数器后,当程序关闭时,会建立一个文本文件"mscoree.stat"。这个文件会存放在设备的根目录。这是一个文件每行的长度是固定的,所以导入Excel是非常方便的。
注意: 计数器只能被一个运行着的托管的程序使用。
注意: 使用性能计数器时,会导致30%的性能下降。
7.6. 如何取消一个程序的关闭?
程序可以重载OnClosing方法,设置CancelEventArgs.Cancel为true就可以取消关闭。
//C#
protected override void OnClosing(CancelEventArgs e)
{
e.Cancel = true;
}
'VB
Protected Overrides Sub OnClosing(ByVal e As CancelEventArgs)
e.Cancel = True
End Sub 'OnClosing
7.7. 如何在我的程序中调用另一个应用程序?
您可以调用本地代码的CreateProcess函数开始运行第二个程序。然后调用本地代码的WaitForSingleObject函数暂停调用的程序,直到第二个程序运行结束。以下快速入门演示了通过PocketPC模拟器来实现这一操作:
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/waitforsingleobject.aspx
7.8. .net精简框架的应用程序会建立什么线程?
一个.net精简框架程序最多会产生4个线程:
一个主应用程序线程。
一个线程控制各种时间间隔,时间间隔是供系统和其他应用程序使用的。
一个线程跟踪活动的TCP/IP接口的变化(模拟Windows XP上的媒体动作,Windows CE上是没有这些操作的)。
一个执行终止对象的线程。当第一个被垃圾回收的对象回收时,就被建立了。 7.9. 如何把byte数组转换成结构体?
在C++中,通过建造类型(typecasting)可以很方便和有效的保存一个类或结构体到文件,并直接从文件中重构出来。但托管代码的本性决定了它不能这样实现。但还是有办法实现的,建立一个类,把内存中的数据作为它的属性让其他类访问。例如:
//C#
public class MyClass
{
protected byte[] m_data = null;
// uint uiDummy
// short sDummy
// This is a bit unsafe so you should throw an
// exception or assert if the byte array length is
// not 6. A safer but less memory efficient approach
// would be to set m_data = new byte[6] and then copy
//bytes to m_data.
public MyClass(byte[] bytes) {m_data = bytes;}