Autor Beitrag
yogo
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 121

Windowse, Linuxe
Delphi 3 Prof., D5 Enterprise, D6 Enterprise, Kylix, Delphi 2010
BeitragVerfasst: Sa 19.02.11 16:19 
Hallo,

ich habe mit delphi 6 eine anwendung geschrieben, in der ich diese zusammenkopierte funktion benutzt habe:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function CreateProcessCstm(befehl: string): Longint;
var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  //Fenster nicht anzeigen
  StartupInfo.dwFlags := StartF_UseShowWindow;

  StartupInfo.wShowWindow := SW_Hide;
  //in delphi 6 ging das hier zB mit Befehl := 'sqlcmd -?'
  //if CreateProcess(nil, PChar(Befehl), nil, nil, False, 0, nil,
  //  PChar(ExtractFilePath(ParamStr(0))), StartupInfo, ProcessInfo) then

  // hier gibts nen zugriffsfehler in der kernel32.dll:
  if CreateProcess(nil, PChar('C:\Windows\System32\calc.exe'), nilnil, False, 0nil,
    nil, StartupInfo, ProcessInfo) then
  //oder:
  if CreateProcess(nil, PChar('calc.exe -bla'), nilnil, False, 0nil,
    nil, StartupInfo, ProcessInfo) then
  //oder: 
  if CreateProcess(PChar('calc.exe'), nilnilnil, False, 0nil,
    nil, StartupInfo, ProcessInfo) then
  //schon allein: 
  if CreateProcess(PChar('C:\Windows\System32\calc'), nilnilnil, False, 0nil,
    nil, StartupInfo, ProcessInfo) then



Nach der Portierung auf Delphi 2010 bekam ich dann allerdings Laufzeitfehler.
Die Hilfe sagt dazu:
ausblenden Quelltext
1:
The first parameter, lpApplicationName, can be NULL, in which case the executable name must be in the white space-delimited string pointed to by lpCommandLine.					

Trotzdem muss ich zB CreateProcess(PChar(C:\Windows\System32\calc.exe'), PChar('-bla'), ... ausführen, um einen Fehler zu Vermeiden.
Ich kann weder den Pfad weglassen, noch alles in den zweiten Parameter schreiben.

In meinem Fall (sqlcmd) ist allerdings nicht vorher klar, wo die executable stehen wird.
ShellExecute kommt nicht in Frage, da ich einen Error-Code erwarte.

Ich bin ratlos :nixweiss:
Kann mir jemand von euch sagen, was ich anders machen muss?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 19.02.11 18:08 
Das liegt daran, dass der zweite Parameter in der Unicodeversion variabel sein muss. Du übergibst aber Konstanten. Dass das eine Exception auslösen kann, steht doch sogar explizit in der Doku...
MSDN Doku zu CreateProcess hat folgendes geschrieben:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
Also muss das ein variabler Parameter sein. Ein einfacher Workaround:
ausblenden Delphi-Quelltext
1:
2:
3:
procedure ExecuteFile(const AFileName: string);
begin
  CreateProcess(nil, PChar(AFileName + ''), ...
Durch die Stringkonkatenation wird der String zur Laufzeit neu im Speicher abgelegt und kann verändert werden. Das ist zwar nicht ganz sauber so, aber es funktioniert.

Um es sauber zu machen, müsstest du tatsächlich eine eigene Variable anlegen und die Daten dort hineinkopieren (also nicht nur casten).