Discussion:
createprocesswithlogonw passing arguments
(too old to reply)
Marc Dullien
2004-11-10 13:06:14 UTC
Permalink
Hello World,

we are prparing CDs for our laptop users with the appropriate Windows
and office patches. The users then need to connect their laptops and
start the little program. We then want to start the patches as a
Domain user with the necessary rights to install them.

I use the createProcesswithlogonuser to call the patch (win1.exe,
win2.exe, ofice1.exe,...) This works great!

BUT, i can not pass arguments to the patch. I want to call the patches
with /QUIET and /norestart but that is ignored.
However, if I call notepad.exe c:\gaga.txt, that works ?? Also cmd.exe
/? works

Any suggestions are welcome!

I tried blanks, '' "" at the various points, buit had no lock.

Thanks a lot!
Marc
-----------------------------
THE CODE:

unit Softwarepatch;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Shape1: TShape;
Image1: TImage;
Label5: TLabel;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);


end;


var
Form1: TForm1;

implementation
{$R *.dfm}

function CreateProcessWithLogonW(
lpUsername,
lpDomain,
lpPassword:PWideChar;
dwLogonFlags:dword;
lpApplicationName: PWideChar;
lpCommandLine: PWideChar;
dwCreationFlags: DWORD;
lpEnvironment: Pointer;
lpCurrentDirectory: PWideChar;
const lpStartupInfo: tSTARTUPINFO;
var lpProcessInformation: TProcessInformation
): BOOL; stdcall; external 'advapi32.dll';

procedure RunAsUser(const Domain, Username, Password, Command:
string);
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
wDomain, wUsername, wPassword, wCommand: PWideChar;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOWNORMAL;

GetMem(
wDomain,
Length(Domain) * SizeOf(WideChar) + SizeOf(WideChar));
GetMem(
wUsername,
Length(Username) * SizeOf(WideChar) + SizeOf(WideChar));
GetMem(
wPassword,
Length(Password) * SizeOf(WideChar) + SizeOf(WideChar));
GetMem(
wCommand,
Length(Command) * SizeOf(WideChar) + SizeOf(WideChar));

StringToWideChar(
Domain,
wDomain,
Length(Domain) * SizeOf(WideChar) + SizeOf(WideChar));
StringToWideChar(
Username,
wUsername,
Length(Username) * SizeOf(WideChar) + SizeOf(WideChar));
StringToWideChar(
Password,
wPassword,
Length(Password) * SizeOf(WideChar) + SizeOf(WideChar));
StringToWideChar(
Command,
wCommand,
Length(Command) * SizeOf(WideChar) + SizeOf(WideChar));

if not CreateProcessWithLogonW(
wUsername,
wDomain,
wPassword,
0,
nil,
wCommand,
0,
nil,
nil,
StartupInfo,
ProcessInfo) then RaiseLastOSError;

FreeMem(wDomain);
FreeMem(wUsername);
FreeMem(wPassword);
FreeMem(wCommand);
end;


procedure TForm1.Button3Click(Sender: TObject);
begin
RunAsUser('DOMAIN', 'USER','PASDS','win1.exe /QUIET');
end;

End.
VBDis
2004-11-11 01:45:04 UTC
Permalink
Post by Marc Dullien
StringToWideChar(
Domain,
wDomain,
Length(Domain) * SizeOf(WideChar) + SizeOf(WideChar));
Have you tried WideString for passing the arguments to the function?
A WideString is equivalent to PWideChar, when passed to a subroutine, but a
typecast may be required if the compiler complains.

Probably you forgot to include the zero-terminator when converting the strings?
Such a terminator is appended by Delphi to all AnsiStrings and WideStrings.

var wPassword: WideString;
...
wPassword := Password;
...
if not CreateProcessWithLogonW(
...
PWideChar(wPassword),
...
wPassword := ''; //perhaps required to "free" the memory (not sure, but does no
harm)

DoDi

Loading...