using StartInfo.Verb = "runas"

ismu

Member
Joined
Nov 11, 2010
Messages
6
Programming Experience
Beginner
Hi!

At some point in my application, I do a "Analyze disk" using the defrag command with attribute "-a -v". The application works fine in Win XP, but in Win 7, the command don't seems to be executed at all!

Doing some research, I found that I need to add "StartInfo.Verb = "runas" " to run my defrag as administrator. But this don't seems to be enough because I still get a NullReferenceException(clsProcess.StandardOutput seems to return nothing). Maybe someone can help me on this...


VB.NET:
                    Dim clsProcess As New System.Diagnostics.Process()
                    clsProcess.StartInfo.UseShellExecute = False
                    clsProcess.StartInfo.RedirectStandardOutput = True
                    clsProcess.StartInfo.RedirectStandardError = True
                    clsProcess.StartInfo.FileName = "defrag"
                    clsProcess.StartInfo.Arguments = driveLetter & ": -a -v"
                    clsProcess.StartInfo.CreateNoWindow = True
                    ' Check if system is Windows Vista or higher
                    If System.Environment.OSVersion.Version.Major >= 6 Then
                        clsProcess.StartInfo.Verb = "runas"
                    Else
                        ' No need to prompt to run as admin
                    End If
                    clsProcess.Start()
                    clsProcess.WaitForExit()

                    Dim sLine As String = clsProcess.StandardOutput.ReadLine
                    Dim limit As Integer = 0
                    ' Tried to skip every empty line at the beginning...
                    While sLine = Nothing
                        sLine = clsProcess.StandardOutput.ReadLine
                        limit += 1
                        If limit > 50 Or sLine <> Nothing Then
                            Exit While
                        End If
                    End While
                    limit = 0
                    Try
                        While Not sLine.Contains("Average fragments per file")
                            sLine = clsProcess.StandardOutput.ReadLine
                            limit += 1
                            If limit > 50 Or sLine Is Nothing Then
                                Exit While
                            End If
                        End While
                        sLine = sLine.Trim()
                    Catch ex As Exception
                        If sLine = Nothing Then
                            MsgBox("sline empty!!!")                       
                        End If
                        MsgBox(ex.ToString)
                    End Try

Thanks in advance!
 
To be clear, Verb="runas" is a directive to elevate UAC privilegies, ie to allow a UAC limited admin account full rights. It doesn't grant rights the user doesn't have access to, but it should prompt for administrator credentials when current user is not. This verb requires UseShellExecute=True.

What you can do is to require your app to run with admin rights by using a manifest. In VB 2010 and 2008 this is 'ready-made' from project settings, but I can't recall 2005 having that. Here's an article about it: Step 6: Create and Embed an Application Manifest (UAC)
 
Added manifest but still not working.

Hi JohnH!

I changed the property of UseShellExecute to True and I added a manifest to by software, but I'm not sure if I done it right. I use VS2005 so it's not straight forward as VS2008 and later seems to be.

Here's the manifest I used :

Analyze Disk.exe.manifest
HTML:
<?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="Analyze Disk"
     type="win32"/> 
  <description>Analyze Disk Software description</description> 
  <!-- Identify the application security requirements. -->
  <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft- 
     com:asm.v2">
      <ms_asmv2:security>
         <ms_asmv2:requestedPrivileges>
            <ms_asmv2:requestedExecutionLevel level="asInvoker">
            </ms_asmv2:requestedExecutionLevel>
         </ms_asmv2:requestedPrivileges>
      </ms_asmv2:security>
   </ms_asmv2:trustInfo>
</assembly>

I put the manifest into the solution explorer under my project.

Then, in the my project property, I add this post-build command :

mt.exe -manifest "$(ProjectDir)$(TargetName).exe.manifest" "-outputresource:$(TargetDir)$(TargetName).exe;#1"

Then when I build my project mt.exe gives me this result(witch seems ok...) :
VB.NET:
mt.exe -manifest "C:\Working\E2596_TVSS\Analyze\Analyze_VB\Analyze\Analyze Disk.exe.manifest" "-outputresource:C:\Working\E2596_TVSS\Analyze\Analyze_VB\Analyze\bin\Release\Analyze Disk.exe;#1"
Microsoft (R) Manifest Tool version 5.2.3790.2075

Copyright (c) Microsoft Corporation 2005. 

All rights reserved.

========== Build: 4 succeeded or up-to-date, 0 failed, 0 skipped ==========

When I run my software, I still get the same error as the begining...

Any other idea of what my problem could be?

Thanks in advance!
 
I realized that I need UseShellExecute = False because I use the RedirectStandardOutput = True.

So it it possible to use the runas at the same time as redirecting IO streams ?
 
No, what I meant was you can use manifest instead of runas to have the app run as elevated admin to begin with. This will allow you to use ShellExecute=False in elevated context.
 
How do I know my manifest is correctly added?

Good news for me then!

Because manifest concept is new to me, I have two questions :

1) How can I know that my manifest is correctly set in my project? As I wrote in a previous post, I added a manifest, but my app behave as when it didn't had a manifest. I was thinking that adding this manifest would, for example, pop-up a UAC windows, like when we select Run as administrator on an app.

2) If I right-click on my application and chose "Run as Administrator" is it supposed to do the same effect as adding a manifest to my app? (I tried and got the same error...)

Note: in my manifest(see previous post) I changed this line :
<ms_asmv2:requestedExecutionLevel level="asInvoker">
to
<ms_asmv2:requestedExecutionLevel level="requireAdministrator" uiAccess="false">
 
I used ildasm.exe on my application hoping to find some keywords related to my manifest (ex "requireAdministrator", "requestedPrivileges" etc) but I don't find any trace of my manifest : is it a hint that I didn't correctly add the manifest to my project?
 
1) How can I know that my manifest is correctly set in my project? As I wrote in a previous post, I added a manifest, but my app behave as when it didn't had a manifest.
Don't know, I have never used it yet.
I was thinking that adding this manifest would, for example, pop-up a UAC windows, like when we select Run as administrator on an app. 2) If I right-click on my application and chose "Run as Administrator" is it supposed to do the same effect as adding a manifest to my app? (I tried and got the same error...)

Note: in my manifest(see previous post) I changed this line :
<ms_asmv2:requestedExecutionLevel level="asInvoker">
to
<ms_asmv2:requestedExecutionLevel level="requireAdministrator" uiAccess="false">
Yes, that's the effect, where the manifest is a way of telling runtime automatically that is required. Yes, requireAdministrator is what you need.
 
I used ildasm.exe on my application hoping to find some keywords related to my manifest (ex "requireAdministrator", "requestedPrivileges" etc) but I don't find any trace of my manifest : is it a hint that I didn't correctly add the manifest to my project?
This article talks about ildasm and manifest information: How to: View Assembly Contents
 
I did a test with the built in UAC configuration in VB 2010 and it works when UAC is enabled, if not is has no effect. I checked both these cases; admin is asked to elevate, and regular user is asked for admin credentials. The app icon was also added the "UAC shield", and this should be a visible indication that the manifest instruction has taken effect.
 
Thanks for the info, now I'm sure that the manifest instructions are not working... still searching.

Do you think I need to set the build action of the manifest file to "Embeded Ressource" ? When I compile the project with this setting, the file Analyze.Analyze Disk.exe.manifest is created (I was thinking that the manifest file would be merged into the exe file.)
 
No, the manifest is added to the PE file after assembly is compiled.

Without you wasting too much time on this manifest stuff, first make sure you get things working when running the .exe manually with the "run as administrator" option, since this is the same thing and doesn't require you to do anything.
 
Back
Top