首页
社区
课程
招聘
[求助]能够不能够实现只让一台机器上运行10个实例
2006-8-10 21:04 8744

[求助]能够不能够实现只让一台机器上运行10个实例

2006-8-10 21:04
8744
我想实现这样的一个功能
比如软件A.exe
我只想在一台机器上能够打开10个A.exe
可否通过加密的方法实现

谢谢

[培训]内核驱动高级班,冲击BAT一流互联网大厂工 作,每周日13:00-18:00直播授课

收藏
点赞0
打赏
分享
最新回复 (33)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nhyzj 2006-8-11 10:27
2
0
可以设一个全局的计数器,可以进程间共享。
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
guanmj 2006-8-11 11:28
3
0
也可以用Mutex
雪    币: 0
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
chinadev 2006-8-13 03:32
4
0
兄弟门说得太简洁了 哎
雪    币: 216
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
analog 2 2006-8-13 08:15
5
0
最初由 guanmj 发布
也可以用Mutex

要打开十个A.exe,如何用mutex
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-13 10:53
6
0
最初由 analog 发布
要打开十个A.exe,如何用mutex

个人愚见:
Mutex1 ~ Mutex10 ,如果全都在,就拒绝运行,否则就创建一个
雪    币: 216
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
analog 2 2006-8-13 11:08
7
0
最初由 testttt 发布
个人愚见:
Mutex1 ~ Mutex10 ,如果全都在,就拒绝运行,否则就创建一个

代码是相当的冗长,如果系统配置够的话,是要运行100个呢,创建100个mutex?

还是参考2楼的吧
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-13 16:19
8
0
最初由 analog 发布
代码是相当的冗长,如果系统配置够的话,是要运行100个呢,创建100个mutex?

还是参考2楼的吧


我的答案完全是针对这个问题:
最初由 analog 发布
要打开十个A.exe,如何用mutex
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nhyzj 2006-8-13 19:38
9
0
#pragma data_seg("InsCShare")
long InstanceCount = 0
#pragma data_seg()

#pragma comment(linker, "/section:InsCShare, RWS")

然后在程序中控制InstanceCount即可。
雪    币: 260
活跃值: (214)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
andy00 4 2006-8-14 11:07
10
0
使用信号量
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
haibin1013 2006-8-16 20:39
11
0
用内存映射文件
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
masmprogra 2006-8-17 10:51
12
0
如果楼主是需要控制自己写的程序可以这样做:

//打开内存映射文件
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.
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
masmprogra 2006-8-17 10:56
13
0
如果是需要监视其他人写的程序,我也只是提供一个思路,具体没试过:

在后台运行自己的监视程序,使用钩子钩住
ShellExecute或者CreateProcess等能够启动进程的API函数,出现你需要记录的进程计数器+1,
还要把ExitProcess钩住,程序退出,计数器-1.
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
masmprogra 2006-8-17 10:59
14
0
还有一个龌龊点的办法,就是:

在后台建立一个监视程序,每隔一段时间遍历一下所有的进程.并记录你需要监视的进程数量,超过了就杀之.
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
thinkSJ 4 2006-8-17 11:06
15
0
用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就符合要求了
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
masmprogra 2006-8-17 11:35
16
0
最初由 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
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-17 11:41
17
0
最初由 thinkSJ 发布
用9楼住户的方法实现了一个:
........


如果某个进程非正常结束,那就......
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
thinkSJ 4 2006-8-17 12:15
18
0
s代码的是共享的意思,share
对于MAKEFILE我不了解,非正常结束是不对的,不知楼上有何高招不?
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-17 14:04
19
0
最初由 thinkSJ 发布
不知楼上有何高招不?

高招实在没有
让某个进程去维护计数器也不现实,还是建议使用Mutex、Event等内核对象
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
thinkSJ 4 2006-8-17 14:26
20
0
为什么建议用内核对象?在程序非正常结束的情况,内核对象也得不到释放,而这些都是系统资源,因此用这种方法的损失会更大。

另外一个郁闷的问题是,用内核对象的代码我不知该怎么写,testttt能否发一份代码学习下??
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-17 17:19
21
0
[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];
}
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-17 17:26
22
0
最初由 thinkSJ 发布
为什么建议用内核对象?在程序非正常结束的情况,内核对象也得不到释放,而这些都是系统资源,因此用这种方法的损失会更大。

程序非正常结束的情况,资源是否会被释放我也不清楚
但内核对象用于防止进程重复执行的可行性,已经得到大量的实践的证实
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
thinkSJ 4 2006-8-17 22:14
23
0
哇哈哈,如果是程序的单实例运行,采用命名内核对象的方法是很有效的,但现在的问题是运行10份实例,所以对于21楼的代码我的理解是:
当它第一次运行时就会产生一个Mutex Name的内核对象,
当它第二次运行就会失败,因为已经存在同名的了。
所以结论是21楼的代码不符合要求。
雪    币: 209
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
testttt 2006-8-17 22:48
24
0
最初由 thinkSJ 发布
所以结论是21楼的代码不符合要求。

可能是我回答问题太有针对性了,以后要改一改
那么 6 楼的如何?
雪    币: 1593
活跃值: (736)
能力值: ( LV13,RANK:370 )
在线值:
发帖
回帖
粉丝
luocong 9 2006-8-17 23:01
25
0
// 用信号量:
HANDLE hSema = CreateSemaphore(NULL, 10, 10, "MySemaName");
DWORD dwRet = WaitForSingleObject(hSema, 0);
if (0 != dwRet)
{
    // 退出!
}

// 在程序结束前:
RealseSemaphore(hSema, 1, NULL);
CloseHandle(hSema);
游客
登录 | 注册 方可回帖
返回