技术开发 频道

基于Windows CE的Mutex简单探讨和应用

  接下来,我们看看开发一个Windows CE的应用程序如何做;作为.NET Framework 的一个子集,.NET Compact Framework只提供了.NET Framework的一部分功能 ,所以特别的Mutex的对象的功能已经完全被弱化.; NET Compact Framework 并不支持这个所谓的互斥体,但幸运的是 Windows CE通过这个coredll.dll动态链接库中的几个函数可以实现这一功能; 有人就问啦,为什么是coredll.dll,而不是其他动态链接库呢?好问题,是因为Windows CE下大部分的API存在于coredll.dll里面,同时DllImport不仅仅支持Win32 API,他可以支持任何native 的DLL的引入。于是有人又要问啦,啥叫”native的DLL的引入?”..呵呵…自己查资料,网上一大堆..

  在操作系统创建这个Mutex是必须带有一个特别的命名,这个在文章开头已经讲的比较清楚,就是唯一的暂住证(哈哈..真的有点象..大家好好体会这个”暂住证”..);有了这个暂住证呢,这个Mutex的实际功能才能真正体现;如果你想再冒名创建同样的名字,对不起,系统就警告你;

  基本上来讲,如果你创建一个带特别命名的Mutex应用程序,就能确保这个应用程序能唯一地运行在操作系统中;

  作为.NET Framework 的一个子集,.NET Compact Framework只提供了.NET Framework的一部分功能,因此有时在实现一些功能时不得不借助于Windows CE API。另外还存在一些第三方的组件或资源,或以动态链接库形式提供,或者已经是COM组件。相对于.NET Compact Framework,它们都属于非托管资源。我们需要一种功能,实现由托管环境访问这些非托管资源。和.NET Framework 一样,平台调用P/Invoke(Platform Invocation Services)提供托管代码调用驻留于 DLL 中的非托管函数的功能。下面是一张平台调用的原理图(From MSDN)。

  .NET Compact Framework下,如何做平台调用呢?

  下面使用DllImport特征导入Windows CE的API函数MessageBoxW的定义。现举例说明:

Public class APIHelper
<DllImport("coredll.dll", SetLastError := true)> _
public static extern                      Private Shared function MessageBoxW(ByVal hWnd as IntPtr, ByVal text as String, ByVal caption as String caption, byVal type as uint) as Integer
End Function
End Class
然后可以对它进行调用;
Private sub button1_Click(ByVal sender as object, ByVal e as EventArgs )
  
Dim Zero as intPtr
APIHelper.MessageBoxW(Zero,
"测试MessageBoxW函数",
"API调用", 0)
End sub

   然后可以对它进行调用;

Private sub button1_Click(ByVal sender as object, ByVal e as EventArgs )
  
Dim Zero as intPtr
APIHelper.MessageBoxW(Zero,
"测试MessageBoxW函数",
"API调用", 0)
End sub

   可以看到,使用P/Invoke包括声明和调用两个过程,另外还有一个错误处理的过程。通过声明来指定要调用的非托管函数,.NET Compact Framework也是使用DllImport特性来进行声明,包括模块名、函数名及调用约定。与.NET Framework完整版的DllImport特性不同,.NET Compact Framework的一共包括五个公共字段:CallingConvention,CharSet,EntryPoint,PreserveSig和SetLastError。具体各字段的说明可以参考MSDN。

  有了上述的内容打底,我们就要用平台调用这样的概念来实现,Windows CE下,这个应用程序单独运行这样的用户需求;下面我创建了一个类,就叫SingleInstance Application;

Imports System
Imports System.Windows.Forms
‘记得要引用InteropServices这个类
Imports System.Runtime.InteropServices
Imports System.Reflection

Public Class SingleInstanceApplication
    
<DllImport("coredll.dll", SetLastError:=True)> _
    
Private Shared Function CreateMutex(ByVal Attr As IntPtr, ByVal Own As Boolean, ByVal Name As String) As Integer
    
End Function

    
<DllImport("coredll.dll", SetLastError:=True)> _
    
Private Shared Function ReleaseMutex(ByVal hMutex As IntPtr) As Boolean
    
End Function

    
Const ERROR_ALREADY_EXISTS As Long = 183

    
Public Sub Run(ByVal frm As Form)
        
Dim name As String = Assembly.GetExecutingAssembly().GetName().Name
        
Dim mutexHandle As IntPtr = CreateMutex(IntPtr.Zero, True, name)
        
Dim xError As Long = Marshal.GetLastWin32Error()

        
If xError <> ERROR_ALREADY_EXISTS Then
            Application.Run(frm)
        
Else
            
MsgBox("This Application already running now!")
            frm.Close()
        
End If
        ReleaseMutex(mutexHandle)
    
End Sub
End Class

   这个类导入了两个native 的函数,一个是创建Mutex,那另一个就是释放Mutex;还有一个简单的公用函数;

0
相关文章