Einzelnen Beitrag anzeigen

tommie-lie
(Gast)

n/a Beiträge
 
#23

Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro

  Alt 22. Jan 2005, 21:38
Also folgendes funktioniert bei mir:
Delphi-Quellcode:
function CreateProcessAsLogon(const User, PW, Application, CmdLine: WideString):
  LongBool;
var
  si : TStartupInfoW;
  pif : TProcessInformation;
  WUser : WideString;
  WPW : WideString;
  WApp : WideString;
  WCmdLine : WideString;
begin
  ZeroMemory(@si, sizeof(si));
  si.cb := sizeof(si);
  si.dwFlags := STARTF_USESHOWWINDOW;
  si.wShowWindow := 1;

  WUser := User;
  WPW := PW;
  WApp := Application;
  WCmdLine := CmdLine;

  result := CreateProcessWithLogonW(PWideChar(WUser), nil, PWideChar(WPW),
    LOGON_WITH_PROFILE, PWideChar(WApp), PWideChar(WCmdLine),
    CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif);

  if not result then
    MessageBox(0, PChar(SysErrorMessage(GetLastError)), 'Testanwendung', MB_ICONSTOP);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  User, PW, Filename, Params: WideString;
begin
  User := Edit1.Text;
  PW := Edit2.Text;
  Filename := Edit3.Text;
  Params := Edit4.Text;

  CreateProcessAsLogon(User, PW, Filename, Params)
end;
Mit Parameter, mit ohne Parameter, mit falschen Passwrt, mit richtigem Passwort, Username, immer das erwartete Ergebnis.

Das geniale ist aber, folgender Code:
Delphi-Quellcode:
function CreateProcessAsLogon(const User, PW, Application, CmdLine: WideString):
  LongBool;
var
  si : TStartupInfoW;
  pif : TProcessInformation;
  WUser : WideString;
  WPW : WideString;
  WApp : WideString;
  WCmdLine : WideString;
begin
  ZeroMemory(@si, sizeof(si));
  si.cb := sizeof(si);
  si.dwFlags := STARTF_USESHOWWINDOW;
  si.wShowWindow := 1;

  WUser := User;
  WPW := PW;
  WApp := Application;
  WCmdLine := CmdLine;

  result := CreateProcessWithLogonW(PWideChar(WUser), nil, PWideChar(WPW),
    LOGON_WITH_PROFILE, PWideChar(WApp), PWideChar(WCmdLine),
    CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  User, PW, Filename, Params: WideString;
begin

User := Edit1.Text;
PW := Edit2.Text;
Filename := Edit3.Text;
Params := Edit4.Text;

SetLastError(0);

if not CreateProcessAsLogon(User, PW, Filename, Params)then
    MessageBox(0, PChar(SysErrorMessage(GetLastError)), '', MB_ICONSTOP);
end;
führt zu GetLastError = 0.

Dem bin ich mal nachgegangen, und das ganze scheint sich tief in der Laufzeitumgebung abzuspielen und - oh wunder - alles andere als dokumentiert zu sein.
Vor dem Austritt aus der Funktion ruft der Compiler WStrArrayClr() aus der Borland-RTL auf. Die wiederum ruft SysFreeString aus Microsofts OleAuto32.dll auf (deren Funktioenen in D6 übrigens nur unvollständig implementiert sind, und in der Personal anscheinend noch unvollständiger). Diese ist eigentlich dazu da, einen String wieder freizugeben. Das erstaunliche aber ist, daß sie gleichzeitig den Wert von GetLastError() ändert, und zwar ohne daß das mit nur einem Wort im SDK erwähnt wird. Wenn du GetLastError() vor dem Funktionsaustritt aufrufst, hat der Compiler noch nicht versucht die Widestrings wieder freizugeben, folglich wurde SysFreeString() noch nicht aufgerufen und der Wert von GetLastError stimmt noch. So wie es aussieht musst du also entweder einen variablen Parameter für den Fehlerwert einführen, oder anstatt eines Boolean-Ergebnisses einen Integer mit dem Wert von GetLastError() nehmen.

Ich denke, daß folgender Code es auch tun würde:
Delphi-Quellcode:
function CreateProcessAsLogon(const User, PW, Application, CmdLine: WideString):
  LongBool;
var
  si : TStartupInfoW;
  pif : TProcessInformation;
begin
  ZeroMemory(@si, sizeof(si));
  si.cb := sizeof(si);
  si.dwFlags := STARTF_USESHOWWINDOW;
  si.wShowWindow := 1;

  result := CreateProcessWithLogonW(PWideChar(User), nil, PWideChar(PW),
    LOGON_WITH_PROFILE, PWideChar(App), PWideChar(CmdLine),
    CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif);

  if not result then
    MessageBox(0, PChar(SysErrorMessage(GetLastError)), 'Testanwendung', MB_ICONSTOP);
end;
Macht den Code kürzer und spart immerhin das Rumreferenziere der Strings




Kriege ich jetzt auch einen feuchten Händedruck? Biddöööö
  Mit Zitat antworten Zitat