Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

вызов функции в потоке


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]

Отдели мух от котлет.
Отладь вызов с одним хостом в основном потоке.
Отладь вызов со списком хостов в основном потоке
Перенеси функционал во вторичный поток


Наверх

Титульная страница Поиск, карта сайта Написать письмо