Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Systemfehler Code 6 (https://www.delphipraxis.net/165913-systemfehler-code-6-a.html)

ONeill 21. Jan 2012 10:28


Systemfehler Code 6
 
Hallo Leute,
ich habe mal ein bisschen ggegoogelt und gelesen, aber nicht wirklich eine Lösung für mein Problem gefunden.
ZUm Programm:
Ich bin gerade dabei ein Programm zu schreiben, welches nacheinander verschiedene Befehle ausführen soll, ähnlich wie eine Batchdatei.
Dabei sollen allerdings die Ereignise, die in dem cmd-Fenster erscheinen auch in ein Memo geschrieben werden als Logbuch.
Nun habe ich das Problem, das bei einer Abfolge von Befehlen ein Fehler kommt:
Code:
Systemfehler. Code:6.
Das Handle ist ungültig.
Der Fehler tritt in folgendem Code auf:
Delphi-Quellcode:
function Tfmain.installcwm:Boolean;
begin
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'adb', 'reboot bootloader');
  Delay(500);
  flog.log.Lines.Add('reboot into bootloader');
  flog.log.Free;
  Delay(500);
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'fastboot', 'flash recovery cwm.img');
  flog.log.Lines.Add('install CWM recovery');
  flog.log.Free;
  Delay(1000); //<-------------------- hier wird der Fehler angezeigt
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'fastboot', 'reboot');
  Delay(500);
  result := true;
end;
Die Funktion wird durch den Klick eines Buttons aufgerufen:
Delphi-Quellcode:
procedure Tfmain.Button3Click(Sender: TObject);
begin
  if installcwm() = true then
  begin
    showmessage('CWM installed successfully!');
  end
  else
  begin
    showmessage('Ann error occur. Please show log and see at your phone.');
  end;
end;
Als Funktion zum ausführen der cmd-Befehle verwende ich den Code, den ich irgendwo hier gefunden habe, ich weiß bloß nicht mehr wo :(
Delphi-Quellcode:
function Tfmain.RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;
var
  start: TStartupInfo;
  procInfo: TProcessInformation;
  tmpName: string;
  tmp: Windows.THandle;
  tmpSec: TSecurityAttributes;
  res: TStringList;
  return: Cardinal;
  i,i2:integer;
begin
  Result := False;
  try
    { Setze ein Temporäres File }
    { Set a temporary file }
    tmpName := 'marvel.tmp';
    FillChar(tmpSec, SizeOf(tmpSec), #0);
    tmpSec.nLength := SizeOf(tmpSec);
    tmpSec.bInheritHandle := True;
    tmp := Windows.CreateFile(PChar(tmpName),
           Generic_Write, File_Share_Write,
           @tmpSec, Create_Always, File_Attribute_Normal, 0);
    try
      FillChar(start, SizeOf(start), #0);
      start.cb         := SizeOf(start);
      start.hStdOutput := tmp;
      start.dwFlags    := StartF_UseStdHandles or StartF_UseShowWindow;
      start.wShowWindow := SW_Minimize;
      { Starte das Programm }
      if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,
                       0, nil, PChar(_dirName), start, procInfo) then
      begin
        SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
        WaitForSingleObject(procInfo.hProcess, Infinite);
        GetExitCodeProcess(procInfo.hProcess, return);
        Result := (return = 0);
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
        Windows.CloseHandle(tmp);
        { Die Ausgaben hinzufügen }
        if KillProcess(GetProcessID('adb.exe')) = true then
        begin
          res := TStringList.Create;
          output:='';
          try
            res.LoadFromFile(tmpName);
            for i:= 0 to res.Count-2 do
            begin
             if res.Strings[i] = '* daemon not running. starting it now *' then
              res.Delete(i);
            end;
            for i:= 0 to res.Count-2 do
            begin
             if res.Strings[i] = '* daemon started successfully *' then
              res.Delete(i);
            end;
            i:=0;
            IF res.Count <> 0 then begin
            For i := res.Count - 1 downto 0 do
            begin
              IF res.Strings[i] = '' then
               res.Delete(i);
            end;
            end;
            flog.log.Lines.AddStrings(res);
            output:=res.Text;
          finally
            res.Free;
          end;
        end;
        Windows.DeleteFile(PChar(tmpName));
      end
      else
      begin
        Application.MessageBox(PChar(SysErrorMessage(GetLastError())),
          'RunCaptured Error', MB_OK);
      end;
    except
      Windows.CloseHandle(tmp);
      Windows.DeleteFile(PChar(tmpName));
      raise;
    end;
  finally
  end;
end;
Da die adb.exe als Service gestartet wird, muss ich vorher den Prozess beenden, bevor ich wieder Zugriff auf die marvel.tmp habe. Dazu verwende ich folgenden Code:
Delphi-Quellcode:
function tfmain.KillProcess(dwProcID: DWORD):Boolean;
var
  hProcess : Cardinal;
  dw : DWORD;
begin
  { open the process and store the process-handle }
  hProcess := OpenProcess(SYNCHRONIZE or PROCESS_TERMINATE, False, dwProcID);
  { kill it }
  TerminateProcess(hProcess, 0);
  { TerminateProcess returns immediately, so wie have to verify the result via
    WaitfForSingleObject }
  dw := WaitForSingleObject(hProcess, 5000);
  case dw of
    WAIT_OBJECT_0: result:=true;
    { process could not be terminated after 5 seconds }
    WAIT_TIMEOUT:
    begin
      Messagebox(Application.Handle, 'Prozess konnte nicht innerhalb von 5 Sekunden beendet werden.',
        'Prozess beenden', MB_ICONSTOP);
        result:=false;
      CloseHandle(hProcess);
      exit;
    end;
    { error in calling WaitForSingleObject }
    WAIT_FAILED:
    begin
      RaiseLastOSError;
      CloseHandle(hProcess);
      exit;
    end;
  end;
  CloseHandle(hProcess);
  end;
Nun weiß ich nicht wirklich wo denn der Fehler ist. Laut meiner Auffassung müsste es gehen. Hat von euch noch jemand Lösungsansätze?

Danke schon mal im voraus.

einbeliebigername 21. Jan 2012 10:47

AW: Systemfehler Code 6
 
Hallo,

Zitat:

Zitat von ONeill (Beitrag 1146970)
Code:
  flog.log.Lines.Add('reboot into bootloader');
  flog.log.Free;
  ...
  flog.log.Lines.Add('install CWM recovery');

Und was ist flog und wie sieht flog.log aus. Wieso wird da was freigegeben und danach scheinbar wieder benutzt.

einbeliebigername.

ONeill 21. Jan 2012 10:57

AW: Systemfehler Code 6
 
flog is ein weiters Form, indem das Memo log eingebunden ist ;)

Das ist mir so noch gar nicht aufgefallen, das ich das erst schließe und dann wieder beschreibe :(
Neue Funktion ist somit dann:
Delphi-Quellcode:
function Tfmain.installcwm:Boolean;
begin
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'adb', 'reboot bootloader');
  Delay(500);
  flog.log.Lines.Add('reboot into bootloader');
  Delay(500);
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'fastboot', 'flash recovery cwm.img');
  flog.log.Lines.Add('install CWM recovery');
  Delay(1000);
  fmain.RunCaptured(ExtractFilePath(Application.Exename), 'fastboot', 'reboot');
  Delay(500);
  flog.log.Free;
  result := true;
end;
Ist aber für das Problem keine Lösung :(

einbeliebigername 21. Jan 2012 12:47

AW: Systemfehler Code 6
 
Hallo,

Zitat:

Zitat von ONeill (Beitrag 1146974)
flog is ein weiters Form, indem das Memo log eingebunden ist

Dann würde ich auf
Delphi-Quellcode:
flog.log.free;
aber ganz verzichten, denn bei jedem Aufruf von Tfmain.installcwm würde das ja freigegeben werden.

Zitat:

Zitat von ONeill (Beitrag 1146974)
Ist aber für das Problem keine Lösung :(

Wenn du das obige berücksichtigt hast, wo steigt er dann aus und mit welchem Fehler.

Und dann bin ich der Meinung das man ein Service nicht über CreateProcess startet, sondern über den Service Control Manager. Und dann hat ein Service auch kein StdOut.

einbeliebigername.

ONeill 21. Jan 2012 13:51

AW: Systemfehler Code 6
 
Die adb.exe ist kein Windows Service sondern ein zusätzlicher daemon für die Android ENtwicklung. Man kann den Service nur über das starten der adb.exe starten und auch über das Beenden des Prozeses oder durch den adb kill-server befehl beenden.
Ich beende also den Service ganz normal, wie ich es auch per Hand tun würde.

Er steigt bei der selben stelle nach dem ausführen von "fastboot flash recovery recovery.img" aus.

einbeliebigername 21. Jan 2012 14:24

AW: Systemfehler Code 6
 
Hallo,

Zitat:

Zitat von ONeill (Beitrag 1146992)
Die adb.exe ist kein Windows Service sondern ein zusätzlicher daemon für die Android ENtwicklung. Man kann den Service nur über das starten der adb.exe starten und auch über das Beenden des Prozeses oder durch den adb kill-server befehl beenden.
Ich beende also den Service ganz normal, wie ich es auch per Hand tun würde.

Ich hatte halt Service eher mit Widowsdienst in Verbindung gebracht.

Zitat:

Zitat von ONeill (Beitrag 1146992)
Er steigt bei der selben stelle nach dem ausführen von "fastboot flash recovery recovery.img" aus.

Ich denke da ist wieder das Problem, das Delphi bei einem Fehler nicht direkt an der Stelle in der Funktion steht bleibt, sonder außerhalb der Funktion. Beim zweiten rüber schauen über Tfmain.RunCaptured, ist mir das aufgefallen
Zitat:

Zitat von ONeill (Beitrag 1146970)
Code:
        CloseHandle(procInfo.hThread);
        CloseHandle(procInfo.hProcess);
        Windows.CloseHandle(tmp);
        { Die Ausgaben hinzufügen }
        if KillProcess(GetProcessID('adb.exe')) = true then

in Verbindung mit dem
Zitat:

Zitat von ONeill (Beitrag 1146970)
Code:
    except
      Windows.CloseHandle(tmp);
      Windows.DeleteFile(PChar(tmpName));
      raise;
    end;
  finally
  end;
end;

Es könnt dazu kommen das
Delphi-Quellcode:
Windows.CloseHandle(tmp)
zweimal aufgerufen wird. Was Windows beim zweiten Aufruf macht weiß ich jetzt nicht. Aber ich könnte mir denkt das es zu deinem Fehler führt. Mach doch mal einen Haltepunkt nach dem except und schau ob er da vorbei kommt. Wenn du damit auch nicht weiterkommst bleibt dir wohl nichts anderes übrig als mal mit F7 durchzudebuggen.

einbeliebigername.

ONeill 21. Jan 2012 14:36

AW: Systemfehler Code 6
 
Das zweite WIndow.CloseHandle(tmp) ist aber in dem Exceptbereich. Wenn ich das richtig in Erinnerung habe, dürften niemals beide Windows.CloseHandle(tmp) ausgeführt werden. Dafür ist es ja da ;)

Dann werde ich wohl mal den Debugger bedienen müssen :pale:
Falls noch jemand eine Idee hat, bitte posten ;)

einbeliebigername 21. Jan 2012 14:50

AW: Systemfehler Code 6
 
Hallo,

Zitat:

Zitat von ONeill (Beitrag 1146999)
Das zweite WIndow.CloseHandle(tmp) ist aber in dem Exceptbereich. Wenn ich das richtig in Erinnerung habe, dürften niemals beide Windows.CloseHandle(tmp) ausgeführt werden. Dafür ist es ja da ;)

Das ist aber nur so, wenn zwischen dem ersten CloseHandle und dem except keine Exception ausgelöst wird. Dritt da aber eine auf, wird das Handle zweimal geschlossen.

einbeliebigername.

ONeill 21. Jan 2012 15:09

AW: Systemfehler Code 6
 
Dann wäre es doch besser, wenn ich das CloseHandle in die finally abschnitt reinschreibe, oder?:thumb:

einbeliebigername 21. Jan 2012 15:59

AW: Systemfehler Code 6
 
Hallo,

Zitat:

Zitat von ONeill (Beitrag 1147006)
CloseHandle in die finally abschnitt reinschreibe, oder?:thumb:

Ich würde auch das löschen der Datei in ein finally verfrachten.

einbeliebigername.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:19 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz