|
基本是根据asbai大侠VC源码的思路去写,区别有:
1、取消30秒的黙认延迟。
目的是防止不明这个程式功能的用户拼命双击它,因为它允许多副本同时运行,当用户双击它发现没有任何提示可能会在30秒内连续多次双击它,这样就会出现多个副本同时运行。
2、增加对WinPE系统环境的检测,在非WinPE环境执行时显示帮助说明。
目的是使用户在非WinPE环境中了解它的功能和作用。
3、简化延迟时间参数,参数只用秒表示。
这种情况下用分、小时表示意义不大,支持小数秒。
4、取消异常处理。
以下是Delphi源码,附件也有,不明一点,为什么这个比VC做的还小很多?
- program PEWaitKill;
- uses
- tlHelp32,
- Windows,
- SysUtils;
- //查找进程函数
- //入口参数: 进程文件名
- //返 回 值: 进程ID(0表示进程不存在或找不到)。
- function FindProcess(ProcessEXEName: string): integer;
- var
- hSnap: THandle;
- ProcessEntry: TProcessEntry32;
- ProcessID: integer;
- Proceed: Boolean;
- begin
- ProcessID := 0;
- hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
- if not (HSnap = 0) then begin
- ProcessEntry.dwSize := SizeOf(TProcessEntry32);
- Proceed := Process32First(hSnap, ProcessEntry);
- while Proceed do begin
- if UpperCase(ProcessEXEName) = UpperCase(StrPas(ProcessEntry.szEXEFile)) then
- begin
- ProcessID := ProcessEntry.Th32ProcessID;
- break;
- end;
- Proceed := Process32Next(hSnap, ProcessEntry);
- end;
- CloseHandle(hSnap);
- end;
- result := ProcessID;
- end;
- //杀进程过程,入口参数为进程文件名。
- procedure KillProcess(ProcessEXEName: string);
- var
- ProcessID: integer;
- ProcessHndle: THandle;
- uexitcode: byte;
- begin
- ProcessID := FindProcess(ProcessEXEName);
- if ProcessID <> 0 then begin
- ProcessHndle := OpenProcess(PROCESS_TERMINATE, false, ProcessID);
- TerminateProcess(ProcessHndle, uexitcode);
- CloseHandle(ProcessHndle);
- end;
- end;
- //延时过程,入口参数毫秒。
- procedure TimeDelay(TimeToWait: Cardinal);
- var StartTime: Cardinal;
- begin
- StartTime := GetTickCount;
- repeat
- Windows.Sleep(200);
- until ((GetTickCount - StartTime) > TimeToWait);
- end;
- //延迟指定时间后,杀进程。
- procedure WaitToKillProcess(TimeToWait: Cardinal);
- begin
- TimeDelay(TimeToWait);
- //其实下面两行通过创建一个进程执行 XPEinit -9 可能更可靠。
- KillProcess('Smss.exe');
- KillProcess('Winlogon.exe');
- end;
- //显示帮助说明。
- procedure DisplayHelp();
- var AppName: string;
- begin
- AppName := ExtractFileName(ParamStr(0));
- MessageBox(0, Pchar(
- '功能: 为了防止WinPE在24小时后重启,等待一定时间后在后台结束' + #13 +
- ' Winlogon.exe 和 Smss.exe 进程。' + #13 + #13 +
- '用法: ' + AppName + ' [TimeToWait]' + #13 +
- ' TimeToWait - 等待指定的时间(秒)后,试图结束那两个进程。' + #13 + #13 +
- '例子: ' + AppName + ' 12.345 - 等待12.345秒。' + #13 + #13 +
- '注意: 本进程只能在WinPE系统环境中执行,在指定的等待时间后,' + #13 +
- ' 若找不到目标进程或已结束目标进程,本进程也结束。'),
- Pchar(AppName + ' By 老九'), MB_OK)
- end;
- //取得命令行延迟时间函数,返回数值(毫秒)。
- function GetTimeToWait(): Cardinal;
- var TMP: Single;
- Code: integer;
- begin
- Val(ParamStr(1), TMP, Code);
- if Code = 0 then result := Round(TMP * 1000)
- else result := 0;
- end;
- //主体过程。
- procedure MainProcedure();
- var TimeToWait: Integer;
- Parameters: string;
- StartupInfo: TStartupInfo;
- ProcessInfo: TProcessInformation;
- begin
- if UpperCase(GetEnvironmentVariable('SystemDrive')) = 'X:' then
- case ParamCount of
- 1: begin // 1个参数,由xpeinit调用的前台进程
- TimeToWait := GetTimeToWait();
- if TimeToWait > 0 then begin
- Parameters := ParamStr(0) + ' ' + ParamStr(1) + ' /DaemonFork';
- FillChar(StartUpInfo, SizeOf(StartUpInfo), 00);
- StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
- StartUpInfo.wShowWindow := SW_HIDE;
- CreateProcessA(nil, PChar(Parameters), nil, nil, False, 0,
- nil, nil, StartupInfo, ProcessInfo);
- end;
- end;
- 2: begin // 2个参数,由本身启动的后台进程。
- TimeToWait := GetTimeToWait();
- if ((TimeToWait > 0) and (ParamStr(2) = '/DaemonFork')) then
- WaitToKillProcess(TimeToWait);
- end;
- else DisplayHelp(); //不是1个或2个参数都显示帮助说明。
- end
- else DisplayHelp(); //非WinPE系统环境。
- end;
- begin
- MainProcedure();
- end.
复制代码 |
|