Cyotek Development Bloghttps://devblog.cyotek.com/tag/permissions/atom.xml2011-11-27T11:52:13ZDetecting if an application is running as an elevated process, and spawning a new process using elevated permissionsurn:uuid:cf279d2c-631e-4759-b8fc-43682c746c572011-11-27T11:52:13Z2011-11-27T11:39:44Z<p>Recently I was writing some code to allow a program to register
itself to start with Windows for all users. On Windows 7 with
User Account Control (UAC) enabled, trying to write to the
relevant registry key without having elevated permissions throws
an <code>UnauthorizedAccessException</code> exception. If you want to make
these sorts of modifications to a system, the application needs
to be running as an administrator.</p>
<h2 id="checking-if-your-application-is-running-with-elevated-permissions">Checking if your application is running with elevated permissions</h2>
<p>To check if your application is currently running with elevated
permissions, you simply need to see if the current user belongs
to the <code>Administrator</code> user group.</p>
<figure class="lang-csharp highlight"><figcaption><span>csharp</span></figcaption><pre class="code">
<span class="comment">// Requires &quot;using System.Security.Principal;&quot;</span>

<span class="keyword">public</span> <span class="keyword">bool</span> IsElevated
<span class="symbol">{</span>
 <span class="keyword">get</span>
 <span class="symbol">{</span>
 <span class="keyword">return</span> <span class="keyword">new</span> WindowsPrincipal<span class="symbol">(</span>WindowsIdentity<span class="symbol">.</span>GetCurrent<span class="symbol">(</span><span class="symbol">)</span><span class="symbol">)</span><span class="symbol">.</span>IsInRole<span class="symbol">(</span>WindowsBuiltInRole<span class="symbol">.</span>Administrator<span class="symbol">)</span><span class="symbol">;</span>
 <span class="symbol">}</span>
<span class="symbol">}</span>

<span class="keyword">public</span> <span class="keyword">void</span> SomeMethod<span class="symbol">(</span><span class="symbol">)</span>
<span class="symbol">{</span>
 <span class="keyword">if</span> <span class="symbol">(</span><span class="keyword">this</span><span class="symbol">.</span>IsElevated<span class="symbol">)</span>
 <span class="symbol">{</span>
 <span class="comment">// running as administrator</span>
 <span class="symbol">}</span>
<span class="symbol">}</span>
</pre>
</figure>
<h2 id="running-an-application-as-an-administrator">Running an application as an administrator</h2>
<p>While it might be possible to elevate your applications process
via the <code>LogonUser</code> API, this requires user names and passwords,
and isn't a trivial task. So we'll ignore this approach in
favour of something much more simplistic and less likely to go
wrong, not to mention not requiring admin passwords.</p>
<p>You're probably already aware that there are various &quot;verbs&quot;
predefined for dealing with specific actions relating to
interaction with a file, such as <code>print</code> and <code>open</code>. While these
verbs are normally configured on file associations in the
Windows Registry, you can also force a process to be run under
the administration account by specifying the <code>runas</code> verb.</p>
<blockquote>
<p>Note: Specifying this verb in Windows XP displays a dialog
allowing a user to be selected. Unfortunately this means that
it's possible for the spawned application to not have the
required permissions either - remember to check that you have
permission to do an action before actually attempting it!</p>
</blockquote>
<p>For my scenario, the core application shouldn't need to run in
elevated mode, so I decided to create a generic stub program
which would accept a number of arguments for if the startup
program should be registered or unregistered, and the title and
location used to perform the action. Then the main application
simply spawned this process in administration mode to apply the
users choice.</p>
<figure class="lang-csharp highlight"><figcaption><span>csharp</span></figcaption><pre class="code">
ProcessStartInfo startInfo<span class="symbol">;</span>

startInfo <span class="symbol">=</span> <span class="keyword">new</span> ProcessStartInfo<span class="symbol">(</span><span class="symbol">)</span><span class="symbol">;</span>
startInfo<span class="symbol">.</span>FileName <span class="symbol">=</span> Path<span class="symbol">.</span>Combine<span class="symbol">(</span>Path<span class="symbol">.</span>GetDirectoryName<span class="symbol">(</span>Application<span class="symbol">.</span>ExecutablePath<span class="symbol">)</span><span class="symbol">,</span> <span class="string">&quot;regstart.exe&quot;</span><span class="symbol">)</span><span class="symbol">;</span> <span class="comment">// replace with your filename</span>
startInfo<span class="symbol">.</span>Arguments <span class="symbol">=</span> <span class="keyword">string</span><span class="symbol">.</span>Empty<span class="symbol">;</span> <span class="comment">// if you need to pass any command line arguments to your stub, enter them here</span>
startInfo<span class="symbol">.</span>UseShellExecute <span class="symbol">=</span> <span class="keyword">true</span><span class="symbol">;</span>
startInfo<span class="symbol">.</span>Verb <span class="symbol">=</span> <span class="string">&quot;runas&quot;</span><span class="symbol">;</span>

Process<span class="symbol">.</span>Start<span class="symbol">(</span>startInfo<span class="symbol">)</span><span class="symbol">;</span>
</pre>
</figure>
<blockquote>
<p>Note: Although I haven't included it in the example above, you
may wish to handle the <code>Win32Exception</code> that can be thrown by
the <code>Process.Start</code> method. If the user cancels the UAC
prompt, this exception will be automatically thrown with the
<code>ERROR_CANCELLED</code> (1223) error code.</p>
</blockquote>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/uac-prompt.png" class="gallery" title="An example of a UAC prompt for an unsigned application" ><img src="https://images.cyotek.com/image/thumbnail/devblog/uac-prompt.png" alt="An example of a UAC prompt for an unsigned application" decoding="async" loading="lazy" /></a><figcaption>An example of a UAC prompt for an unsigned application</figcaption></figure>
<p>With the <code>runas</code> verb specified, the application is now run in
elevated mode, and the operating system asks the user for
permission to continue. Unfortunately, if your application isn't
signed, then you get a scarier version of the prompt, as
displayed above. If your application is signed, then you'll get
something similar to the screenshot below.</p>
<figure class="screenshot" ><a href="https://images.cyotek.com/image/devblog/uac-prompt-signed.png" class="gallery" title="An example of a UAC prompt for a properly signed application" ><img src="https://images.cyotek.com/image/thumbnail/devblog/uac-prompt-signed.png" alt="An example of a UAC prompt for a properly signed application" decoding="async" loading="lazy" /></a><figcaption>An example of a UAC prompt for a properly signed application</figcaption></figure><h2 id="update-history">Update History</h2>
<ul>
<li>2011-11-27 - First published</li>
<li>2020-11-21 - Updated formatting</li>
</ul>

<p><small>
All content <a href="https://devblog.cyotek.com/copyright-and-trademarks">Copyright (c) by Cyotek Ltd</a> or its respective writers. Permission to reproduce news and web log entries and other RSS feed content in unmodified form without notice is granted provided they are not used to endorse or promote any products or opinions (other than what was expressed by the author) and without taking them out of context. Written permission from the copyright owner must be obtained for everything else.<br />Original URL of this content is https://devblog.cyotek.com/post/detecting-if-an-application-is-running-as-an-elevated-process-and-spawning-a-new-process-using-elevated-permissions .
</small></p>Richard Mosshttps://www.cyotek.com/richard.moss@cyotek.com