![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
вызов функции в потоке
freeman82 © (2004-04-21 14:38:00)Здравствуйте!Помогите пожалуйста разобраться.
Есть код
unit uThread;
interface
uses
Classes,Windows,Dialogs,sysutils;
type
TShutdown = class(TThread)
private
{ Private declarations }
protected
function shutdown(name1,message:string;delay:integer;restart,closeall:boolean):integer;
procedure Execute; override;
public
b:integer;
end;
implementation
uses umain;
function Tshutdown.shutdown(name1,message:string;delay:integer;restart,closeall:boolean):integer;
var
tkp,tkpo:TTokenPrivileges;
zero:DWORD;
hToken:Thandle;
begin
Zero:=0;
if not OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)then
begin
messagebox(0,'Exit error','OpenProcessToken fail',MB_OK);
exit;
end;
if not LookupPrivilegeValue(nil,'SeShutdownPrivilege',tkp.Privileges[0].Luid) then
begin
messagebox(0,'Exit error','LookupPrivilegeValue fail',MB_OK);
exit;
end;
tkp.PrivilegeCount :=1;
tkp.Privileges[0].Attributes :=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, tkp, SizeOf(TtokenPrivileges),tkpo,Zero);
If Boolean(GetLastError()) then
begin
messagebox(0,'Exit error','AdjustTokenPrivileges fail',MB_OK);
exit;
end;
initiateSystemShutdown (PChar(name1),PChar(Message),delay,restart,closeall);
result:=GetLastError();
end;
procedure TShutdown.Execute;
begin
b:=shutdown(name1,message,delay,restart,closeall);
synchronize(form1.showmess );
end;
end.
В основном модуле
uMain
.....
....
procedure tform1.showmess;
begin
if proc1.b =997 then Rxrichedit1.lines.Add('--'+'успешно')
else Rxrichedit1.lines.Add('--'+syserrormessage(proc1.b ));
end;
.....
.....
for i:=0 to checklistbox1.Items.Count-1 do
if checklistbox1.Checked[i] then
begin
name1:=form1.checklistbox1.Items.Strings[i];
proc1:=tshutdown.Create(false);
.......
.......
Проблема в следующем, если в списке компов указано более 1 компьютера программа не работает(syserrormessage не найден сетевой путь) или если указан не существующий компьютер.
Спасибо за ответы!
freeman82 (2004-04-21 16:48:00) [1]все работает. большое спасибо за помощь!
Reindeer Moss Eater (2004-04-21 16:30:00) [2]У меня написано
inherited Create(...)
freeman82 (2004-04-21 16:11:00) [3]еще проблемка
inherited(false);
ошибка Incompatible types
Reindeer Moss Eater (2004-04-21 15:54:00) [4]Наврал я.
Убери override
freeman82 (2004-04-21 15:50:00) [5]constructor CreateIt(const AName:string; ADelay : integer; ARestart, ACloseall : boolean); override;
Пишет метод CreateIt не обнаружен в базовом классе
а если
constructor Create(const AName:string; ADelay : integer; ARestart, ACloseall : boolean); override;
не может быть переопределен статический метод.
Reindeer Moss Eater (2004-04-21 15:15:00) [6]просто запомни - нельзя использовать в потоке перемнные, объявленные не в нем!
Можно. Нет такого запрета.
Reindeer Moss Eater (2004-04-21 15:11:00) [7]...
fName:string;
...
fCloseAll:boolean;
public
constructor CreateIt(const AName:string; ADelay : integer; ARestart, ACloseall : boolean); override;
...
end;
implementation
constructor TShutdown.CreateIt(const AName:string; ADelay : integer; ARestart, ACloseall : boolean);
begin
inherited Create(True);
fName:=AName;
fDelay:=ADelay;
fRestart:=ARestart;
fCloseAll:=ACloseAll;
end;
Smithson (2004-04-21 15:10:00) [8]Передавай в конструктор потока нужное имя, запоминай его в локальнойпеременной потока и с ним потом работай.
Пока плаваешь в этих вопросах, просто запомни - нельзя использовать в потоке перемнные, объявленные не в нем!
freeman82 (2004-04-21 15:08:00) [9]А как это сделать.Мы же сначала присваиваем переменной name1 значение,а потом вызываем конструктор.(или я что-то не понимаю помоги разобраться)
Reindeer Moss Eater (2004-04-21 15:05:00) [10]Из этой ситуации можно выйти сообщая каждому экземпляру потока конкретное имя хоста которое он должен погасить.
freeman82 (2004-04-21 15:03:00) [11]подскажи пожалуйста выход из этой ситуации.
Reindeer Moss Eater (2004-04-21 14:55:00) [12]for i:=0 to checklistbox1.Items.Count-1 do
if checklistbox1.Checked[i] then
begin
name1:=form1.checklistbox1.Items.Strings[i];
proc1:=tshutdown.Create(false);
.......
Откуда святая уверенность в том, что когда дело доходит до Execute очередного потока, в переменной name1 чудесным образом оказывается именно то имя, какое нужно этому экземпляру потока.
Они ВСЕ у тебя работают с одним и тем же именем.
Поэтому второй поток и все последующие обламываются перезагрузить хост, который уже ушел в перезагрузку.
freeman82 (2004-04-21 14:54:00) [13]for i:=0 to checklistbox1.Items.Count-1 do
name1:=form1.checklistbox1.Items.Strings[i];
Reindeer Moss Eater (2004-04-21 14:51:00) [14]И при чем здесь вообще какой-то там спискок, если все потоки работают с одними и теми же глобальными переменными?
Reindeer Moss Eater (2004-04-21 14:49:00) [15]В каком нафик списке, если все это - скалярные переменные.
freeman82 (2004-04-21 14:48:00) [16]Они объявленны глобальными в umain,тамже и инициализируются.Если в списке один комп то все работает.
Reindeer Moss Eater (2004-04-21 14:44:00) [17]procedure TShutdown.Execute;
begin
b:=shutdown( name1,message,delay,restart,closeall);
synchronize(form1.showmess );
end;
end.
Откуда берутся значения переменных выделенные жирным?
Reindeer Moss Eater (2004-04-21 14:41:00) [18]Отдели мух от котлет.
Отладь вызов с одним хостом в основном потоке.
Отладь вызов со списком хостов в основном потоке
Перенеси функционал во вторичный поток