如和判断文件已被打开,并关闭该进程!(0分)

  • 主题发起人 主题发起人 nutian
  • 开始时间 开始时间
N

nutian

Unregistered / Unconfirmed
GUEST, unregistred user!
找到个函数,可是不能判断文本文件的打开
function IsFileInUse(fName : string) : boolean;
var
HFileRes : HFILE;
begin
Result := false;
if not FileExists(fName) then
exit;
HFileRes := CreateFile(pchar(fName), GENERIC_READ or GENERIC_WRITE,
0 {this is the trick!}, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
Result := (HFileRes = INVALID_HANDLE_VALUE);
if not Result then
CloseHandle(HFileRes);
end;
=====================================
再試下面的﹐絕對沒有問題了。加上ShellAPI,TlHelp32
procedure TForm1.Button3Click(Sender: TObject);//查出所有進程﹐
var
hSnapshot: THandle;
ProcessEntry: TProcessEntry32;
hProcess: THandle;
sFileName: string;
iProcessID: Integer;
iOK:Boolean;
begin
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
ProcessEntry.dwSize := SizeOf(TProcessEntry32);
iOK := Process32First(hSnapshot, ProcessEntry);
repeat
sFileName := ExtractFileName(ProcessEntry.szExeFile);
listbox1.Items.Add(sFileName);//進程使用的EXE
listbox2.Items.Add(IntToStr(ProcessEntry.th32ProcessID));//進程號
if sFileName = 'EXPLORER.EXE' then
begin
iProcessID := ProcessEntry.th32ProcessID; // ExplorerµÄProcessID
Break;
end;
until (not Process32Next(hSnapshot, ProcessEntry));
CloseHandle(hSnapshot);
end;

procedure TForm1.Button5Click(Sender: TObject);//殺掉你選中的進程
begin
TerminateProcess(OpenProcess(PROCESS_TERMINATE,BOOL(0),StrToInt(Edit1.Text)),0);
end;
==============================
如果你知道指定应用程序的标题就好办多了.
比如标题为'Kill'.
var
h: HWnd;
begin
h:=FindWindow(nil, 'Kill');
if h<>0 then
SendMessage(h, WM_Close, 0, 0);
end;
 
我的一个程序用TFindProc控件列出当前系统的全部进程,但我发现它列出的进程比FPE等工具软件
列出的数量要少。以前还可以凑合着用,现在发现了一个大问题:我的程序看不见DOS进程!
如富甲天下2这个DOS游戏。
FPE到底使用了什么技术?最好给出源代码。

以下是TFindProc控件枚举进程的代码:
var
i:Integer;
snap : THandle;
pe32 : TPROCESSENTRY32;
begin
snap := 0;
for i := 0 to fProcessList.Count-1 do
fProcessList.Objects.Free;
fProcessList.Clear;
try
snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if snap < > 0 then begin
pe32.dwSize := SizeOf(TPROCESSENTRY32);
if Process32First(snap, pe32) then begin
AddProcess(pe32);
while Process32Next(snap, pe32) do
AddProcess(pe32);
end;
end;
finally
CloseHandle(snap);
end;
End;

它列出的进程数比FPE少太多了...
================================================================
1.如何在win 9x下实现列举所有进程?
2.如何取得一个进程的真句柄,即通用的、不变的句柄?(据MSDN,OpenProcess取得的是
一个伪句柄,不可传递给其他进程)
1.EnumProcesses在98下照样用
2 HANDLE OpenProcess(
DWORD dwDesiredAccess, // access flag
BOOL bInheritHandle, // handle inheritance flag
DWORD dwProcessId // process identifier
);获得的句柄可以用。MSDN中有详细的关于各个参数的说明。

==============================================================
在线获取更新信息演示程序
http://www.delphibox.com/softview.php?type=m&softid=49
 
怎样关闭在ListView中选定的进程
程序:
type
TProcessInfo = Record
ExeFile : String;
ProcessID : DWORD;
end;
pProcessInfo = ^TProcessInfo;

type
TForm1 = class(TForm)
Button1: TButton;
ListView1: TListView;

procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
processlist:array of word ;
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var p : pProcessInfo;
ContinueLoop:BOOL;
ListItem: TListItem;

FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
i:integer;
begin

FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
New(p);
p.ExeFile := FProcessEntry32.szExeFile;
p.ProcessID := FProcessEntry32.th32ProcessID;
ListItem := listview1.Items.Add;
ListItem.Caption := Format('%d',[p.ProcessID]);
ListItem.SubItems.Add(Format('%s',[p.ExeFile]));
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;

procedure TForm1.Button1Click(Sender: TObject);//关闭进程
var Exehandle:thandle;
s,str:string;
begin
??? //s:=listview1.Items[listbox1.ItemIndex];
//ExeHandle:=Findwindow(nil,pchar(s));
//if ExeHandle<>0 then
// PostMessage(ExeHandle,WM_CLOSE,0,0);
end;

end.
=============================================================
你在listview中显示的是进程id,而你用findwindow,当然不行了。如果你打开计算器,然后

ExeHandle:=Findwindow(nil,pchar('计算器'));
if ExeHandle<>0 then
PostMessage(ExeHandle,WM_CLOSE,0,0);
就可以关闭计算器。


来自:hnzgf, 时间:2001-12-19 21:15:00, ID:798844
procedure TForm1.FormCreate(Sender: TObject);
var
p : pProcessInfo;
ContinueLoop:BOOL;
ListItem: TListItem;
FSnapshotHandle:THandle;
FProcessEntry32:TProcessEntry32;
i:integer;
begin

FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do begin
New(p);
p.ExeFile := FProcessEntry32.szExeFile;
p.ProcessID := FProcessEntry32.th32ProcessID;
ListItem := listview1.Items.Add;
//ListItem.Caption := Format('%d',[p.ProcessID]);
ListItem.Caption := Format('%s',[p.ExeFile]);
//ListItem.SubItems.Add(Format('%s',[p.ExeFile]));

ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;
==================================================================================
杀掉一个进程
用CB测试(Delphi类似)
HWND HF;
HF=FindWindow(NULL,"1.txt - 记事本"); //找到句柄
if (HF)
PostMessage(HF,WM_QUIT,NULL,NULL);
 
procedure TForm1.Button1Click(Sender: TObject);
var
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
ProgramName: String;
begin
ProgramName := 'calc.exe';
FillChar(StartInfo,SizeOf(TStartupInfo),#0);
FillChar(ProcInfo,SizeOf(TProcessInformation),#0);
StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := CreateProcess(nil,
PChar(ProgramName), nil, nil,
False,
CREATE_NEW_PROCESS_GROUP +
NORMAL_PRIORITY_CLASS,
nil, nil, StartInfo, ProcInfo);//获取进程ID
Sleep(1000);
if CreateOK then
TerminateProcess(ProcInfo.hProcess, 0);
end;
=========================================================================
 
用FindWindow得到窗口句柄,再GetWindowThreadProcessId()得到进程id,
用OpenProcess得到进程句柄,再ExitProcess();
或者直接给窗口句柄发送一个WM_CLOSE消息。SendMessage(FindWindow(NULL,"记事本"),
WM_CLOSE,0,0);
=========================================================================
可以通过进程句柄(process handle)来查看进程(程序)是否结束。为了得到进程句柄,
有两个Win32 API函数可以利用:ShellExecuteEx 或者CreateProces。解决这个问题最简
单的方法是,使用ShellExecuteEx启动一个外部程序,然后使用WaitForSingleObject管理
这个外部程序的进程句柄。
var Id: DWORD;//存放ProcessId的变量
GetWindowThreadProcessId(hwnd, @Id);//hwnd是你得到的窗口句柄

先用OpenProcess获取进程ID,然后用TermiateProcess终止即可

 
怎么得到指定窗口的进程ID啊
var
ProcessId: THandle;
ThreadId: THandle;
begin
ThreadId := GetWindowThreadProcessId(您感兴趣的form的Handle, @ProcessId);
// ProcessId就是您要的进程的Id, ThreadId是这个form所在的线程的Id
end;

测试一个字符串中有没有指定的子串,function pos(substr, sourcestr: string): Integer;
=============================================================
下面这段程序,先得到一个窗口的句柄,再得到进程ID,再得到进程句柄,再终止进程,
但13行返回的为0,为什么?(uses TlHelp32)
98&2000都一样.

1procedure TForm1.Button1Click(Sender: TObject);
2var
3 aHwnd: HWND;
4 aProcID: DWORD;
5 aProcHandle: DWORD;
6begin
7 aHwnd := FindWindow(nil, 'WindowToBeClosed');
8 if aHwnd = 0 then
9 Exit;
10 aProcID := GetWindowThreadProcessId(aHwnd);
11 if aProcID = 0 then
12 Exit;
13 aProcHandle := OpenProcess(PROCESS_TERMINATE, False, aProcID);
14 if aProcHandle = 0 then
15 Exit;
16 TerminateProcess(aProcHandle, 0);
17end;

 
下面是我写的一段源代码,只要你把你想要终止的程序名(包括路径)写入
D:/Program Files/text1.txt这个文件中(注意每行写一个程序名).那么这个
程序无法运行下去.程序里有详细的注释.祝你好运!
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,tlhelp32,stdCtrls, ExtCtrls;//注意加上tlhelp32这个单元;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
Timer1: TTimer;
ListBox2: TListBox;
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
procedure processlist(var prolist:tlist);//自定义函数列举所有的进程;
procedure exitcode ;//自定义函数终止进程;
{ Private declarations }
public
{ Public declarations }
end;
type tproinfo=record
filename:string;
proid:dword;
end;proinfo=^tproinfo;//自定义记录用来记录进程的文件名和ID;

var
Form1: TForm1;
curr:tlist;
temp,b,a1:integer;
implementation

{$R *.DFM}


procedure TForm1.processlist(var prolist: tlist);
var p:proinfo;
ok:bool;
prolisthandle:thandle;
prostruct:tprocessentry32; //记录进程的数据结构;
begin
prolist:=tlist.Create ;
prolist.Clear ;
prolisthandle:=createtoolhelp32snapshot(th32cs_snapprocess,0);
prostruct.dwSize :=sizeof(prostruct);
ok:=process32first(prolisthandle,prostruct);//发现第一个进程;
while integer(ok)<>0 do
begin
new(p);
p.filename :=prostruct.szExeFile ;
p.proid :=prostruct.th32ProcessID ;
prolist.Add (p);
ok:=process32next(prolisthandle,prostruct);//发现下一个进程;
end;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
a:string;
f:textfile;
begin
listbox1.Clear;
listbox2.Clear;
if fileexists('D:/Program Files/text1.txt') then
begin //该文件记录你所想禁止运行的程序的路径;
assignfile(f,'D:/Program Files/text1.txt');
reset(f);
while not eof(f) do
begin
readln(f,a);
a:=uppercase(a); //转化成大写字母;
listbox2.Items.Add (a); //记录所有被禁止运行程序的路径;
end;
closefile(f)
end
else application.Terminate ;

end;


procedure Tform1.exitcode;
var h:thandle;
a:dword;
p:proinfo;

begin
begin
p:=curr.items; //指向禁止运行的进程的数据结构;
h:=openprocess(process_all_access,true,p.proid);
getexitcodeprocess(h,a); //得到进程退出代码;
terminateprocess(h,a) ; //终止进程
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i:integer;
p:proinfo;
begin
listbox1.Clear ;
processlist(curr); //调用进程列举的函数;
for i:=0 to curr.Count-1 do
begin
new(p);
p:=curr.Items;
listbox1.Items.Add(p.filename); //记录所有的进程的路径;
end; //listbox2是记录所有禁止运行的程序的路径;
for i:=0 to listbox2.Items.Count-1 do
if (listbox1.Items.IndexOf(listbox2.Items.Strings)>=0) then
begin
b:=listbox1.Items.IndexOf(listbox2.Items.Strings);
exitcode;//调用终止进程的函数;
end;
end;
end.
 
想通过循环找出已运行的“计算器”程序,并关闭其进程,unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,TLHelp32, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

type TProcessInfo = Record
ExeFile : String;
ProcessID : DWORD;
end;
pProcessInfo = ^TProcessInfo;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
p: pProcessInfo;
ContinueLoop: BOOL;
FSnapshotHandle, hProcess: THandle;
FProcessEntry32: TProcessEntry32;
n: integer;
begin
n:=1;
New(p);
FSnapshotHandle:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
FProcessEntry32.dwSize:=Sizeof(FProcessEntry32);
ContinueLoop:=Process32First(FSnapshotHandle,FProcessEntry32);
while integer(ContinueLoop)<>0 do
begin
p.ExeFile:= FProcessEntry32.szExeFile;
ListBox1.Items.Add(inttostr(n)+':'+inttostr
(FProcessEntry32. th32ProcessID)+' * '+p.ExeFile);
inc(n);
if p.ExeFile='C:/WINDOWS/CALC.EXE' then
begin
hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE,
FProcessEntry32. th32ProcessID);
TerminateProcess(hProcess,0);
end;
ContinueLoop:=Process32Next(FSnapshotHandle,FProcessEntry32);
end;
end;

end.

为了阅读,加了几个回车,请你调试时删掉。主要的改动只有一处: hProcess;
不过我还是倾向于geshengping的方法(9x, NT都能用),而前者只有9x支持。

 
后退
顶部