我有两个程序A.exe和B.exeA.exe执行CreateSemaphore(nil,0,5,'1122334455'); //创建一个信号机那么系统里现在有一个 1122334455 的信号机,我用工具已经看到了.
我如何用B.exe来关闭这个1122334455信号机呢?我用工具可以关闭...
我用了ReleaseSemaphore和CloseHandle都不行呢,请给代码另外必须是两个程序,A:创建信号,B:关闭信号,我知道同一个进程是可以关闭的!
我如何用B.exe来关闭这个1122334455信号机呢?我用工具可以关闭...
我用了ReleaseSemaphore和CloseHandle都不行呢,请给代码另外必须是两个程序,A:创建信号,B:关闭信号,我知道同一个进程是可以关闭的!
解决方案 »
- delphi 的Utf8ToUnicode方法
- 請問一個很簡單的問題:dbf文件是什麽數據庫的數據文件,怎麽把數據導出來
- 請教各路英雄,我想讓程序在每天的某個特定時間自動執行,該如何去做??
- 菜问题:oracle 里能不能用left join ,inner join 这样关联表?
- TreeView的text可不可以换行?
- 请教关于TreeView和ListView的问题?
- 哪儿有数据库驱动的象资源管理器那样的TREEVIEW的原代码?
- 关于进程问题
- 动态生成DBchart显示不一致
- 在BCB中的AnsiString 和delphi中的AnsiString有何区别?
- 我HOOK了别人的connect,让别人的程序连我,请教如何判断connect断开
- DateTimePicker1 年月日时分秒合并 SQL语句 delphi
你在b.exe先用这个函数得到信号量的句柄然后在用releasesemaphore释放。
如果你指的是删除信号量对象的话,你就得用CloseHandle关闭信号量的所有句柄。它的所有句柄都关闭以后,对象自己也会删除。所以你需要在b中枚举所有内核对象然后找到你需要关闭的。
关于枚举内核对象的大多是vc的需要自己翻译成delphi。以下两个各自参考下:
http://topic.csdn.net/u/20100209/22/43678cfa-0716-4936-96eb-2300a22ed533.html
http://topic.csdn.net/u/20100331/05/b19406e0-20d3-44a6-bae2-e91b637eb8bc.html
VC的实在看不懂,求会的列一下代码,DELPHI的
在A放个时钟,用来判断运行的条件是否而在,如:外部一个文件或一个外部的变量,用B来改变外部文件或变量。A就会自动响应了。 如我在A运行时自动建立一个名字为C.txt的文件,然后在A的时钟里判断C是否存在,如C不存在就退出。
在B程序中只要删除C.txt就可以了。抛砖引玉。
LZ还是把代码贴出来吧,这么猜没谱了,不过你的ReleaseSemaphore执行成功了么?
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
http://www.cnblogs.com/del/archive/2011/07/19/1390747.html
“4、最后, 作为系统内核对象, 要用 CloseHandle 关闭.”
而这个方法不用我贴代码了吧,就一个参数,囧.............
__in HANDLE hObject
);另外,之所以LZ关闭不成功,我觉得应该先检查下在另一个进程里获取是否成功,然后判断closehandle的返回值,查看下错误代码,所以开始我才说把代码贴出来看下嘛,这么猜不靠谱啊
A进程调用CreateSemaphore成功后,信号量内核对象计数应该已经是1了,然后B.exe去获取信号量句柄成功后,内核对象计数为2,在B.exe中调用CloseHandle成功内核对象计数又变为1,所以才会出现删除不成功,除非把A.exe中也调用CloseHandle或是结束A进程,要么就是枚举内核对象根据名称找到需要关闭的,然后CloseHandle关闭它。
我想楼主用的那个工具就应该是枚举指定进程中的内核对象。
Increases the count of the specified semaphore object by a specified amount.
Realease增加的是信号量的资源计数器,CreateSemaphore第二个参数指定资源计数器初始化多少个资源可利用。
另外CreateSemaphore创建一个信号量成功后,该信号量内核对象的使用计数是1,当使用OpenSemaphore成功时候内核计数器就会增加1.
PS:内核对象的使用计数:
如果你的进程调用了一个创建内核对象的函数,然后你的进程终止运行,那么内核对象不一定被撤消。因为此时内核对象可能被其它进程使用着。内核对象的存在时间可以比创建该对象的进程长。
每个内核对象包含一个使用计数(有点像COM的引用计数)。当一个对象刚刚创建时,它的使用计数被置为1 。然后,当另一个进程访问一个现有的内核对象时,使用计数就递增1 。当进程终止运行时,内核就自动确定该进程 仍然打开的所有内核对象的使用计数。如果内核对象的使用计数降为0 ,内核就撤消该对象。这样可以确保在没有进程引用该对象时系统中不保留任何内核对象。
(PS内容摘自http://www.cnblogs.com/fangyukuan/archive/2010/08/31/1813125.html)
所以我要干掉A程序的这个信号量.只能枚举A程序的所有内核对象了么?
还有,to m617105,你那两个贴子我看了, 确实有个翻译的,但是我测试了不能用.C代码也看不懂
还有,中秋快乐,谢谢
ps. CreateSemaphore CreateSemaphoreA CreateSemaphoreW 我都HOOK过,没有创建112233445的信号量,但是我用工具XueTr确看到了创建了这个1122334455的信号量,XueTr可以把这个信号量删除,然后我就可以多开A程序了
releaseCount 小于 1。Lz如果能正确取到信号量的句柄,ReleaseSemaphore也能正常执行,那就多次执行ReleaseSemaphore直到该异常抛出,然后再试试能不能多开
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
UNICODE_STRING = record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
hSemaphore:THandle;
implementation{$R *.dfm}
procedure EumKnlObjectName(var sList:TStringList);
type
PObjectTypeInformation = ^TObjectTypeInformation;
TObjectTypeInformation = packed record
Name: string;
ObjectCount, HandleCount: Cardinal;
Reserved1: array[0..3] of Cardinal;
PeakObjectCount, PeakHandleCount: Cardinal;
Reserved2: array[0..3] of Cardinal;
InvalidAttributes: Cardinal;
GenericMapping: TGenericMapping;
ValidAccess: Cardinal;
Unknown: UCHAR;
MaintainHandleDatabase: Boolean;
Reserved3: array[0..1] of UCHAR;
PoolType: Cardinal;
PagedPoolUsage, NonPagedPoolUsage: Cardinal;
end; POBJECT_ALL_TYPES_INFORMATION = ^TOBJECT_ALL_TYPES_INFORMATION;
TOBJECT_ALL_TYPES_INFORMATION = record // Information Class 3
NumberOfTypes: DWORD;
TypeInformation: TObjectTypeInformation;
end; TOBJECT_INFORMATION_CLASS = (
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllTypesInformation,
ObjectHandleInformation); PObjectNameInformation = ^TObjectNameInformation;
TObjectNameInformation = packed record
Name: UNICODE_STRING;
end; PSystemHandleInformation = ^TSystemHandleInformation;
TSystemHandleInformation = packed record
ProcessId: DWORD;
ObjectTypeNumber: Byte;
Flags: Byte;
Handle: Word;
eObject: Pointer;
GrantedAccess: ACCESS_MASK;
end; PSystemHandleInformation_Ex = ^TSystemHandleInformation_Ex;
TSystemHandleInformation_Ex = packed record
NumberOfHandles: DWORD;
Information: TSystemHandleInformation;
end; PNtQuerySystemInformation = function(SystemInformationClass: DWORD; SystemInformation: Pointer; SystemInformationLength: ULONG; ReturnLength: PULONG): DWORD; stdcall; PNtQueryObject = function(ObjectHandle: THANDLE;
ObjectInformationClass: TOBJECT_INFORMATION_CLASS;
ObjectInformation: Pointer;
ObjectInformationLength: DWORD;
ReturnLength: PDWORD): DWORD; stdcall;
var
_ModuleHandle, _Count, i: Dword;
_NtQueryObject: PNtQueryObject;
_ObjTypeInfo: POBJECT_ALL_TYPES_INFORMATION;
_P, _StrLen, _Size: DWORD;
_ObjName: string;
_NtQuerySystemInformation: PNtQuerySystemInformation;
pHandleInfor: PSystemHandleInformation_Ex;
_HandleInfor: PSystemHandleInformation;
_Name: PObjectNameInformation;
begin _Count := 0;
_ModuleHandle := GetModuleHandle('ntdll.dll');
_NtQueryObject := GetProcAddress(_ModuleHandle, 'NtQueryObject');
_NtQuerySystemInformation := GetProcAddress(LoadLibrary('ntdll.dll'), 'NtQuerySystemInformation');
_Size := $1000;
GetMem(pHandleInfor, _Size);
while _NtQuerySystemInformation(16, pHandleInfor, _Size, nil) <> 0 do
begin
_Size := _Size + _Size;
ReallocMem(pHandleInfor, _Size);
end;
_Name := GetMemory($1000);
for I := 0 to pHandleInfor^.NumberOfHandles - 1 do
begin
_HandleInfor := PSystemHandleInformation(dword(pHandleInfor) + 4 + (i * SizeOf(TSystemHandleInformation)));
if (_HandleInfor^.ProcessId = GetCurrentProcessId) then
begin
if _NtQueryObject(_HandleInfor^.Handle, ObjectNameInformation, _Name, $1000, nil) = 0 then
begin
_ObjName := WideCharToString(_Name.Name.Buffer);
sList.Add(IntToHex(Dword(_HandleInfor^.Handle), 8) + '-' + IntToStr(_HandleInfor^.ObjectTypeNumber) + ':' + _ObjName);
end;
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
test:TStringList;
begin
hSemaphore:=CreateSemaphore(nil,0,5,'1122334455');
ShowMessage(IntToStr(GetLastError));
test:=TStringList.Create;
EumKnlObjectName(test);
ShowMessage(IntToStr(GetLastError));
Memo1.Lines.Assign(test);
end;
end.部分运行截图如下: