-1

I try to execute a single DLL in admin context to force the user to enter UAC when calling a method in case that he is authenticated as a normal user.

I have found the suggestion here: Visual Basic Program - Ask for Admin Permissions

I have tried to create what Nathan M has suggested but I don't get the UAC control displayed.

This is the code I'm using:

Main application:

Imports System
Imports System.Diagnostics.Eventing.Reader
Imports GetUninstallToken.UninstallToken

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            Dim t As New GetToken
            t.Test()
        Catch ex As Exception
        End Try
    End Sub

I have added a simple DLL file to the project just for getting the authentication dialog:

Namespace UninstallToken
    Public Class GetToken
        Public Sub Test()
            MsgBox("Test")
        End Sub
    End Class
End Namespace

And I have created a manifest file which should apply to the DLL with this configuration

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
             If you want to change the Windows User Account Control level replace the 
             requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Specifying requestedExecutionLevel element will disable file and registry virtualization. 
            Remove this element if your application requires this virtualization for backwards
            compatibility.
        -->
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>

The project looks like this:

enter image description here

So when I run the program and click the button the DLL is invoked and the MsgBox is displayed but there is no UAC - I'm not running VS as Admin.

Any Ideas what I'm missing? It seems as if the manifest file might be ignored...

I'm using Microsoft Visual Studio Community 2019 Version 16.5.4 on Win 10 19H2 - I execute as normal user.

GSerg
  • 76,472
  • 17
  • 159
  • 346
  • Does this answer your question? [Requested Execution Level for a dll](https://stackoverflow.com/questions/1882906/requested-execution-level-for-a-dll) – GSerg May 21 '21 at 10:56
  • Hi @GSerg thanks for that info. Actually that didn't come up when I was searching and the answer is actually different to what I found berfore (I think)... Will check the rundll stuff to see if that does help somehow. Thx Daniel – Daniel Schmitz May 21 '21 at 12:55
  • [What's the guidance on when to use rundll32? Easy: Don't use it](https://devblogs.microsoft.com/oldnewthing/20130104-00/?p=5643) – Bill_Stewart May 21 '21 at 19:08
  • The answer linked in the first comment on this question is correct: There's no such thing as "running a DLL as an administrator" because DLLs contains code that are executed by processes, and only a process can be elevated. As the other answer says: If you need code in your DLL to run elevated, write an executable that calls the code in the DLL, and run the executable elevated. – Bill_Stewart May 21 '21 at 20:04

1 Answers1

0

This is what I came up with finally:

  1. I have generated a new EXE which contains the requested sub functionality

  2. I have added a manifest file setting the execution context to "requireAdministrator"

  3. I call that exe in the main application using this code:

    Try
         Dim process As System.Diagnostics.Process = Nothing
         Dim processStartInfo As System.Diagnostics.ProcessStartInfo
         processStartInfo = New System.Diagnostics.ProcessStartInfo()
         processStartInfo.FileName = ".\MyApplication.exe"
         processStartInfo.Verb = "runas"
    
         processStartInfo.Arguments = ""
         processStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
         processStartInfo.UseShellExecute = True
         process = System.Diagnostics.Process.Start(processStartInfo)
    
     Catch ex As Exception
         MsgBox("You need to be administrator to request this function")
     End Try
    

This way I do receive a UAC prompt when invoking the function and if not the user is presented with an error message.

Might not be the most elegant thing but simple and working ;)