Текущий архив: 2004.05.30;
Скачать: CL | DM;
Внизвызов функции в потоке Найти похожие ветки
← →
freeman82 (2004-04-21 14:38) [0]Здравствуйте!Помогите пожалуйста разобраться.
Есть код
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 не найден сетевой путь) или если указан не существующий компьютер.
Спасибо за ответы!
← →
Reindeer Moss Eater © (2004-04-21 14:41) [1]Отдели мух от котлет.
Отладь вызов с одним хостом в основном потоке.
Отладь вызов со списком хостов в основном потоке
Перенеси функционал во вторичный поток
← →
Reindeer Moss Eater © (2004-04-21 14:44) [2]procedure TShutdown.Execute;
begin
b:=shutdown(name1,message,delay,restart,closeall);
synchronize(form1.showmess );
end;
end.
Откуда берутся значения переменных выделенные жирным?
← →
freeman82 (2004-04-21 14:48) [3]Они объявленны глобальными в umain,тамже и инициализируются.Если в списке один комп то все работает.
← →
Reindeer Moss Eater © (2004-04-21 14:49) [4]В каком нафик списке, если все это - скалярные переменные.
← →
Reindeer Moss Eater © (2004-04-21 14:51) [5]И при чем здесь вообще какой-то там спискок, если все потоки работают с одними и теми же глобальными переменными?
← →
freeman82 (2004-04-21 14:54) [6]for i:=0 to checklistbox1.Items.Count-1 do
name1:=form1.checklistbox1.Items.Strings[i];
← →
Reindeer Moss Eater © (2004-04-21 14:55) [7]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 15:03) [8]подскажи пожалуйста выход из этой ситуации.
← →
Reindeer Moss Eater © (2004-04-21 15:05) [9]Из этой ситуации можно выйти сообщая каждому экземпляру потока конкретное имя хоста которое он должен погасить.
← →
freeman82 (2004-04-21 15:08) [10]А как это сделать.Мы же сначала присваиваем переменной name1 значение,а потом вызываем конструктор.(или я что-то не понимаю помоги разобраться)
← →
Smithson © (2004-04-21 15:10) [11]Передавай в конструктор потока нужное имя, запоминай его в локальной переменной потока и с ним потом работай.
Пока плаваешь в этих вопросах, просто запомни - нельзя использовать в потоке перемнные, объявленные не в нем!
← →
Reindeer Moss Eater © (2004-04-21 15:11) [12]...
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;
← →
Reindeer Moss Eater © (2004-04-21 15:15) [13]просто запомни - нельзя использовать в потоке перемнные, объявленные не в нем!
Можно. Нет такого запрета.
← →
freeman82 (2004-04-21 15:50) [14]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:54) [15]Наврал я.
Убери override
← →
freeman82 (2004-04-21 16:11) [16]еще проблемка
inherited(false);
ошибка Incompatible types
← →
Reindeer Moss Eater © (2004-04-21 16:30) [17]У меня написано
inherited Create(...)
← →
freeman82 (2004-04-21 16:48) [18]все работает. большое спасибо за помощь!
Страницы: 1 вся ветка
Текущий архив: 2004.05.30;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.064 c