Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Die Exe schon, leider habe ich es noch nicht geschafft es zu kompilieren.
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Hm meine Versuche sehen jetzt so aus:
Delphi-Quellcode:
Anwendungen lassen sich mit und ohne Parameter starten, aber es kommt eine AV. Die Parameter werden als PWideChar(WideString(User)) übergeben.
function CreateProcessAsLogon(const User, PW, Application, CmdLine: PWideChar):
LongBool; var si : TStartupInfoW; pif : TProcessInformation; AppCmdLine : PWideChar; begin GetMem(AppCmdLine, length(Application) + length(CmdLine) + 3); try lstrcpyW(AppCmdLine, Application); lstrcatW(AppCmdLine, ' "'); lstrcatW(AppCmdLine, CmdLine); lstrcatW(AppCmdLine, '"'); ZeroMemory(@si, sizeof(si)); si.cb := sizeof(si); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := 1; result := CreateProcessWithLogonW(User, nil, PW, LOGON_WITH_PROFILE, nil, AppCmdLine, CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif); finally FreeMem(AppCmdLine); end; end; Dann noch das:
Delphi-Quellcode:
Die Parameter werden ungecastet als Stringsübergeben. Da bekomme ich auch Anwendungen mit und ohne Parameter gestartet, aber bei falschen Passwort habe ich wieder GetLastError = 0:
function CreateProcessAsLogon(const User, PW, Application, CmdLine: WideString):
LongBool; var si : TStartupInfoW; pif : TProcessInformation; //AppCmdLine : PWideChar; begin // GetMem(AppCmdLine, length(Application) + length(CmdLine) + 3); try // lstrcpyW(AppCmdLine, Application); // lstrcatW(AppCmdLine, ' "'); // lstrcatW(AppCmdLine, CmdLine); // lstrcatW(AppCmdLine, '"'); 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, nil, PWideChar(Application+' "'+CmdLine+'"'), CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif); finally // FreeMem(AppCmdLine); end; end; Noch ein Versuch:
Delphi-Quellcode:
False und GetLastError = 0.
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, nil, PWideChar(WApp + ' "' + WCmdLine + '"'), CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif); end; Nächster Versuch:
Delphi-Quellcode:
False und GetLastError = 0. Bei Anwendungen mit Paramtern komt eine AV nach dem Start.
function CreateProcessAsLogon(const User, PW, Application, CmdLine: PWideChar):
LongBool; var si : TStartupInfoW; pif : TProcessInformation; WUser : LPWSTR; WPW : LPWSTR; WApp : LPWSTR; WCmdLine : LPWSTR; AppCmd: LPWSTR; begin ZeroMemory(@si, sizeof(si)); si.cb := sizeof(si); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := 1; WUser := SysAllocString(User); WPW := SysAllocString(PW); WApp := SysAllocString(Application); WCmdLine := SysAllocString(CmdLine); GetMem(AppCmd, length(Application)+length(CmdLine)+3); lstrcpyW(AppCmd, WApp); lstrcatW(AppCmd, ' "'); lstrcatW(AppCmd, CmdLine); lstrcatW(AppCmd, '"'); result := CreateProcessWithLogonW(PWideChar(WUser), nil, PWideChar(WPW), LOGON_WITH_PROFILE, nil, AppCmd, CREATE_DEFAULT_ERROR_MODE, nil, nil, @si, @pif); end; |
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Also folgendes funktioniert bei mir:
Delphi-Quellcode:
Mit Parameter, mit ohne Parameter, mit falschen Passwrt, mit richtigem Passwort, Username, immer das erwartete Ergebnis.
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; Das geniale ist aber, folgender Code:
Delphi-Quellcode:
führt zu GetLastError = 0.
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; 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:
Macht den Code kürzer und spart immerhin das Rumreferenziere der Strings ;-)
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; Kriege ich jetzt auch einen feuchten Händedruck? Biddöööö :mrgreen: |
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Zitat:
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Joa, also mit dem Problem der WideStrings bzw den Typecasts hab ich mich auch schonmal ausführlich beschäftigt. Das Problem ist, wie schon von Thomas erkannt, das interne String-Handling und die damit verbundenen transparenten API-Aufrufe. Werd mir das sobald ich dazu komm nochmal genauer anschaun...
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Moin Thomas,
Zitat:
Man sollte nur die Doku zu GetLastError berücksichtigen, bezüglich SysFreeString ist hier der letzte markierte Satz entscheidend. Zitat:
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Hmm, habe ich tatsächlich nicht bemerkt, aber ändert nichts dran, denn:
Zitat:
Zitat:
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Um die Ecke denken? Nein. Richtig übersetzen würde schon reichen. :mrgreen:
Zitat:
|
Re: Rückgabewert von CreateProcessWithLogonW und GetLastErro
Zitat:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var c: PWideChar; begin SysAllocStringLen(c, 10); SetLastError(123); ShowMessage(IntToStr(GetLastError)); // <-- '123' SysFreeString(c); ShowMessage(IntToStr(GetLastError)); // <-- '0' end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:47 Uhr. |
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