Avatar billede kennethv Nybegynder
23. oktober 2014 - 14:08 Der er 61 kommentarer og
1 løsning

Animation stopper

Hejsa.

Ja, jeg ved ikke lige hvordan jeg skal forklare mit problem.

Jeg har lavet et program som skal slette alle unødvendige mapper på vores netværk. Programmet starter op uden en mainform. Jeg bruger så en komponent "cooltrayicon" til at vise at der så sker noget, men animationen stopper når programmet er ved at slette mapperne. Hvordan kan jeg få animationen til at kører uden at den stopper?

Dette er funktionen der sletter. Jeg kan ikke selv tage kredit for den, da jeg ikke selv har lavet den.

Function DelTree(DirName : string): Boolean;
var
  SHFileOpStruct : TSHFileOpStruct;
  DirBuf : array [0..1024] of char;
begin
  try
    Fillchar(SHFileOpStruct,Sizeof(SHFileOpStruct),0) ;
    FillChar(DirBuf, Sizeof(DirBuf), 0 ) ;
    StrPCopy(DirBuf, DirName) ;
    with SHFileOpStruct do begin
      Wnd := 0;
      pFrom := @DirBuf;
      wFunc := FO_DELETE;
      fFlags := FOF_ALLOWUNDO;
      fFlags := fFlags or FOF_NOCONFIRMATION;
      fFlags := fFlags or FOF_SILENT;
    end;
    Result := (SHFileOperation(SHFileOpStruct) = 0) ;
  except
  Result := False;
end;
end;

Jeg ved at komponenten har en CoolTrayIcon1.focus, men vil det hjælpe på noget? Jeg tænker på at det er vel denne:
    Result := (SHFileOperation(SHFileOpStruct) = 0) ;

der ligesom klare sagen, ikk?
Avatar billede hugopedersen Nybegynder
23. oktober 2014 - 14:58 #1
Det er et ikke ukendt problem med CoolTrayIcon
Jeg har selv brugt det og jeg har til dels løst problemet ved at indsætte et passende antal Application.ProcessMessages; i min kode

Hvor og hvor mange er der kun eksperimenter der kan vise.

Det er ikke den mest elegante men det ser bedre ud end min globus står stille i længere perioder :-)
Avatar billede kennethv Nybegynder
23. oktober 2014 - 15:09 #2
Ja, Application.ProcessMessages; bruger jeg osse flittigt, men det står stadig stille når den er igang med at slette mapperne.
Avatar billede hugopedersen Nybegynder
23. oktober 2014 - 15:27 #3
Det tror jeg helt sikkert du har ret i og det er nok fordi den overtager for meget af styringen og ikke 'tillader' den kaldende application at opdatere = du kan nok ikke gøre noget ved det
Avatar billede kennethv Nybegynder
23. oktober 2014 - 15:42 #4
Ok.

Øv.

Du må ligge et svar.
Avatar billede kroning Nybegynder
23. oktober 2014 - 18:37 #5
Det kan vel let ordnet ved at slette filerne i en tråd
Avatar billede kennethv Nybegynder
24. oktober 2014 - 10:28 #6
Ved desværre ikke hvordan man laver den slags. :(
Avatar billede kroning Nybegynder
24. oktober 2014 - 11:30 #7
Jeg laver lige et eks. senere i dag.
Avatar billede kroning Nybegynder
24. oktober 2014 - 11:32 #8
Hvordan laver du animationen i CoolTray
Avatar billede hugopedersen Nybegynder
24. oktober 2014 - 12:18 #9
Jeg mener du skal vente på kronings forslag og give ham point
Avatar billede kroning Nybegynder
24. oktober 2014 - 16:59 #10
unit Unit1;

interface

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

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

  TDelTreeThread = class(TThread)
  private
    { Private declarations }
    pDirName : string;

    Function DelTree(DirName : string): Boolean;
  protected
    procedure Execute; override;
  public
    ErrorTekst : string;
    constructor Create(DirName : string);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TDelTreeThread }
constructor TDelTreeThread.Create(DirName : string);
begin
    inherited Create(False);
    FreeOnTerminate:=true;
  pDirName:=DirName;
  ErrorTekst:='';
end;

Function TDelTreeThread.DelTree(DirName : string): Boolean;
var
  SHFileOpStruct : TSHFileOpStruct;
  DirBuf : array [0..1024] of char;
begin
  try
    Fillchar(SHFileOpStruct,Sizeof(SHFileOpStruct),0) ;
    FillChar(DirBuf, Sizeof(DirBuf), 0 ) ;
    StrPCopy(DirBuf, DirName) ;
    with SHFileOpStruct do begin
      Wnd := 0;
      pFrom := @DirBuf;
      wFunc := FO_DELETE;
      fFlags := FOF_ALLOWUNDO;
      fFlags := fFlags or FOF_NOCONFIRMATION;
      fFlags := fFlags or FOF_SILENT;
    end;
    Result := (SHFileOperation(SHFileOpStruct) = 0) ;
  except
    Result := False;
  end;
end;

procedure TDelTreeThread.Execute;
begin
  try
    if not DelTree(pDirName) then
      ErrorTekst:='Der opstod en fejl.';
    except
    on E:Exception do
    begin
      ErrorTekst:=E.Message;
    end;
  end;
end;

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  beep; //blot til test

  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
end;
{ TDelTreeThread SLUT }


procedure TForm1.Button1Click(Sender: TObject);
begin
  TDelTreeThread.Create('c:\HK\Test').OnTerminate:=DelTreeOnTerminate;
end;

end.
Avatar billede kroning Nybegynder
24. oktober 2014 - 17:04 #11
Husk du må ikke direkte kalde nogen funktioner i din hoved tråd (her Form1) fra TDelTreeThread tråden.

Du kan uden problemer starte flere tråde af gangen, men hvis du starter mange tråde og der skal slettes mange filer så vil Windows måske blive lidt sløv.
Avatar billede kennethv Nybegynder
27. oktober 2014 - 11:02 #12
Mange tak.
Jeg har dog lige et lille spørgsmål som er, at jeg i min kode gør dette:

                      if sDatafolder = '' then
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name + '*.*'); //
                      end
                      else
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name + '*.*'); // + IncludeTrailingPathDelimiter('Log')
                      end;

Kan jeg med det du har lavet gør det samme?
Avatar billede kennethv Nybegynder
27. oktober 2014 - 11:03 #13
Det er en logfil som fortæller mig om det er gået godt eller ej på stien.
Avatar billede kroning Nybegynder
27. oktober 2014 - 23:08 #14
Ja der skal ændres lidt på den fremgangsmåde.

Hvor mange mapper skal der slettes, hvis der kun er f.eks. 3 så kan man nok godt starte 3 tråde på samme tid men hvis der er mange så er det nok bedst at vente med næste tråd til den første er færdig.
Avatar billede kennethv Nybegynder
28. oktober 2014 - 09:48 #15
Uha. det kan være mange. Jeg fik lavet et lille test og der var ca. 2000 mapper der skal slettes.

Så det er nok bedst at få afsluttet en tråd først inden jeg starter en ny.
Avatar billede kroning Nybegynder
28. oktober 2014 - 10:55 #16
Og de ligger så man ikke bare kan slette den mappe de ligger i og dermed slette dem alle på een gang.
Det har du selvfølgelig tænkt på men jeg er nød til at spørge :-)
Avatar billede kennethv Nybegynder
28. oktober 2014 - 11:23 #17
Hver af de mapper ligger i struktur som dette:

Username
  CDATABUP
    FolderDerSkalSlettes

Der kan godt være flere foldere i samme folder som "FolderDerSkalSlettes"
Avatar billede kroning Nybegynder
28. oktober 2014 - 11:51 #18
En måde kunne være først at gemme alle mapper der skal slettes i en TStringList,
f.eks.
DelTreeList : TStringList;

Når alle mapper er gemt i DelTreeList startes den første tråd og derefter startes en ny tråd hver gang DelTreeOnTerminate kaldes.

f.eks. (utestet)
procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
  Logfile.Add(DateTimeToStr(Now) + ':  Failed To Delete: ' + (Sender as TDelTreeThread).pDirname);

  end
else
  Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + (Sender as TDelTreeThread).pDirname);

if DelTreeList.count>0 then
begin
TDelTreeThread.Create(DelTreeList[0]).OnTerminate:=DelTreeOnTerminate;
DelTreeList.Delete(0);
end;

end;

Dit program kan dog stadig "hænge" lidt hvis trådene hurtig afsluttes og DelTreeOnTerminate kaldes uden meget tid i mellem.
For helt at komme ud over det problem kan hele listen med mappe navne sendes til tråden således at der kun oprettes een tråd som sletter alle mapper og vender tilbage med en log, men så får man selvfølgelig ikke løbende status vist.
Avatar billede kennethv Nybegynder
28. oktober 2014 - 12:09 #19
Jeg kan godt se hvad du mener, men at gemme alle mapper i en liste, vil det ikke tage noget tid at få det gjort hvis man skal gennemse mere end 5.000 ansatte backupfoldere?
Avatar billede kroning Nybegynder
28. oktober 2014 - 13:03 #20
Jeg ved ikke om det vil tage 10 sekunder eller 5 minutter. Men den funktion der finder alle mapper kan også flytes til tråden så er der ingen ting der hænger i hoved formen. Selvom du flytter det hele til tråden kan du stadig få løbende status vist på din hoved form men som tidligere nævnt må du ikke kalde funktioner i din hoved form direkte fra tråden, kaldet skal pakket ind i en Synchronize, det er meget let at bruge Synchronize, det kræver kun 3 liniers extra kode.

Men det du kan gøre er at flytte den kode der finder alle mapperne ind i trådens Execute funktion.

Skal jeg lavet et eks. ?
Avatar billede kennethv Nybegynder
28. oktober 2014 - 13:18 #21
Det her er koden jeg bruger:

procedure DeleteTempRAW(S1: String);
var
  SearchRec: TSearchRec;
  X: Integer;
  Path: String;
  ListToDelete: TStringList;
begin
  ListToDelete := TStringList.Create;
  Path := ExtractFilePath(S1);
  X := FindFirst(S1, faAnyFile - faDirectory - faVolumeID, SearchRec);
  if X = 0 then
  begin
    while X = 0 do
    begin
      ListToDelete.Add(Path + SearchRec.Name);
      X := FindNext(SearchRec);
    end;
    FindClose(SearchRec);
  end;
  for X := 0 to ListToDelete.Count - 1 do
  begin
    FileSetAttr(ListToDelete[X], 0);
    DeleteFile(ListToDelete[X]);
  end;
  ListToDelete.Free;
end;

procedure TForm1.DeleteDirectory;
var i : integer; SearchRec: TSearchRec;
OwnerList, LogFile, LineList : TStringList;
begin
  try
    LogFile := TStringList.Create;
    for I := 0 to list.Count -1 do
    begin
      LineList := TStringList.Create;
      LineList.Delimiter := ',';
      try
        LineList.DelimitedText := StringReplace(List.Strings[i],' ','_',[rfReplaceAll]);
        sSiteOU := LineList[0] + ',' + LineList[1];
        sUsername := LineList[2];
        sDataFolder := LineList[3];
        sSiteHomePath := LineList[4];
        sMail := LineList[5];
        sManagedBy := StringReplace(LineList[6] + ',' + LineList[7] + ',' + LineList[8] + ',' + LineList[9] + ',' + LineList[10] + ',' + LineList[11] + ',' + LineList[12] + ',' + LineList[13],'_',' ',[rfReplaceAll]);
      finally
        LineList.Free;
      end;
      try
        OwnerList := TStringList.Create;
        try
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Text := 'SELECT CN FROM ' + Quotedstr('LDAP://OU=COMPUTERS,' + sSiteOU + ',OU=company,DC=AD,DC=company,DC=ORG') + ' WHERE ObjectClass=' + Quotedstr('computer') + ' AND managedby=' + Quotedstr(sManagedBy);
          ADOQuery1.Open;
          ADOQuery1.First;
          ADOQuery1.RecordCount;
          while not ADOQuery1.Eof do
          begin
            OwnerList.Add(ADOQuery1.FieldByName('CN').AsString);
            ADOQuery1.Next;
            Application.ProcessMessages;
          end;
        finally
          ADOQuery1.Close;
        end;
        if OwnerList.Count <> 0 then
        begin
          if FindFirst(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + sDataFolder + '\*', faDirectory, SearchRec) = 0 then
          try
            begin
              repeat
                if ((SearchRec.Attr and faDirectory) <> faDirectory) or (SearchRec.Name = '.') or (SearchRec.Name = '..') then
                  continue;
                if pos(searchRec.Name,OwnerList.Text) = 0 then //
                begin
                  if (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'LT',SearchRec.Name) <> 0) or (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'DT',SearchRec.Name) <> 0) then
                  begin
                    if monthsbetween(date,FileDateToDateTime(SearchRec.Time)) > iVal then
                    begin
                      if sDatafolder = '' then
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name  '*.*');                      end
                      else
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name + '*.*');
                      end;
                    end
                    else
                      Logfile.Add(DateTimeToStr(Now) + ': Nothing to do: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name);
                  end;
                end
                else
                  Logfile.Add(DateTimeToStr(Now) + ': Everthing is ok ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername));
                Application.ProcessMessages;
              until findNext(SearchRec) <> 0;
            end;
          finally
            FindClose(SearchRec);
          end;
        end
        else
        begin
          Logfile.Add(DateTimeToStr(Now) + ': No owner: ' + sManagedBy);
        end;
      finally
        FreeAndNil(OwnerList);
      end;
      Application.ProcessMessages;
    end;
  finally
    LogFile.SaveToFile(IncludeTrailingPathDelimiter(getcurrentdir)+datetostr(now)+'.log');
    FreeAndNil(LogFile);
  end;
end;
Avatar billede kroning Nybegynder
28. oktober 2014 - 14:38 #22
Koden virker ikke som den er, der er en del ukendte variabler. Bla. skal du manuelt oprette din TADOQuery i trådens constructor (Create) og alle andre ukendte variabler skal også defineres i tråden.


unit Unit1;

interface

uses
  ActiveX, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, DB, ADODB;

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

  TDelTreeThread = class(TThread)
  private
    { Private declarations }
        ADOConnection: TADOConnection;
      ADOQuery1: TADOQuery;

    Function DelTree(DirName : string): Boolean;
    procedure DeleteTempRAW(S1: String);
    procedure DeleteDirectory;
  protected
    procedure Execute; override;
  public
    ErrorTekst : string;
    constructor Create;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TDelTreeThread }
constructor TDelTreeThread.Create;
begin
    inherited Create(False);
    FreeOnTerminate:=true;
  ErrorTekst:='';

  ADOConnection:=TADOConnection.Create(nil);
  ADOConnection.LoginPrompt:=false;
  ADOConnection.ConnectionString:='din connection string';
    ADOConnection.CursorLocation:=clUseServer;

  ADOQuery1:=TADOQuery.Create(nil);
  ADOQuery1.AutoCalcFields:=false;
  ADOQuery1.CursorLocation:=clUseServer;
  ADOQuery1.Connection:=ADOConnection;
  ADOQuery1.CursorType:=ctOpenForwardOnly;
  ADOQuery1.EnableBCD:=false;
  ADOQuery1.ParamCheck:=false;
end;

procedure TDelTreeThread.DeleteTempRAW(S1: String);
var
  SearchRec: TSearchRec;
  X: Integer;
  Path: String;
  ListToDelete: TStringList;
begin
  ListToDelete := TStringList.Create;
  Path := ExtractFilePath(S1);
  X := FindFirst(S1, faAnyFile - faDirectory - faVolumeID, SearchRec);
  if X = 0 then
  begin
    while X = 0 do
    begin
      ListToDelete.Add(Path + SearchRec.Name);
      X := FindNext(SearchRec);
    end;
    FindClose(SearchRec);
  end;
  for X := 0 to ListToDelete.Count - 1 do
  begin
    FileSetAttr(ListToDelete[X], 0);
    DeleteFile(ListToDelete[X]);
  end;
  ListToDelete.Free;
end;

Function TDelTreeThread.DelTree(DirName : string): Boolean;
var
  SHFileOpStruct : TSHFileOpStruct;
  DirBuf : array [0..1024] of char;
begin
  try
    Fillchar(SHFileOpStruct,Sizeof(SHFileOpStruct),0) ;
    FillChar(DirBuf, Sizeof(DirBuf), 0 ) ;
    StrPCopy(DirBuf, DirName) ;
    with SHFileOpStruct do begin
      Wnd := 0;
      pFrom := @DirBuf;
      wFunc := FO_DELETE;
      fFlags := FOF_ALLOWUNDO;
      fFlags := fFlags or FOF_NOCONFIRMATION;
      fFlags := fFlags or FOF_SILENT;
    end;
    Result := (SHFileOperation(SHFileOpStruct) = 0) ;
  except
    Result := False;
  end;
end;

procedure TDelTreeThread.DeleteDirectory;
var i : integer; SearchRec: TSearchRec;
OwnerList, LogFile, LineList : TStringList;
begin
  try
    LogFile := TStringList.Create;
    for I := 0 to list.Count -1 do
    begin
      LineList := TStringList.Create;
      LineList.Delimiter := ',';
      try
        LineList.DelimitedText := StringReplace(List.Strings[i],' ','_',[rfReplaceAll]);
        sSiteOU := LineList[0] + ',' + LineList[1];
        sUsername := LineList[2];
        sDataFolder := LineList[3];
        sSiteHomePath := LineList[4];
        sMail := LineList[5];
        sManagedBy := StringReplace(LineList[6] + ',' + LineList[7] + ',' + LineList[8] + ',' + LineList[9] + ',' + LineList[10] + ',' + LineList[11] + ',' + LineList[12] + ',' + LineList[13],'_',' ',[rfReplaceAll]);
      finally
        LineList.Free;
      end;
      try
        OwnerList := TStringList.Create;
        try
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Text := 'SELECT CN FROM ' + Quotedstr('LDAP://OU=COMPUTERS,' + sSiteOU + ',OU=company,DC=AD,DC=company,DC=ORG') + ' WHERE ObjectClass=' + Quotedstr('computer') + ' AND managedby=' + Quotedstr(sManagedBy);
          ADOQuery1.Open;
          ADOQuery1.First;
          ADOQuery1.RecordCount;
          while not ADOQuery1.Eof do
          begin
            OwnerList.Add(ADOQuery1.FieldByName('CN').AsString);
            ADOQuery1.Next;
            Application.ProcessMessages;
          end;
        finally
          ADOQuery1.Close;
        end;
        if OwnerList.Count <> 0 then
        begin
          if FindFirst(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + sDataFolder + '\*', faDirectory, SearchRec) = 0 then
          try
            begin
              repeat
                if ((SearchRec.Attr and faDirectory) <> faDirectory) or (SearchRec.Name = '.') or (SearchRec.Name = '..') then
                  continue;
                if pos(searchRec.Name,OwnerList.Text) = 0 then //
                begin
                  if (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'LT',SearchRec.Name) <> 0) or (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'DT',SearchRec.Name) <> 0) then
                  begin
                    if monthsbetween(date,FileDateToDateTime(SearchRec.Time)) > iVal then
                    begin
                      if sDatafolder = '' then
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name  '*.*');                      end
                      else
                      begin
                        if DelTree(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name) then
                          Logfile.Add(DateTimeToStr(Now) + ': Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name)
                        else
                          Logfile.Add(DateTimeToStr(Now) + ': Failed To Delete: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name);
                        DeleteTempRAW(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + IncludeTrailingPathDelimiter('Log') + SearchRec.Name + '*.*');
                      end;
                    end
                    else
                      Logfile.Add(DateTimeToStr(Now) + ': Nothing to do: ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name);
                  end;
                end
                else
                  Logfile.Add(DateTimeToStr(Now) + ': Everthing is ok ' + IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername));
                Application.ProcessMessages;
              until findNext(SearchRec) <> 0;
            end;
          finally
            FindClose(SearchRec);
          end;
        end
        else
        begin
          Logfile.Add(DateTimeToStr(Now) + ': No owner: ' + sManagedBy);
        end;
      finally
        FreeAndNil(OwnerList);
      end;
      Application.ProcessMessages;
    end;
  finally
    LogFile.SaveToFile(IncludeTrailingPathDelimiter(getcurrentdir)+datetostr(now)+'.log');
    FreeAndNil(LogFile);
  end;
end;

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  try
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst:=E.Message;
    end;
  end;
  CoUninitialize;
end;

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
end;
{ TDelTreeThread SLUT }


procedure TForm1.Button1Click(Sender: TObject);
begin
  TDelTreeThread.Create.OnTerminate:=DelTreeOnTerminate;
end;

end.
Avatar billede kroning Nybegynder
28. oktober 2014 - 14:42 #23
hov, glemte noget. Alle dine "Application.ProcessMessages;" skal fjernes i koden.
Avatar billede kennethv Nybegynder
29. oktober 2014 - 09:17 #24
Hold'a op. :)

Jeg får hurtigst muligt kigget på det her.
Avatar billede kennethv Nybegynder
29. oktober 2014 - 15:56 #25
Jeg har ikke lige fået testet det, men jeg har dog et lille spørgsmål som dukker op.

Jeg kan se at procedure DeleteDirectory; er blevet flyttet fra standard {Private declarations} til thread {Private declarations}

skal jeg så osse have disse:
    procedure GetTheUsers;
    procedure GetTheConsultants;
    procedure ReadTheIniFile;

da de er i standard {Private declarations}?

GetTheUsers og GetTheConsultants bliver kaldt fra ReadTheIniFile som så igen bliver kaldt fra min OnCreate.

type
  TForm1 = class(TForm)
    ImageList1: TImageList;
    CoolTrayIcon1: TCoolTrayIcon;
    ADOQuery1: TADOQuery;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    iVal : integer;
    List : TStringList;
    sSiteOU, sDataFolder, sSiteHomePath, sUsername, sMail, sManagedBy : string;
    { Private declarations }
    procedure GetTheUsers;
    procedure GetTheConsultants;
    procedure ReadTheIniFile;
    procedure DeleteDirectory;
  public
    { Public declarations }
  end;

procedure TForm1.ReadTheIniFile;
var myIniFile : TIniFile; Sections : TStringList; i : integer;
begin
  Sections := TStringList.Create;
  myIniFile := TIniFile.Create(ChangeFileExt( Application.Exename,'.ini'));
  myIniFile.ReadSections(Sections);
  try
    for I := 0 to Sections.Count-1 do
    begin
      Application.ProcessMessages;
      if pos('MONTHSBETWEEN',sections.Strings[i]) <> 0 then
      begin
        iVal := myIniFile.ReadInteger('MONTHSBETWEEN','IntVal',6);
      end
      else
      begin
        sSiteOU := 'OU=' + copy(Sections.Strings[i],3,2) + ',' + 'OU=' + copy(Sections.Strings[i],1,2);
        sDataFolder := myIniFile.ReadString(Sections.Strings[i],'BackupFolder','No Value');
        sSiteHomePath := myIniFile.ReadString(Sections.Strings[i],'SiteHomePath','No Value');
        GetTheUsers;
        GetTheConsultants;
      end;
    end;
  finally
    myIniFile.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  List := TStringList.Create;
  ReadTheIniFile;
  DeleteDirectory;
  application.Terminate;
end;
Avatar billede kroning Nybegynder
29. oktober 2014 - 17:25 #26
Du kan flytte den ind i tråden eller du kan give tråden de variabler den skal bruge når du kalder trådens Create.
Hvis du ikke skal bruge ReadTheIniFile andre steder så kan du ligeså godt flytte den ind i tråden, og så skal GetTheUsers og GetTheConsultants også flyttes med.

Husk at du ikke må kalde application.Terminate; før tråden er afsluttet, dvs. du kan kalde application.Terminate; i TForm1.DelTreeOnTerminate
Avatar billede kennethv Nybegynder
31. oktober 2014 - 11:11 #27
Hov du spurgte i et af dine tidligere opslag hvordan jeg laver animationen i CoolTrayIcon.

Der har jeg 1 cooltrayicon og 1 images komponent på min form. Images er tilknyttet i designtime til cooltrayicon.
På CoolTrayIcon har jeg i designtime sat CycleIcons til true og CycleInterval til 400.
Avatar billede kennethv Nybegynder
31. oktober 2014 - 11:22 #28
Måske gør jeg noget forkert og har sikkert overset noget, men får disse fejl:
[DCC Error] MainForm.pas(288): E2003 Undeclared identifier: 'CoInitializeEx'
[DCC Error] MainForm.pas(288): E2003 Undeclared identifier: 'COINIT_MULTITHREADED'
[DCC Error] MainForm.pas(297): E2003 Undeclared identifier: 'CoUninitialize'
[DCC Error] MainForm.pas(302): E2003 Undeclared identifier: 'List'
[DCC Error] MainForm.pas(303): E2003 Undeclared identifier: 'ReadTheIniFile'
[DCC Error] MainForm.pas(304): E2003 Undeclared identifier: 'DeleteDirectory'
[DCC Error] MainForm.pas(310): E2003 Undeclared identifier: 'List'

Jeg kan se i det du har lavet at du kalder TDelTreeThread.Create.OnTerminate:=DelTreeOnTerminate; fra en knap, så jeg går udfra at jeg godt kan kalde den samme fra en FormCreate, ikk? List er en TStringlist som jeg har oprettet i FormCreate. Jeg fornemmer at den skal flyttes, men er nok en lille smulle usikker på hvor hen. :) Det er måske i TDelTreeThread.Execute;?

Det samme gælder osse når jeg afslutter i FormDestroy

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  try
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst:=E.Message;
    end;
  end;
  CoUninitialize;
end;

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  TDelTreeThread.Create.OnTerminate:=DelTreeOnTerminate;
  List := TStringList.Create;
  ReadTheIniFile;
  application.Terminate;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(List);
end;
Avatar billede kroning Nybegynder
31. oktober 2014 - 13:48 #29
E2003 Undeclared identifier: 'CoInitializeEx'
E2003 Undeclared identifier: 'COINIT_MULTITHREADED'
E2003 Undeclared identifier: 'CoUninitialize'
Du skal tilføje ActiveX til din uses som vist i mit eks.

E2003 Undeclared identifier: 'List'
E2003 Undeclared identifier: 'ReadTheIniFile'
E2003 Undeclared identifier: 'DeleteDirectory'
E2003 Undeclared identifier: 'List'
List, ReadTheIniFile og DeleteDirectory skal flyttes til TDelTreeThread

Ja TDelTreeThread.Create.OnTerminate:=DelTreeOnTerminate; kan flyttes til formens OnCreate.

List skal flyttes til TDelTreeThread, du kan create den i trådens Create eller Execute

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  List := TStringList.Create;
  try
    ReadTheIniFile;
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst:=E.Message;
    end;
  end;
  FreeAndNil(List);
  ADOQuery1.Free;
  ADOConnection.Free;
  CoUninitialize;
end;

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
application.Terminate;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  TDelTreeThread.Create.OnTerminate:=DelTreeOnTerminate;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //ingenting her
end;
Avatar billede kennethv Nybegynder
03. november 2014 - 15:14 #30
Aha, den del med ActiveX havde jeg lige overset.

Debugger man bare som man ellers ville gøre?
Avatar billede kroning Nybegynder
03. november 2014 - 15:31 #31
Jeg bruger Delphi 7 og i den kan man ikke debugge som man plejer i en tråd, jeg ved ikke hvordan det virker i Delphi XE
Avatar billede kennethv Nybegynder
04. november 2014 - 10:24 #32
Ok. Jeg har sat nogle breakpoints de samme steder som før og det ser ud tl at det fungere helt fint.

Det ser ganske godt ud. Det virker ihvertfald. Hvis jeg nu gerne vil tilføje 1 popupmenu og 1 memo som jeg vil bruge som, hvor skulle det tilføjes? Jeg vil kunne gøre sådan at jeg kunne vise min form og på den se log oplysninger.
Avatar billede kennethv Nybegynder
04. november 2014 - 10:52 #33
Faktisk så er min tanke at have 1 memo på en pagecontrol.
Avatar billede kroning Nybegynder
04. november 2014 - 11:13 #34
Du tilføjer din popup og memo som du normalt gør.

Du kan se på TDelTreeThread tråden som et "andet program" der ikke direkte har noget med dit hoved program at gøre. Du starter bare programmet (TDelTreeThread) og på et tidspunkt så melder TDelTreeThread tilbage til dit hoved program at nu er jeg færdig.

Ofte så flytter jeg alt koden til en separat tråd ind i en Unit for sig selv, så er det lettere at overskue hvis der er meget kode.

Som tidligere nævnt så kan du godt få tråden (TDelTreeThread) til at melde tilbage løbende.
Avatar billede kennethv Nybegynder
04. november 2014 - 23:35 #35
Jeg går udfra at du tænker på #18?

I det eks. har du tænkt at det var en liste af mapper der skulle slettes, ikk? Jeg har sikkert ikke helt forstået det og det beklager jeg, men hvordan får tråden af vide at hvad der skal skives i en memo, når det er proceduren Deltree der giver mig en sand eller falsk tilbage melding?
Avatar billede kennethv Nybegynder
05. november 2014 - 00:08 #36
Hvis jeg nu skulle gøre den tanke som du nævnte at finde alle mapper der skal slettes først inden jeg kalder tråden, så forestiller jeg mig at det skulle være sådan her:

procedure TDelTreeThread.DeleteDirectory;
var i : integer; SearchRec: TSearchRec;
OwnerList, LogFile, LineList : TStringList;
begin
    for I := 0 to list.Count -1 do
    begin
      LineList := TStringList.Create;
      LineList.Delimiter := ',';
      try
        LineList.DelimitedText := StringReplace(List.Strings[i],' ','_',[rfReplaceAll]);
        sSiteOU := LineList[0] + ',' + LineList[1];
        sUsername := LineList[2];
        sDataFolder := LineList[3];
        sSiteHomePath := LineList[4];
        sMail := LineList[5];
        sManagedBy := StringReplace(LineList[6] + ',' + LineList[7] + ',' + LineList[8] + ',' + LineList[9] + ',' + LineList[10] + ',' + LineList[11] + ',' + LineList[12] + ',' + LineList[13],'_',' ',[rfReplaceAll]);
      finally
        LineList.Free;
      end;
      try
        OwnerList := TStringList.Create;
        try
          ADOQuery1.SQL.Clear;
          ADOQuery1.SQL.Text := 'SELECT CN FROM ' + Quotedstr('LDAP://OU=COMPUTERS,' + sSiteOU + ',OU=company,DC=AD,DC=company,DC=ORG') + ' WHERE ObjectClass=' + Quotedstr('computer') + ' AND managedby=' + Quotedstr(sManagedBy);
          ADOQuery1.Open;
          ADOQuery1.First;
          ADOQuery1.RecordCount;
          while not ADOQuery1.Eof do
          begin
            OwnerList.Add(ADOQuery1.FieldByName('CN').AsString);
            ADOQuery1.Next;
          end;
        finally
          ADOQuery1.Close;
        end;
        if OwnerList.Count <> 0 then
        begin
          if FindFirst(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + sDataFolder + '\*', faDirectory, SearchRec) = 0 then
          try
            begin
              repeat
                if ((SearchRec.Attr and faDirectory) <> faDirectory) or (SearchRec.Name = '.') or (SearchRec.Name = '..') then
                  continue;
                if pos(searchRec.Name,OwnerList.Text) = 0 then
                begin
                  if (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'LT',SearchRec.Name) <> 0) or (pos(uppercase(copy(sSiteOU,10,2)+copy(sSiteOU,4,2))+'DT',SearchRec.Name) <> 0) then
                  begin
                    if monthsbetween(date,FileDateToDateTime(SearchRec.Time)) > iVal then
                    begin
                      if sDatafolder = '' then
Her vil jeg tilføje ->  DelTreeList.add(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + SearchRec.Name)
                      else
Her vil jeg tilføje ->  DelTreeList.add(IncludeTrailingPathDelimiter(sSiteHomePath) + IncludeTrailingPathDelimiter(sUsername) + IncludeTrailingPathDelimiter(sDataFolder) + SearchRec.Name)
                    end;
                  end;
                end;
              until findNext(SearchRec) <> 0;
            end;
          finally
            FindClose(SearchRec);
          end;
        end;
      finally
        FreeAndNil(OwnerList);
      end;
    end;
end;
Avatar billede kroning Nybegynder
05. november 2014 - 00:25 #37
Hvis du vil opdatere din memo fra tråden gøres det sådan:

Lav en procedure i tråden:

procedure TDelTreeThread.OpdaterMemo;
begin
  TForm1.Memo.Lines.Add('en tekst');
end;

Når du vil skrive noget i memoen fra tråden gøres det sådan:
Synchronize(OpdaterMemo);
Avatar billede kennethv Nybegynder
05. november 2014 - 13:36 #38
Okay.
Så jeg laver en procedure i tråden for hver tekst jeg skal bruge?
Avatar billede kroning Nybegynder
05. november 2014 - 15:09 #39
Nej, en procedure er nok.
Avatar billede kennethv Nybegynder
05. november 2014 - 16:19 #40
Men hvis jeg har brug for noget forskellige tekst afhængig af udfaldet, hvordan kalder man så de forskellige tekster?

Du må meget undskylde at jeg ikke sådan lige har fanget det endnu. :)
Avatar billede kroning Nybegynder
05. november 2014 - 16:34 #41
Hvis det bare er den sidste linie i Logfile kan du gøre sådan:

procedure TDelTreeThread.OpdaterMemo;
begin
  TForm1.Memo.Lines.Add(Logfile....sidste linie);
end;

eller f.eks.
opret en tekst variable

LogTekst:='din tekst her';
Synchronize(OpdaterMemo);

og så:
procedure TDelTreeThread.OpdaterMemo;
begin
  TForm1.Memo.Lines.Add(LogTekst);
end;
Avatar billede kennethv Nybegynder
05. november 2014 - 17:31 #42
Dette er hvad jeg har gjort i tråden:

  TDelTreeThread = class(TThread)
  private
    { Private declarations }
    ADOConnection: TADOConnection;
    ADOQuery1: TADOQuery;
    iVal : integer;
    List : TStringList;
    sLogTekst, sSiteOU, sDataFolder, sSiteHomePath, sUsername, sMail, sManagedBy : string;
    Function DelTree(DirName : string): Boolean;
->  procedure OpdaterMemo;
    procedure GetTheUsers;
    procedure GetTheConsultants;
    procedure ReadTheIniFile;
    procedure DeleteTempRAW(S1: String);
    procedure DeleteDirectory;
  protected
    procedure Execute; override;
  public
    ErrorTekst : string;
    constructor Create;
  end;

Også lavet dette:

procedure TDelTreeThread.OpdaterMemo;
begin
  TForm1.Memo.Lines.Add(LogTekst);
end;

Men når jeg skriver:

TForm1.

Så forventer jeg at "Memo1" dukker op på listen. Det gør det ikke. Jeg har så bare skrevet videre og forsøgt at compile det, men der får jeg så en fejl:

[DCC Error] MainForm.pas(82): E2096 Method identifier expected

Min Form1 ser således ud:

  TForm1 = class(TForm)
    ImageList1: TImageList;
    CoolTrayIcon1: TCoolTrayIcon;
    PopupMenu1: TPopupMenu;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    Open1: TMenuItem;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure Open1Click(Sender: TObject);
  private
    procedure DelTreeOnTerminate(Sender: TObject);
  public
    { Public declarations }
  end;
Avatar billede kennethv Nybegynder
05. november 2014 - 17:35 #43
Hov der skulle selvfølgelig stå:

procedure TDelTreeThread.OpdaterMemo;
begin
  TForm1.Memo1.Lines.Add(LogTekst);
end;

:)
Avatar billede kroning Nybegynder
05. november 2014 - 17:45 #44
Det skal være Form1 og ikke TForm1

procedure TDelTreeThread.OpdaterMemo;
begin
  Form1.Memo1.Lines.Add(LogTekst);
end;
Avatar billede kennethv Nybegynder
05. november 2014 - 18:28 #45
Ja, sgu.

Det ser ud til at det spiller.

Perfekt.

Hvis jeg nu lige inden at programmet afsluttes vil gemme indholdet af memo1, skal det så gøres i form1.onClose?

Det har ikke noget med selve tråden at gøre vel? For som jeg husker at du nævnte var at jeg må ikke kalde nogen funktioner fra tråden.
Avatar billede kroning Nybegynder
05. november 2014 - 19:33 #46
Ja i OnClose er en mulighed.

Det er rigtig du må ikke inde fra tråden direkte kalde variabler eller funktioner som ikke er defineret i tråden.
Avatar billede kennethv Nybegynder
05. november 2014 - 19:41 #47
Super.

Du må ligge et ´svar.
Mange tak for hjælpen.
Avatar billede kroning Nybegynder
05. november 2014 - 19:53 #48
ok :-)
Avatar billede kennethv Nybegynder
05. november 2014 - 20:10 #49
Hov jeg var lidt for hurtig.
Den afslutter ikke sig selv efter at den har været TDelTreeThread.Execute igennem.

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  List := TStringList.Create;
  try
    ReadTheIniFile;
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst := E.Message;
    end;
  end;
  FreeAndNil(List);
  CoUninitialize;
end;
Avatar billede kroning Nybegynder
05. november 2014 - 21:53 #50
Hvad afslutter ikke, tråden eller programmet?
Bliver TForm1.DelTreeOnTerminate kaldt på et tidspunkt?
Avatar billede kennethv Nybegynder
06. november 2014 - 09:05 #51
Bliver den ikke det i TForm1.FormCreate?

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TDelTreeThread.Create.OnTerminate := DelTreeOnTerminate;
end;

Den gennemfører TDelTreeThread.Execute, men derefter sker der ikke noget.

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  List := TStringList.Create;
  try
    ReadTheIniFile;
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst := E.Message;
    end;
  end;
  FreeAndNil(List);
  CoUninitialize;
end;
Avatar billede kennethv Nybegynder
06. november 2014 - 14:47 #52
Iøvrigt bliver tråden afsluttet, men ikke programmet.
Avatar billede kroning Nybegynder
06. november 2014 - 15:52 #53
Tråden bliver startet i TForm1.FormCreate.

Hvor og hvordan afslutter du programmet?
Avatar billede kennethv Nybegynder
06. november 2014 - 16:07 #54
Ja, det er jo så spørgsmålet. Jeg troede at det skete udfra det der allerede var i koden. :) Det bliver ikke afsluttet. Jeg kan se at min memo bliver opdateret med status:

End of checking for old backup folders.

Så sker der ikke mere.

Disse er hvad jeg har lavet:

procedure TDelTreeThread.Execute;
begin
  CoInitializeEx(nil,COINIT_MULTITHREADED);
  List := TStringList.Create;
  try
    ReadTheIniFile;
    DeleteDirectory;
    except
    on E:Exception do
    begin
      ErrorTekst := E.Message;
    end;
  end;
  FreeAndNil(List);
  ADOQuery1.Free;
  ADOConnection.Free;
  CoUninitialize;
end;

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  memo1.Lines.Add(DateTimeToStr(Now) + ' - End of checking for old folders');
  memo1.Lines.SaveToFile(IncludeTrailingPathDelimiter(getcurrentdir)+datetostr(now)+'.log');
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TDelTreeThread.Create.OnTerminate := DelTreeOnTerminate;
end;
Avatar billede kroning Nybegynder
06. november 2014 - 16:25 #55
Som beskrevet i #29 vil jeg forslå at du afslutter i DelTreeOnTerminate

procedure TForm1.DelTreeOnTerminate(Sender: TObject);
begin
  if (Sender as TDelTreeThread).ErrorTekst<>'' then
  begin
    ShowMessage((Sender as TDelTreeThread).ErrorTekst);

//I stedet for en ShowMessage her kan du evt. i stedet
//tilføje ErrorTekst til din memo1

  end;
application.Terminate; //Afslut program her
end;
Avatar billede kennethv Nybegynder
10. november 2014 - 10:02 #56
Jeg har et lille spørgsmål hetil sidst. Når nu Application.Terminate bliver kaldt i procedure TForm1.DelTreeOnTerminate(Sender: TObject); bliver procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); så ikke kaldt derefter? For det jeg har stående i den er, at indholdet i min Memo skal gemmes, men det gør den ikke når programmet afsluttes.
Avatar billede kroning Nybegynder
10. november 2014 - 16:20 #57
Det har du ret i, OnClose bliver ikke kaldt hvis man bruger Application.Terminate.

Jeg bruger aldrig Application.Terminate men altid Close. Så udskrift Application.Terminate; med Close; så burde det virke.
Avatar billede kennethv Nybegynder
11. november 2014 - 09:46 #58
Tak for det, men problemet er, at application.close findes ikke.
Avatar billede kroning Nybegynder
11. november 2014 - 10:25 #59
Jeg syntes jeg skrev det meget tydelig :-)

Udskrift Application.Terminate; med Close;

jeg skrev ikke

udskrift Application.Terminate; med Application.Close;
Avatar billede MADOlsen Forsker
11. november 2014 - 10:34 #60
#59
Udskift "Udskrift" med "Udskift" ;-)
Avatar billede kroning Nybegynder
11. november 2014 - 11:02 #61
Hov :-)  Udskift...udskift..udskift, sådan går det når man tænker på noget andet mens man skriver.
Avatar billede kennethv Nybegynder
11. november 2014 - 11:43 #62
:)

Ja, jeg troede at det var med en application først. Men det virker nu.

Tak for hjælpen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester