while 循环为什么不执行了?(看起来没问题,似易实难)!!Delphi 本身的问题? ( 积分: 200 )

  • 主题发起人 主题发起人 陆波
  • 开始时间 开始时间

陆波

Unregistered / Unconfirmed
GUEST, unregistred user!
问题如下,执行以下代码取进程列表!为什么不执行以下代码中的while 循环了!(其他代码能执行)也就是说runfile1中只有runfile1.Add('所有运行进程如下:') ;这句加进去的字符!!

//====================测试了许久,发现问题在下面,错在哪了!!!为什么得不到进程列表?==
//========
use
Tlhelp32;
//========


var
mystream: TMemorystream ;
runfile1:TStringList;
lppe: TProcessEntry32;
found : boolean;
Hand1 : THandle;
begin
runfile1:=TStringList.Create;
mystream := TMemoryStream.Create;
Hand1 := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
try
// 列出所有进程
runfile1.Add('所有运行进程如下:') ;
found := Process32First(Hand1,lppe);
while found do
begin
runfile1.Add(inttostr(lppe.th32ProcessID)+' '+StrPas(lppe.szExeFile));
found := Process32Next(Hand1,lppe);
end;
CloseHandle(Hand1);
// 列出所有进程
runfile1.SaveToStream(mystream)
// memo1.Lines.Add('已取得进程==='+runfile1.Strings[0]) ;
mystream.Position:=0;
listbox1.Items.LoadFromStream(mystream);
finally
runfile1.Free;
mystream .Free ;
end;
end;
//======================
///只要有人告诉我什么情况下会导致以上部分代码中的WHILE 语句不再执行,即给分!上帝啊,主啊,阿门,高手啊,谁可帮我????
 
你想取得进程的话
Hand1 := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
应该改成
Hand1 := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 
to cocoa2135
先谢了!在XP下好像没什么区别啊!试了,我查下SDK,明白区别了!但我提出的问题没解决啊!
 
memo1.Lines.Add('已取得进程==='+runfile1.Strings[0]) ;
是不是因为这句啊
显示的问题
可别是这种错误啊呵呵
 
请各位大侠帮忙!!
 
begin
hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hSnapshot <> Cardinal(-1) then
try
[red]prcEntry32.dwSize := Sizeof(prcEntry32);[/red]
ContinueLoop := Process32First(hSnapshot, prcEntry32);
while ContinueLoop do
begin
with prcEntry32 do
begin
prcExeFile := StrPas(szExeFile);
//.............
end;
AList.AddObject(IntToStr(prcEntry32.th32ProcessID),
TProcBaseInfoObj.Create(prcEntry32));
ContinueLoop := Process32Next(hSnapshot, prcEntry32);
end;
finally
CloseHandle(hSnapshot);
end;
end;
以上是我的代码,没有任何问题,拿来和你的代码比较后发现,你漏了一个很重要的句子,红色部分.
 
不是,我发现是这一句的问题:
mystream .Free ;
没这一名竟然没问题,有这一句竟是不行!!为什么?你试下
 
如果是mystream.free的问题的话,估计是创建对象失败,或者其他原因造成的,以至于你释放对象的时候,实际上是在释放没有创建成功的对象,可能出现未知问题

建议你读读这个帖子中我对帖主的回答:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3673054
 
对了,最后还是要强调,这句
prcEntry32.dwSize := Sizeof(prcEntry32);
绝对是必须的,你看看MSDN就知道了.如果你不给这个赋初值,可能根本就找不到任何Process!自然循环不会执行了
 
那么以下代码怎样才行???为什么我 mystream.Free;就不行,我什么也没做啊!!(当然不是测试时要做事的!)关“while found do” 什么事?
var lppe: TProcessEntry32

found : boolean

Hand : THandle;
mystream: TMemorystream ;
runfile1:TStringList;
begin
runfile1:=TStringList.Create;
mystream := TMemoryStream.Create;
Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
// lppe.dwSize := Sizeof(lppe.dwSize);
try
found := Process32First(Hand,lppe);
while found do
begin
ListBox1.Items.Add(StrPas(lppe.szExeFile));//列出所有进程。
found := Process32Next(Hand,lppe)

end;
CloseHandle(Hand);
finally
runfile1.Free;
//mystream.Free;
end;

end;
 
lppe.dwSize := Sizeof(lppe.dwSize);//这句你写错了


lppe.dwSize := Sizeof(lppe);//这才是对的!
 
你如果不指定dwSize为结构长度,Process32First或者Process32Next函数在填充lppe结构的时候,可能超出结构所在堆栈的内容(比如,刚好写到mystream这个变量所在的堆栈空间上),这个时候,Process32First或者Process32Next返回了False,不再执行循环,但是执行到下面mystream.free的时候,由于mystream的值已经被Process32First或者Process32Next给改了,指向了未知地址,当你执行free的时候,自然会出错!
 
是写错了,但没这也行!加了mystream.Free;就什么也不行,你用一个Buttonclick试下便知
 
呵呵,是我错了,mystream.Free,没问题!!是lppe.dwSize := 这句的错,谢!
 
那就给分吧
 
唉,现在好多人提问不给分.....郁闷.
 
呵呵,高手就是手!
 
不是啦,刚才我改代码去了!
 
后退
顶部