能力值:
( LV2,RANK:10 )
|
-
-
2 楼
可以设一个全局的计数器,可以进程间共享。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
也可以用Mutex
|
能力值:
(RANK:10 )
|
-
-
4 楼
兄弟门说得太简洁了 哎
|
能力值:
( LV6,RANK:90 )
|
-
-
5 楼
最初由 guanmj 发布 也可以用Mutex
要打开十个A.exe,如何用mutex
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
最初由 analog 发布 要打开十个A.exe,如何用mutex
个人愚见:
Mutex1 ~ Mutex10 ,如果全都在,就拒绝运行,否则就创建一个
|
能力值:
( LV6,RANK:90 )
|
-
-
7 楼
最初由 testttt 发布 个人愚见: Mutex1 ~ Mutex10 ,如果全都在,就拒绝运行,否则就创建一个
代码是相当的冗长,如果系统配置够的话,是要运行100个呢,创建100个mutex?
还是参考2楼的吧
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
最初由 analog 发布 代码是相当的冗长,如果系统配置够的话,是要运行100个呢,创建100个mutex?
还是参考2楼的吧
我的答案完全是针对这个问题:
最初由 analog 发布 要打开十个A.exe,如何用mutex
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
#pragma data_seg("InsCShare")
long InstanceCount = 0
#pragma data_seg()
#pragma comment(linker, "/section:InsCShare, RWS")
然后在程序中控制InstanceCount即可。
|
能力值:
( LV9,RANK:170 )
|
-
-
10 楼
使用信号量
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
用内存映射文件
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
如果楼主是需要控制自己写的程序可以这样做:
//打开内存映射文件
HANDLE handle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, 0, _T("内存映射文件的名称"));
//如果是第一次运行程序,则创建内存映射文件
if(handle == NULL)
{
//第一个参数传递-1,则将映射创建到页文件,而不是创建到硬盘上的文件.其他参数详见MSDN
handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 256, _T("内存映射文件名称"));
if(handle == NULL)
{
return; //创建失败,返回
}
}
//映射文件,得到缓冲区指针,这时就可以随意操作,记住不要越界
LPVOID lpBuffer = MapViewOfFile(handle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
//在lpBuffer里记录当前程序运行的次数,超过你的定义次数则关闭程序...
/*
...
*/
//完成计数之后记得关闭映射
CloseHandle(handle);
另外在程序退出的时候记得使用同样方法,将计数器-1.
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
如果是需要监视其他人写的程序,我也只是提供一个思路,具体没试过:
在后台运行自己的监视程序,使用钩子钩住
ShellExecute或者CreateProcess等能够启动进程的API函数,出现你需要记录的进程计数器+1,
还要把ExitProcess钩住,程序退出,计数器-1.
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
还有一个龌龊点的办法,就是:
在后台建立一个监视程序,每隔一段时间遍历一下所有的进程.并记录你需要监视的进程数量,超过了就杀之.
|
能力值:
( LV10,RANK:170 )
|
-
-
15 楼
用9楼住户的方法实现了一个:
#include <windows.h>
#include "resource.h"
#include <stdio.h>
#pragma data_seg(".thinkSJ")/////添加一个新节并共享
DWORD gs_dCount = 0;
#pragma data_seg()
#pragma comment(linker,"/section:.thinkSJ,RWS")
LRESULT CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE,LPSTR,int)
{
::DialogBoxParam (hInstance,(LPCTSTR)IDD_MAIN,NULL,(DLGPROC)DlgProc,NULL);
return 1;
}
LRESULT CALLBACK DlgProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
gs_dCount += 1; //////在初使化消息中对全局标志位加1
if(gs_dCount > 5)/////该程序只能运行5份实例
{
::SendMessage (hWnd,WM_CLOSE,0,0);
}
return true;
case WM_CLOSE:
gs_dCount -= 1;//////在关闭消息中对全局标志位减1
::EndDialog (hWnd,0);
return true;
}
return false;
}
将5改成10就符合要求了
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
最初由 thinkSJ 发布 用9楼住户的方法实现了一个: #include <windows.h> #include "resource.h" #include <stdio.h> #pragma data_seg(".thinkSJ")/////添加一个新节并共享 ........
#pragma data_seg(".thinkSJ")/////添加一个新节并共享
DWORD gs_dCount = 0;
#pragma data_seg()
#pragma comment(linker,"/section:.thinkSJ,RWS")
请问这一段代码是告诉编译器段的权限是RWS吗?
R:READ W:WRITE S:代表什么?
还有我正在看win32汇编程序设计,看到Makefile
里面有这么一段代码也是共享数据段,能帮忙解释一下吗?
NAME = Main
DLL = Hookdll
ML_FLAG = /c /coff
LINK_FLAG = /subsystem:windows
DLL_LINK_FLAG = /subsystem:windows /section:.bss,S
$(DLL).dll $(NAME).exe:
$(DLL).dll: $(DLL).obj $(DLL).def
Link $(DLL_LINK_FLAG) /Def:$(DLL).def /Dll $(DLL).obj
$(NAME).exe: $(NAME).obj $(NAME).res
Link $(LINK_FLAG) $(NAME).obj $(NAME).res
.asm.obj:
ml $(ML_FLAG) $<
.rc.res:
rc $<
clean:
del *.obj
del *.res
del *.exp
del *.lib
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
最初由 thinkSJ 发布 用9楼住户的方法实现了一个: ........
如果某个进程非正常结束,那就......
|
能力值:
( LV10,RANK:170 )
|
-
-
18 楼
s代码的是共享的意思,share
对于MAKEFILE我不了解,非正常结束是不对的,不知楼上有何高招不?
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
|
能力值:
( LV10,RANK:170 )
|
-
-
20 楼
为什么建议用内核对象?在程序非正常结束的情况,内核对象也得不到释放,而这些都是系统资源,因此用这种方法的损失会更大。
另外一个郁闷的问题是,用内核对象的代码我不知该怎么写,testttt能否发一份代码学习下??
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
[color=#0000D0]HANDLE[/color] g_hHandle;
g_hHandle = [b][color=#000080]CreateMutex[/color][/b]([color=#0000D0]NULL[/color], [color=#0000D0]FALSE[/color], [color=#808080]"Mutex Name"[/color]);
[color=#0000D0]if[/color]([b][color=#000080]GetLastError[/color][/b]() == ERROR_ALREADY_EXISTS) [color=#008000]//Mutex已经存在[/color]
{
[color=#0000D0]return[/color] [color=#0000D0]FALSE[/color];
}
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
最初由 thinkSJ 发布 为什么建议用内核对象?在程序非正常结束的情况,内核对象也得不到释放,而这些都是系统资源,因此用这种方法的损失会更大。
程序非正常结束的情况,资源是否会被释放我也不清楚
但内核对象用于防止进程重复执行的可行性,已经得到大量的实践的证实
|
能力值:
( LV10,RANK:170 )
|
-
-
23 楼
哇哈哈,如果是程序的单实例运行,采用命名内核对象的方法是很有效的,但现在的问题是运行10份实例,所以对于21楼的代码我的理解是:
当它第一次运行时就会产生一个Mutex Name的内核对象,
当它第二次运行就会失败,因为已经存在同名的了。
所以结论是21楼的代码不符合要求。
|
能力值:
( LV2,RANK:10 )
|
-
-
24 楼
|
能力值:
( LV13,RANK:370 )
|
-
-
25 楼
// 用信号量:
HANDLE hSema = CreateSemaphore(NULL, 10, 10, "MySemaName");
DWORD dwRet = WaitForSingleObject(hSema, 0);
if (0 != dwRet)
{
// 退出!
}
// 在程序结束前:
RealseSemaphore(hSema, 1, NULL);
CloseHandle(hSema);
|
|
|