Reputation: 1957
Much as it is possible to use ExecAsOriginalUser
to run something using the starting/logged in user's credentials, is there a command or way to run a particular piece of code as a specific user?
To explain further, I am writing the computer name into a log on a file share at the end of installation. This works perfectly as long as not installing using a local Administrator account which does not have a matching local Administrator account on the server. Therefore, what I need to do is have the particular bit of code that writes to the log execute as a specific user account, which I have the credentials for, that I know exists on the server.
The code I am using is as follows:
// Auto audit the computer name
procedure AutoAudit();
var
strComputerName: TArrayOfString;
strAutoAuditFile: String;
begin
strAutoAuditFile :=
'\\' + ClientConnectionPage.Values[0] + '\Audit\Client Audit.txt';
SetArrayLength(strComputerName, 1);
strComputerName[0] :=
ExpandConstant('{computername} ') +
GetDateTimeString('dd/mm/yyyy hh:mm', '/', ':');
SaveStringsToFile(strAutoAuditFile, strComputerName, True);
end;
So, what I need is a way of executing the SaveStringsToFile
function as another user.
I have thought of a rather messy way to do this, which would involve testing for an available drive letter, mapping a drive using the account credentials, writing to the file and then disconnecting the drive. However, I am hoping there is a more elegant way to do this?
Upvotes: 4
Views: 2657
Reputation: 202088
You have to use the LogonUser
WinAPI function to run a piece of code as a different account.
It's likely possible to run this from an Inno Setup code, but I haven't found an example.
Alternatively, you can develop a separate tiny application that impersonates the other user and embed the application into your installer.
In C#/VB.NET, you can use the Impersonator
class (which uses the LogonUser
internally):
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
using (new Impersonator("username", "domain", "password"))
{
string strAutoAuditFile = @$"\\{args[0]}\Audit\Client Audit.txt";
string strComputerName =
Environment.MachineName + " " +
DateTime.Now.ToString("dd/mm/yyyy hh:mm");
File.WriteAllText(strAutoAuditFile, strComputerName);
}
}
}
Run the application from Inno Setup like:
[Files]
Source: "getcompname.exe"; Flags: dontcopy
[Code]
...
var
ResultCode: Integer;
begin
...
ExtractTemporaryFile('getcompname.exe');
ExecAsOriginalUser(
ExpandConstant('{tmp}') + '\getcompname.exe ',
ClientConnectionPage.Values[0],
'', SW_HIDE, ewWaitUntilTerminated, ResultCode);
...
end;
If you are not experienced with a console application development, note that the "tiny" application can be even a batch file with use of the runas
command (which does not allow specifying password automatically) or the PsExec
(which does).
Upvotes: 3