首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Windows Mobile >

请问如何样让windows mobile程序只运行一个实例

2012-12-14 
请教怎么样让windows mobile程序只运行一个实例请教怎么样让windows mobile程序只运行一个实例? 我用PC的

请教怎么样让windows mobile程序只运行一个实例
请教怎么样让windows mobile程序只运行一个实例? 我用PC的办法Prop,在MOBILE上根本不行啊.
[最优解释]
可以试一下命名的互斥对象。在调用CreatMutex函数创建一个命名的互斥对象后,如果其返回值是一个有效的句柄,可以接着调用GetLaseError,如果返回值是一个ERROR_ALREADY_EXISTS,就表明已经有该应用程序的一个实例在运行了。
[其他解释]
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.
[其他解释]

引用:
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.


学习了
[其他解释]
引用:
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.

呵呵,谢谢这位仁兄的不吝指正,我所说的只是自己的一个思路,在这里并不存在教别人,也不敢去教别人,只是自己的想法而已。论坛嘛,关键就是交流各自的思路,互相学习,互相指正。呵呵
[其他解释]
貌似我很快就会用到这个东西.mark一下.关注.期待高手解答
[其他解释]
什么意思? win32生成的不是有个判断主窗体的吗  如果之前的主窗体已存在 就运行那个啊

当然这个方法不是很健壮的,可以通过增加注册表项的方法,来防止运行第二个实例时把第一个实例关掉了:


注册我们的应用程序


比较一下微软的快捷方式文件和我们自己的就会发现,有一个明显的不同之处:微软大部分应用程序的快捷方式并不是直接写路径名的,而是一个以 : 开头的化名(半角的冒号),为什么微软要这样绕弯子?用化名很明显还要先解析,比直接用路径名慢。




答案还是和 WM 特殊的内存管理有关,系统最多只能跑 32 个进程,我们来想像一下这样的苛刻条件:系统里已经跑了 32 个进程,其中必定有 Shell32.exe,“开始-程序”这个界面是 shell32.exe 的窗口,假设其中最不常用的进程是 Windows Media,“最不常用”说明有新进程要跑时,被关掉的就会是这个“最不常用”的进程。那么,用户在“开始-程序”里选择运行 Windows Media 时会发生什么?Windows Media 会先被关闭,然后又新建了 Windows Media 的进程。




所以,我们常常写的“兼容程序”靠运行时检测系统里有没有同样类名的窗体来判断前例的方法是不健壮的!因为即使这样检测,程序依然有一段时间是存在两个实例的,有两个进程,就说明可能在新进程跑起来时,由于 32 个进程的限制,而导致前例被关闭,这样就变成一个程序先关掉再运行一次,浪费时间,浪费系统资源。




那为什么用化名就不会这样?还是以 Windows Media 为例,Windows Media 的化名是 :WMPLAYER,打开注册表 [HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:WMPLAYER] 会发现这个键下面有一个名为 0 的字符串值,其数据是 WMP for Mobile Devices,这刚好是 Windows Media 主窗体的类名,还有一个名为 1 的字符串值,数据是其程序名。当某个进程用 ShellExecuteEx 运行 :WMPLAYER 或者指向 :WMPLAYER 的文件时,ShellExecuteEx 会先查找系统里有没有类名为 WMP for Mobile Devices 的窗体,如果找到就激活,不会再新建 Windows Media 的进程,这个过程,是在调用者进程里完成的,没有新建被调用者进程。




建议大家都注册一下自己的模块,以后快捷方式里统一都用化名,例如:AmoiTest.exe 的注册信息为:




[HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:AMOITEST]


"0"="AmoiTestClassName"


"1"="AmoiTest.exe"




另外还有 2 和 3 的 DWORD 值,我还没完全研究清楚(SAN Based App 用的),不过只要有 1 和 2 就可以完成这个机制了。



[其他解释]
引用:
什么意思? win32生成的不是有个判断主窗体的吗? 如果之前的主窗体已存在 就运行那个啊

 当然这个方法不是很健壮的,可以通过增加注册表项的方法,来防止运行第二个实例时把第一个实例关掉了:


 注册我们的应用程序


 比较一下微软的快捷方式文件和我们自己的就会发现,有一个明显的不同之处:微软大部分应用程序的快捷方式并不是直接写路径名的,而是一个以 : 开头的化名(半角的冒号),为什么微软要这样绕弯子?用化名很明显还要先解析,比直接用路径名慢。


 答案还是和 WM 特殊的内存管理有关,系统最多只能跑 32 个进程,我们来想像一下这样的苛刻条件:系统里已经跑了 32 个进程,其中必定有 Shell32.exe,“开始-程序”这个界面是 shell32.exe 的窗口,假设其中最不常用的进程是 Windows Media,“最不常用”说明有新进程要跑时,被关掉的就会是这个“最不常用”的进程。那么,用户在“开始-程序”里选择运行 Windows Media 时会发生什么?Windows Media 会先被关闭,然后又新建了 Windows Media 的进程。




 所以,我们常常写的“兼容程序”靠运行时检测系统里有没有同样类名的窗体来判断前例的方法是不健壮的!因为即使这样检测,程序依然有一段时间是存在两个实例的,有两个进程,就说明可能在新进程跑起来时,由于 32 个进程的限制,而导致前例被关闭,这样就变成一个程序先关掉再运行一次,浪费时间,浪费系统资源。


 那为什么用化名就不会这样?还是以 Windows Media 为例,Windows Media 的化名是 :WMPLAYER,打开注册表 [HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:WMPLAYER] 会发现这个键下面有一个名为 0 的字符串值,其数据是 WMP for Mobile Devices,这刚好是 Windows Media 主窗体的类名,还有一个名为 1 的字符串值,数据是其程序名。当某个进程用 ShellExecuteEx 运行 :WMPLAYER 或者指向 :WMPLAYER 的文件时,ShellExecuteEx 会先查找系统里有没有类名为 WMP for Mobile Devices 的窗体,如果找到就激活,不会再新建 Windows Media 的进程,这个过程,是在调用者进程里完成的,没有新建被调用者进程。


 建议大家都注册一下自己的模块,以后快捷方式里统一都用化名,例如:AmoiTest.exe 的注册信息为:


 [HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:AMOITEST]


 "0"="AmoiTestClassName"


 "1"="AmoiTest.exe"


 另外还有 2 和 3 的 DWORD 值,我还没完全研究清楚(SAN Based App 用的),不过只要有 1 和 2 就可以完成这个机制了。


学习了
[其他解释]
顶蜗牛。
学习了。
[其他解释]
引用:
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.

呵呵,我一直用CreatMutex,原来是错的啊~~~那就错吧,反正可以实现~~~
[其他解释]
学习了。
[其他解释]
引用:
什么意思? win32生成的不是有个判断主窗体的吗? 如果之前的主窗体已存在 就运行那个啊

 当然这个方法不是很健壮的,可以通过增加注册表项的方法,来防止运行第二个实例时把第一个实例关掉了:


 注册我们的应用程序


 比较一下微软的快捷方式文件和我们自己的就会发现,有一个明显的不同之处:微软大部分应用程序的快捷方式并不是直接写路径名的,而是一个以 : 开头的化名(半角的冒号),为什么微软要这样绕弯子?用化名很明显还要先解析,比直接用路径名慢。


 答案还是和 WM 特殊的内存管理有关,系统最多只能跑 32 个进程,我们来想像一下这样的苛刻条件:系统里已经跑了 32 个进程,其中必定有 Shell32.exe,“开始-程序”这个界面是 shell32.exe 的窗口,假设其中最不常用的进程是 Windows Media,“最不常用”说明有新进程要跑时,被关掉的就会是这个“最不常用”的进程。那么,用户在“开始-程序”里选择运行 Windows Media 时会发生什么?Windows Media 会先被关闭,然后又新建了 Windows Media 的进程。


 所以,我们常常写的“兼容程序”靠运行时检测系统里有没有同样类名的窗体来判断前例的方法是不健壮的!因为即使这样检测,程序依然有一段时间是存在两个实例的,有两个进程,就说明可能在新进程跑起来时,由于 32 个进程的限制,而导致前例被关闭,这样就变成一个程序先关掉再运行一次,浪费时间,浪费系统资源。


 那为什么用化名就不会这样?还是以 Windows Media 为例,Windows Media 的化名是 :WMPLAYER,打开注册表 [HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:WMPLAYER] 会发现这个键下面有一个名为 0 的字符串值,其数据是 WMP for Mobile Devices,这刚好是 Windows Media 主窗体的类名,还有一个名为 1 的字符串值,数据是其程序名。当某个进程用 ShellExecuteEx 运行 :WMPLAYER 或者指向 :WMPLAYER 的文件时,ShellExecuteEx 会先查找系统里有没有类名为 WMP for Mobile Devices 的窗体,如果找到就激活,不会再新建 Windows Media 的进程,这个过程,是在调用者进程里完成的,没有新建被调用者进程。


 建议大家都注册一下自己的模块,以后快捷方式里统一都用化名,例如:AmoiTest.exe 的注册信息为:


 [HKEY_LOCAL_MACHINE\Software\Microsoft\Shell\Rai\:AMOITEST]


 "0"="AmoiTestClassName"


 "1"="AmoiTest.exe"


 另外还有 2 和 3 的 DWORD 值,我还没完全研究清楚(SAN Based App 用的),不过只要有 1 和 2 就可以完成这个机制了。

谢谢楼上的朋友,我用的就是判断窗体的办法,不过第2次打开的时候,就停留在只显示标题的界面。貌似这段代码没起作用。 在PC上我试过可以的。
[其他解释]
mark

------其他解决方案--------------------


如果程序有主窗口,就findwindow 先寻找窗口,如果有就return就可以了.
[其他解释]
CreatMutex我记得可以啊~~
[其他解释]
CreatMutex,我用过
[其他解释]
可以利用”任何时刻只能有一个进程操作文件“这一特性实现互斥。(第一个实例开始打开一个文件,第二个实例就无法打开了)
在程序启动完成后,关闭文件就可以了。这个时候如果再单击应用程序,wm会自动把打开的进程显示给用户。

其实wm有只创建一个实例的功能,条件是必须等一个实例完全创建完。那么问题就出现在创建实例的过程中,这段期间你再启动应用,就会创建多个实例。

所有问题的关键就在于在应用创建实例的过程中防止创建多个实例。
[其他解释]
WM里用互斥量是可以的,楼主不会用
[其他解释]
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
[其他解释]
学习了.
[其他解释]
正在学习当中

[其他解释]
学习了
[其他解释]
该回复于2009-12-18 10:13:10被版主删除
[其他解释]

[其他解释]
WINCE可以用CreatMutex
Windows mobile 不行


另外问一下蜗牛,那我每次进入程序就把注册表下的Shell相应的删掉,是不是就能够运行多个实例了?
[其他解释]
verygood
[其他解释]
有必要这么复杂吗,自己写个配置文件什么的,然后在程序初始化时根据配置文件判断就可以了。
[其他解释]
up
[其他解释]
学习了,看来这里还是比较热闹的
[其他解释]

引用:
请教怎么样让windows mobile程序只运行一个实例? 我用PC的办法Prop,在MOBILE上根本不行啊.

prop也可以的。
[其他解释]
引用:
WM里用互斥量是可以的,楼主不会用

同意
[其他解释]
顶了,更多的wince技术资料可以到海同wince技术网站参考。
[其他解释]
什么啊
[其他解释]
这是什么啊
[其他解释]
Mobile 可以运行两个实例?

static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [MTAThread]

        [DllImport("coredll.Dll")]
        private static extern int GetLastError();

        [DllImport("coredll.Dll")]
        private static extern int ReleaseMutex(IntPtr hMutex);

        [StructLayout(LayoutKind.Sequential)]


        public class SECURITY_ATTRIBUTES
        {
            public int nLength;
            public int lpSecurityDescriptor;
            public int bInheritHandle;
        }

        [DllImport("coredll.Dll")]
        private static extern IntPtr CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName);

        private const int ERROR_ALREADY_EXISTS = 0183;

        [DllImport("coredll.dll")]
        public static extern IntPtr FindWindow(string classname, string windowname);
        [DllImport("coredll.dll")]
        public static extern bool SetForegroundWindow(IntPtr hwnd);

        static void Main()
        {
            IntPtr hMutex = CreateMutex(null, false, "StrAppName");
            if (GetLastError() == ERROR_ALREADY_EXISTS)
            {
                ReleaseMutex(hMutex);

                IntPtr hWndApp = FindWindow(null, "StrAppName");
                SetForegroundWindow(hWndApp);

                return;
            }

            Application.Run(new FormMain());
        }
    }


[其他解释]
ding
[其他解释]
学习啦!~
[其他解释]
Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.
[其他解释]
帮顶,呵呵,过些天再来,马上就要用到了。。。。
[其他解释]

using System.Runtime.InteropServices;

[其他解释]
有意思,强烈学习关注中
[其他解释]

[其他解释]
引用:
windows mobile 本身只能运行一个实例。你不用再费心了。

这位仁兄说得正确,你先运行A.EXE,然后最小化A.EXE,在运行一次A.EXE,原来的A.EXE就出来了,WM压根就只能同时运行一个程序的一次实例
------其他解决方案--------------------


TO:huangbeyond
你怎么又在这里摆弄“Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.”了,之前在这个帖子里http://topic.csdn.net/u/20091124/11/95f0fdb7-0e0e-499e-ab1f-270d7778cb03.html已经用指出了CreateMutex 不支持可命名。就凭着自己没试成功的方法,到处去说CreateMutex不支持可命名。更加可悲的是,许多人还认为他是对的,我真想不懂,你们一个个都没有用过,没有调查就没有发言权。

再说,想想看, semaphores, events, mutexes都是内核对象。微软的系统怎么能不支持可命名mutex。那么微软自己是怎么解决进程间互质的问题啊,答案是肯定的,内核同步对象mutex

再看看微软帮助文档。

Two or more processes can call CreateMutex to create the same named mutex. The first process actually creates the mutex, and subsequent processes open a handle to the existing mutex. This enables multiple processes to get handles of the same mutex, while relieving you of the responsibility of ensuring that the creating process is started first. When using this technique, set the bInitialOwner flag to FALSE; otherwise, it can be difficult to be certain which process has initial ownership.

Multiple processes can have handles of the same mutex object, enabling use of the object for interprocess synchronization. To provide object sharing, a process can specify the name of a mutex object in a call to the CreateMutex function.



[其他解释]
windows mobile 本身只能运行一个实例。你不用再费心了。
[其他解释]
路过学习。
[其他解释]
问google啊
[其他解释]
xx
[其他解释]
帮你顶
[其他解释]
不错啊
[其他解释]
study
[其他解释]
咋没个人辛苦下,写几句代码验证下呢~,~
[其他解释]
路过学习。。。
[其他解释]
学习一下呵呵
[其他解释]
可以遍历进程列表根据进程名来判断是否有实例了
[其他解释]
不懂,学习
[其他解释]
该回复于2009-12-21 20:04:32被版主删除
[其他解释]
mark
[其他解释]

引用:
引用:
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.

呵呵,我一直用CreatMutex,原来是错的啊~~~那就错吧,反正可以实现~~~


up
[其他解释]
 0x01));
CloseHandle(hEvent);
return NULL;
}
}
while (++cTries < 2);  // only try twice

// If we didn't find the window, the other application was probably


// shutting down, so we'll just continue
}
}

// Done
return hEvent;
}

[其他解释]

引用:
楼上错了!

Windows Mobile下面不支持可命名的内核对象! 楼自己都没去试过,还出来教别人,真可怕.


呵呵,有意思。WM支持。

1楼说的是对的,标准做法就是CreatMutex, SDK里很多这样的sample,比如
Windows Mobile 6 SDK\Samples\Common\CPP\Win32\BasicApp\basicapp.cpp

HANDLE FindPrevInstance()
{
HANDLE hEvent;
HWND   hwnd;
UINT   cTries = 0;

// Create a named event
hEvent = CreateEvent(NULL, TRUE, FALSE, g_szClassName);
if (hEvent != NULL)
{
// If the event already existed, that means there's another copy of our app
// already running
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
do
{
// Just in case the other window needs to finish initialization
Sleep(cTries ? 250 : 0);

// Try to find the other application window
hwnd = FindWindow(g_szClassName, NULL);
if (hwnd != NULL)
{
SetForegroundWindow((HWND)((UINT_PTR)hwnd 
[其他解释]
最简单的办法:对配置文件加锁.程序启动过后一直维持.进程退出系统自动释放.
[其他解释]
引用:
引用:
引用:windows mobile 本身只能运行一个实例。你不用再费心了。
这位仁兄说得正确,你先运行A.EXE,然后最小化A.EXE,在运行一次A.EXE,原来的A.EXE就出来了,WM压根就只能同时运行一个程序的一次实例


你们真的试过吗??wm只能运行一个实例??
我怎么刚试了同一程序运行了几个实例呢……


试过的, 确实是只运行一个. 不过我的程序是用C#编写的窗口程序, 不知道你的程序是什么样的?
或许是平台的关系吧
[其他解释]
引用:
引用:windows mobile 本身只能运行一个实例。你不用再费心了。
这位仁兄说得正确,你先运行A.EXE,然后最小化A.EXE,在运行一次A.EXE,原来的A.EXE就出来了,WM压根就只能同时运行一个程序的一次实例


你们真的试过吗??wm只能运行一个实例??
我怎么刚试了同一程序运行了几个实例呢~~~,没有实验就不要乱说,太不负责任了
[其他解释]
引用:
windows mobile 本身只能运行一个实例。你不用再费心了。


正解
[其他解释]
我的程序也可以同时运行多个实例,而且在同目录下的程序启动的。c#
[其他解释]
运行自己的程序,然后最小化。
再次运行自己的程序,
让后用Remote Spy查看。只有一个程序实例。


不知道是我看的方法不对还是???

大家说说。。。

C++的。
[其他解释]
我的PDA上同时多个是可以的,等界面出来再去点就不会允许新的窗口了,这是算能还是不能呢...
引用:
我的程序也可以同时运行多个实例,而且在同目录下的程序启动的。c#

[其他解释]
我做了个实验,同一个程序可以运行多个实例的,条件是程序运行后窗体隐藏(使用ShowWindow(SW_HIDE)),当窗体隐藏后,在点击程序运行,就可以创建同名的另一个进程了,只不过再创建新进程的时候会有点慢 大概有个5~10秒才能创建

热点排行