Windows UAC and Elevation

From HashVB
Revision as of 12:39, 10 March 2010 by Dee (Talk | contribs)

Jump to: navigation, search
float
 This article is based on Visual Basic 6. Find other Visual Basic 6 articles.
 This article is currently work in progress. Please come back later.

Windows Vista now has a feature to stop regular "admin" users running with full access all the time. This is called User Account Control (UAC) and requires the user to confirm whether to allow an application to "elevate" to full admin access or not.

This can be set per executable/process by using a Vista aware manifest:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="X86"
    name="company.product"
    type="win32"
  />
  <description>Product name</description>

  <!-- Vista aware, Admin privileges needed -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"
        />
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>

This method works were the entire application needs elevation from the very beginning. If you do NOT want to be elevated for the life of the process but require access at the users request, you will need to shell out to another process with the above manifest or use the COM Elevation moniker.

COM elevation

To do this in VB, you need to have an out of process COM object (ActiveX EXE) with the manifest as above. You then need find the objects Class ID in the registry under the HKCR hive. In here, you need to add the "LocalizedString" string value to the registry containing a dll/exename and string resource ID to load the name from of the format:

@modulename,-resourceid

In addition to this, you need to create an "Elevation" key containing the DWORD value "Enabled" set to 1.

Once the registry has been set as necessary, you can use this code in VB to create an instance of the object when needed:

Set VarName = GetObject("Elevation:Administrator!new:LibraryName.ClassName")

Please note that this does NOT work on anything before Vista so you need to check the Windows version prior to calling this method. If running on 2K or XP, you can safely use just CreateObject()

See also