We developed an ActiveX form control to be installed in IE8+. This control checks for a registry key then download and install a small setup if needed. For administrator everything work as expected on Windows 7 and 8 with any IE version 8+.
With non-admin users, the control runs (it must be installed by admin, but it's ok), it downloads the executable client_setup.exe
in path C:\users\user\AppData\Local\Temp\Low\ but when it tries to run executable (shellexec or createprocess produce same result) an administrative account is required and UAC elevation prompt appears.
If non-admin user download and install same setup, no administration privilege is required (we declared this in exe manifest). This setup is entirely installed in user profile and HKCU registry.
I understand that ActiveX control runs with low privileges like IE process. But why elevation is required in this case? Our setup do not requires privileges.
I tried to add ActiveX control in Low Rights elevation policy exceptions here
HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft\Internet Explorer\Low Rights\ElevationPolicy
but still UAC prompt appears.
I want to allow to run this setup for all users. We can run once as administrator a script to give permission for the whole system. Can someone help with this task?
TEST 1
As non-admin user, I tried to manually install the .exe downloaded by the ActiveX and I get a system error, cannot write to temp directory. If I download the same exe file with Internet Explorer I can install this with no problems.
I checked with ICACLS and on exe downloaded by ActiveX control there is a Mandatory Label\Low Mandatory Level:(I)(NW)
TEST 2
Site was added to trusted sites as Taxilian suggested. As non-admin user, ActiveX now saves .exe setup to C:\users\user\AppData\Local\Temp (no Low), .exe hasn't low level label anymore. But still, CreateProcess raises UAC prompt and fails.
This is my CreateProcess code. It's Delphi code but it should be readable.
function RunProcess(FileName: string; ShowCmd: DWORD; wait: Boolean; ProcID: PDWORD): Longword;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
StartupInfo.wShowWindow := ShowCmd;
if not CreateProcess(nil,
@Filename[1],
nil,
nil,
False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
nil,
nil,
StartupInfo,
ProcessInfo)
then
Result := WAIT_FAILED
else
begin
if wait = FALSE then
begin
if ProcID <> nil then
ProcID^ := ProcessInfo.dwProcessId;
result := WAIT_FAILED;
exit;
end;
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess, Result);
end;
if ProcessInfo.hProcess <> 0 then
CloseHandle(ProcessInfo.hProcess);
if ProcessInfo.hThread <> 0 then
CloseHandle(ProcessInfo.hThread);
end;
This is .exe manifest. It is a simple setup that copies some files to user profile and add a registry key in HKCU.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity name="JR.Inno.Setup" processorArchitecture="x86" version="1.0.0.0" type="win32" />
<description>Inno Setup</description>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
</application>
</compatibility>
</assembly>
CreateProcess
to try to launch the executable? DoesCreateProcess
return an error code? Have you tried using Process Monitor to track the sequence of events? – Harry JohnstonCloseHandle
event whenCreateProcess
fails? - you are not callingCloseHandle
whenWait=False
- if yourFilename
will contain spaces, and it won't be double-quoted, then you it will fail – Krystian Bigaj