views:

509

answers:

8

Hi

We have a suite of programs that check for new versions at startup, and then download new versions to run if required. This is obviously a problem in Windows 7, when it is locked down as a 'standard user', as they can't write to the c:\program files directory and below. Anyone seen a example of an application that gets around with issue ?

Our applications are written in Delphi, but an example in any language would be useful.

Thanks in advance

Update:

We already have a system for determing whether a new version exists, the only problem is the download and install (if required), as this requires elevation. I can't think of a way that doesn't require an elevation prompt, or our users to reduce their security settings.

Update 2 :

I've asked a subsequent question, rather than adding a new one here

+6  A: 

Typically what you will see an application do if it needs to escalate permissions is something like this.

  1. Application determines if upgrade is needed
  2. Application launches an "updater" service that requires "Administrator" permissions
  3. Application updates itself with this updated
  4. Application re-starts

This is a pretty common scenario, especially since to update your own DLL you need to go to a secondary process anyway.

Mitchel Sellers
+1  A: 

Or you can have it so that the user runs a launcher app.

  1. The application uses the LOCALAPPPATH\ folder to store a cache of the main application.
  2. Launcher checks to see if the internet has newer version of file(s) than the cached file.
  3. Launcher launches the cached application in LOCALAPPPATH
MarkRobinson
And if your launched application contains "setup" or "install" as part of its name it automatically is elevated (after a prompt of course), which allows it to write into those protected bits.
skamradt
@skamradt - perfect, yes - just remember it needs to be compiled with setup or install as part of the name, it can't be renamed after!
MarkRobinson
A: 

Your app can check if a new version is available on the remote server. If it does, then it can download update files in one of user-specific folders, like user's temp folder. You can get address of such special folders using SHGetSpecialFolder API function.

Once the download is done, you can pop up a dialog box telling user that you are ready for update. If user agrees with update, then you can run the updater process with elevated privileges (as administrator), and updater process can replace existing files in your installation path with the ones already downloaded in user Temp folder. To run your updater as administrator, you can use ShellExecute:

ShellExecute(0,'runas','notepad.exe',nil,nil,SW_SHOWNORMAL);

When updating is done, your updater process can restart your app.

vcldeveloper
Can you really elevate to admin privileges like this?
locster
You can not elevate a process which is already running, but you can start a new process which is elevated to admin privileges, and the code above does this.
vcldeveloper
+1  A: 

You need to have a separate executable to the updating work. The updater needs to have a manifest that marks it as requiring elevation.

See: http://msdn.microsoft.com/en-us/library/bb756929.aspx

Frederik Slijkerman
+5  A: 

There are two options for application installation:

  1. Application is available for all users: installation or update requires elevation for Windows Vista and up
  2. The application is available for one user: install or update the application in the user profile in %LOCALAPPDATA%, no elevation is required

Ad 2: Google Chrome does this. It installs the .exe here:

%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe

--jeroen

Jeroen Pluimers
Jeroen,This looks like nearly the right answer. Can I register typelibraries locally (for one user) as well ?
Mmarquee
You can, if you maintain your own registration mechanism. You can not if you use the default (system wide) registration mechanism. What kind of functionality do you want to register?
Jeroen Pluimers
We are registering typelibraries. It seems there is a win api call to do this per user that Delphi doesn't publish. We then use these typelibs to provide capabilities to allow use to aggregate our separate functionality into one 'application'. This we do currently but in xp we can get away with it, and in windows 7 we can't.
Mmarquee
+2  A: 

Here are some tips for you to get around updating challenges:

  1. If your file is names 'update.exe' or 'install.exe' then it will automatically force a UAC elevation prompt. This is an easy way to make existing software bypass Windows Vista/7 permissions.
  2. It is not a good idea to have the update checking and update process managed from within your application. The problem is that your app is likely to lock files and need updating itself. An external app should manage your updates.
  3. The simplest update solution is to make an HTTP call that checks for the current product version number, and then download the installer binary if necessary. This won't give you any flexibility in updates, but it is a quick and easy solution.

Our company sells software that specifically helps with automatic updates on Windows 7 UAC (you can visit AutoUpdate+ by clicking here: link text). The best reasons for using a third party solution - any solution - are that you will have more flexibility with your updates and also avoid the finicky challenges of supporting different Windows releases.

Simon E
+1  A: 

If your application uses MSI (Windows Installer) for its installer, then User Account Control Patching, if properly configured, can let you install updates without elevation.

Josh Kelley
A: 
  1. If your installer wasn't run under admin - you don't need any additional rights to install update.

  2. If your installer was run under admin - then it can create a task in Task Sheduler. Say, run this task once a week, under this account (admin) and with highest privs. Task will be your updater. Simple.

Alexander
See also: https://blogs.msdn.com/b/larryosterman/archive/2007/08/20/applet-mitigations-updaters.aspx
Alexander