您的位置:首页 > 其它

WinCE下应用程序的单实例运行

2011-01-16 23:17 120 查看
实现应用程序的单实例运行有很多种方式。如果是有窗口的应用程序,可以通过FindWindow()查找窗口来确认是否已有同名窗口存在。如果是无窗口的应用程序,可以用互斥体等内核对象实现。一般来说,在程序的入口处检查是否已有实例在运行。如果没有,则继续执行。如果有,则退出本次运行。基本流程如下图所示。





以互斥体实现的单实例参考代码如下。

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("SINGLE_INSTANCE"));

if(!hMutex)
{
RETAILMSG(1,(TEXT("\r\nFailed to CreateMutex()...")));
return 0;
}

if ( GetLastError() == ERROR_ALREADY_EXISTS)
{
RETAILMSG(1,(TEXT("\r\nApp already run,CloseHandle(%x)..."), hMutex));
CloseHandle(hMutex);
return 0;
}

RETAILMSG(1,(TEXT("\r\nApp is running (%x)..."), hMutex));
Sleep(3000);

RETAILMSG(1,(TEXT("\r\nApp prepare to exit...")));
Sleep(2000);

RETAILMSG(1,(TEXT("\r\nApp exit(%x)..."), hMutex));
return 0;
}
项目中的倒车可视和DVD播放都使用了TCC89的CIF接口,它们不能同时运行。其中,DVD播放是应用程序实现的,而倒车可视在驱动中处理。在播放DVD的过程中,如果进入倒车可视,需首先关闭DVD播放程序,在退出倒车可视时,再启动DVD播放。DVD播放程序的退出时间较长,也就是T3,大概在2S左右。由于DVD播放程序是单实例运行的,所以在T3这个时间内启动第二个实例会失败,第一个实例也将退出。这样就会出现退出倒车可视后,DVD播放无画面的现象。

为了解决这个问题,需要在检查单实例时做一些调整。如果检查到有实例在运行,并不马上退出,而是等一段时间后再检查一次,如果先前的实例退出了,则继续运行本次的程序。如果先前的实例仍然在运行,则退出本次运行。其中等待的时间,可以设置为T3的2倍。修改后的代码如下。

int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hMutex = CreateMutex(NULL, FALSE, TEXT("SINGLE_INSTANCE"));

if(!hMutex)
{
RETAILMSG(1,(TEXT("\r\nFailed to CreateMutex()...")));
return 0;
}

if ( GetLastError() == ERROR_ALREADY_EXISTS)
{
RETAILMSG(1,(TEXT("\r\nApp already run,CloseHandle(%x)111..."), hMutex));
CloseHandle(hMutex);

Sleep(4000);

hMutex = CreateMutex(NULL, FALSE, TEXT("SINGLE_INSTANCE"));
if(!hMutex)
{
RETAILMSG(1,(TEXT("\r\nFailed to CreateMutex()...")));
return 0;
}

if ( GetLastError() == ERROR_ALREADY_EXISTS)
{
RETAILMSG(1,(TEXT("\r\nApp already run,CloseHandle(%x)222..."), hMutex));
CloseHandle(hMutex);
return 0;
}
}

RETAILMSG(1,(TEXT("\r\nApp is running (%x)..."), hMutex));
Sleep(3000);

RETAILMSG(1,(TEXT("\r\nApp prepare to exit...")));
Sleep(2000);

RETAILMSG(1,(TEXT("\r\nApp exit(%x)..."), hMutex));
return 0;
}
修改前,运行的结果如下图所示。可以看到,在T2和T3时间内启动的实例都失败了。





修改后,运行的结果如下图所示。可以看到,在第一个实例结束后,第二个实例开始了运行,而其他的实例都逐一关闭。





对比两次执行的结果,可以看到,采用第二种方法应该能有所改善。但是否会带来新的问题呢?解BUG最怕的就是解了一个,却又引入一堆!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: