-2

I want to install the Microsoft SQL Server Native Client in a self-written installer. The database driver is to be installed once on first launch.

My problem is that on some computers, the driver installation is not performed if my program is not running as administrator.

If my program is not running as an administrator, I get with 'runas' in ShellExecute Admin rights. The request for admin rights appears, but then on some computers the installation of the driver is not being executed.

function shellExec (APath, AParameter: String) : Boolean;
  rslt := ShellExecute (0, pChar('runas'), pChar(APath), pChar(AParameter), pChar(''), SW_SHOWNORMAL);
  result := ( rslt > 32 );
end;

shellExec('msiexec.exe', '-i' + MsiInstaller + ' /qn IACCEPTSQLNCLILICENSETERMS=YES');
// MsiInstaller = Path to NativeClient-Installer

Then I give the program with Sleep (20000) 20 seconds time, so that the installation can be performed. In normal fast computers, the installation takes 2-4 seconds, so the generously dimensioned 20 seconds should not be a problem.

For clarity, I have the error evaluation off "rslt" omitted here in the post. Of course its added in my code. But I do not get any error codes.

Has anyone any idea why the installation works when the program is started with admin rights, but not when it is requesting Admin rights themselves?

If the program is started with admin rights, no second message is shown for the admin rights for the driver installation.

Question: How to ensure that the installer is always executed, and my program does not need to be started with admin rights?

Johan
  • 71,222
  • 23
  • 174
  • 298
  • Duplicate topic. You can check if you need admin rights, execute as admin if needed and wait for installation complete ... http://stackoverflow.com/questions/923350/delphi-prompt-for-uac-elevation-when-needed/28572886#28572886 – smooty86 Feb 26 '16 at 10:32
  • 6
    Bad idea, installs should happen at install time not during launch. Write a seperate installer (that requires admin privileges) but make sure that the actual application can run with user privileges. – Remko Feb 26 '16 at 11:33

2 Answers2

1

There are two possible scenarios why this could happen

  1. The path is not accessible for the administrator account. Typical when running from a mapped network drive and the mapping is unknown to the administrator account.

  2. You try to install the x86 version of the native client on a x64 OS. You must not install the x86 client on x64 OS and the x64 client on a x86 OS.

With the commandline parameter /qn you hide any output from the installer including the fails. For debugging you can switch to /qb which will just show a small progress window when installing but also error messages if any occur.

To get the real OS version call GetNativeSystemInfo and check SYSTEM_INFO.wProcessorArchitecture

var
  inf: SYSTEM_INFO;
  plt: string;
  msi: string;

GetNativeSystemInfo( inf );
case inf.wProcessorArchitecture of
  PROCESSOR_ARCHITECTURE_INTEL: plt := 'x86';
  PROCESSOR_ARCHITECTURE_AMD64: plt := 'x64';
else
  raise ENotSupportedException.Create( 'Platform not supported.' );
end;

msi := '<PathToNativeClient>\' + plt + '\sqlncli.msi';
Sir Rufo
  • 16,671
  • 2
  • 33
  • 66
0

I'm suggest you to embed Admin manifest into your installer (see link below), so it will run always elevated.

In your case, you check only result code of ShellExecute, but not msiexec.exe, so installer can start fine, but fail during installation process. You need to check result code for msiexec.exe itself:

First of all, use ShellExecuteEx and wait for termination (do not use sleep!), you can read more about this solution. Before closing handle, you may read exit code:

GetExitCodeProcess(shExInfo.hProcess,rslt);

Now analyze msiexec.exe result code to decide it installed successfully.

Community
  • 1
  • 1