From an application that is not being run as administrator, I have the following code:
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = myExePath;
proc.CreateNoWindow = false;
proc.UseShellExecute = false;
proc.Verb = "runas";
When I call Process.Start(proc), I do not get a pop up asking for permission to run as administrator, and the exe is not run as administrator.
I tried adding an app.manifest to the executable found at myExePath, and updated the requestedExecutionLevel to
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
With the updated app.manifest, on the Process.Start(proc) call, I get an exception, "The requested operation requires elevation."
Why isn't the .Verb action not setting administrator privileges?
I am testing on Windows Server 2008 R2 Standard.
You must use ShellExecute. ShellExecute is the only API that knows how to launch Consent.exe in order to elevate.
Sample (.NET) Source Code
In C#, the way you call ShellExecute is to use Process.Start along with UseShellExecute = true:
private void button1_Click(object sender, EventArgs e)
{
//Public domain; no attribution required.
ProcessStartInfo info = new ProcessStartInfo(#"C:\Windows\Notepad.exe");
info.UseShellExecute = true;
info.Verb = "runas";
Process.Start(info);
}
If you want to be a good developer, you can catch when the user clicked No:
private void button1_Click(object sender, EventArgs e)
{
//Public domain; no attribution required.
const int ERROR_CANCELLED = 1223; //The operation was canceled by the user.
ProcessStartInfo info = new ProcessStartInfo(#"C:\Windows\Notepad.exe");
info.UseShellExecute = true;
info.Verb = "runas";
try
{
Process.Start(info);
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ERROR_CANCELLED)
MessageBox.Show("Why you no select Yes?");
else
throw;
}
}
Bonus Watching
UAC - What. How. Why.. The architecture of UAC, explaining that CreateProcess cannot do elevation, only create a process. ShellExecute is the one who knows how to launch Consent.exe, and Consent.exe is the one who checks group policy options.
Related
I have found this via stack-overflow search but no one has given a solution that works. I am writing a simple program and the first part of it is to launch sysprep.exe with some arguments. For some reason sysprep does not launch when code is run. It gives an error that file cannot be found. For e.g. by using the code below Notepad will open with no issues. If I try and open sysprep it will not.
Process.Start(#"C:\Windows\System32\notepad.exe"); -- opens with no issue
Process.Start(#"C:\Windows\System32\sysprep\sysprep.exe"); -- does not open
Any help would be appreciated.
{
public MainWindow()
{
InitializeComponent();
}
private void RadioButton_Checked(object sender, RoutedEventArgs e)
{
if (radioButtonYes.IsChecked == true)
{
Process.Start(#"C:\Windows\System32\sysprep\sysprep.exe");
}
}
I see that another answer has worked for you, but I would like to include a different answer that will allow you to access files from System32 at any time. If you start with a public class to modify the kernel momentarily you should be able to access anything you need so long as you have the right permissions.
public class Wow64Interop
{
[DllImport("Kernel32.Dll", EntryPoint = "Wow64EnableWow64FsRedirection")]
public static extern bool EnableWow64FSRedirection(bool enable);
}
After this the way that i wrote out my call to sysprep was as follows
private void RunSysprep()
{
try
{
if (Wow64Interop.EnableWow64FSRedirection(true) == true)
{
Wow64Interop.EnableWow64FSRedirection(false);
}
Process Sysprep = new Process();
Sysprep.StartInfo.FileName = "C:\\Windows\\System32\\Sysprep\\sysprep.exe";
Sysprep.StartInfo.Arguments = "/generalize /oobe /shutdown /unattend:\"C:\\Windows\\System32\\Sysprep\\unattend.xml\"";
Sysprep.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
Sysprep.Start();
if (Wow64Interop.EnableWow64FSRedirection(false) == true)
{
Wow64Interop.EnableWow64FSRedirection(true);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
when doing something like this you want to make sure that if the process will restart your pc to NOT use the "WaitForExit()" method. Hope this helps anyone else looking for this answer.
It is actually a redirection problem on 64 bit Windows.
According to this discussion,
the System32 calls are redirected to the SysWOW64 folder.
And since C:\Windows\SysWOW64\Sysprep\sysprep.exe does not exist, you get the error.
This is what you want:
Process p = Process.Start(#"C:\Windows\sysnative\Sysprep\sysprep.exe");
Simply use sysnative instead.
I think this is a permission problem, you can try run as admin
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName ="cmd.exe";
startInfo.Arguments = #"/c C:\Windows\System32\sysprep\sysprep.exe";
startInfo.Verb = "runas";
process.StartInfo = startInfo;
process.Start();
I'm trying to make my program to run a bat file, that launches an exe file. It works fine on my local computer, but doesn't work on the server IIS. It doesn't work regardless of whether I specify the username and password in the ProcessStartInfo or not. I've searched forums and applied different stuff, but none of them help.
In Windows event viewer it doesn't give me any errors as well as the process output. If I change a directory and it can't find the bat file, the output gives me an error, but when it finds the file, it doesn't return anything and just doesn't launch the program.
Now, if I provide a credentials for the process, specifying psi.Domain, psi.UserName and psi. Password, the StandartOutput doesn't return any error, but Windows Events gives me two following errors:
Application popup: cmd.exe - Application Error : The application was unable to start correctly (0xc0000142). Click OK to close the application.
And
Application popup: conhost.exe - Application Error : The application was unable to start correctly (0xc0000142). Click OK to close the application.
Here's the code:
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(#"C:\inetpub\CopyToAD\pspasswd\passchange.bat");
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
psi.CreateNoWindow = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process listFiles;
listFiles = new System.Diagnostics.Process();
listFiles.EnableRaisingEvents = false;
listFiles.StartInfo = psi;
listFiles.Start();
System.IO.StreamReader myOutput = listFiles.StandardOutput;
listFiles.WaitForExit(2000);
myOutput.ReadToEnd();
string output = myOutput.ReadToEnd();
ViewBag.View6 += output + "***";
if (listFiles.HasExited)
{
output = myOutput.ReadToEnd();
ViewBag.View6 += output;
}
I´m having a problem with my ASP application. I´m getting an error from the cscript when I run a process on the server.
When I debug locally the page just works fine and the process is executed correctly, but when I deploy the application to the IIS and run it from another machine explorer it crashes when the process starts.
I imagine it was a matter of the user, so I added this line to the web.config, to ensure that.
<identity impersonate="true" userName="domain\user" password="password" />
Then, I added the user that I wanted the process to start with but the page keeps crashing. The error that I get in the server side each time the process is launch (when a button is pressed) is:
cscript.exe - Application Error
The application failed to initialize properly (0xc0000142). Click on OK to terminate the application
The code that launches the process is:
public static void actualizarPersona(csPersona persona)
{
string nombreArchivo = "card.js";
File.WriteAllText(nombreArchivo, persona.setFileActualizarPersona(persona), Encoding.GetEncoding(1252));
Process proc = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.FileName = "cscript.exe";
startInfo.Arguments = nombreArchivo;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UserName = "Administrator";
SecureString password = new SecureString();
string contraseña = "myPassword";
foreach (char c in contraseña)
{
password.AppendChar(c);
}
startInfo.Password = password;
proc.StartInfo = startInfo;
proc.Start();
proc.WaitForExit();
proc.Close();
proc.Dispose();
}
Does anyone have any idea of what may be happening?. I´ve been stuck here for a while today.
Thanks you.
You may need to load the user's profile
startInfo.LoadUserProfile = true
Edit
Try creating a new app pool with a a new admin account. If that works remove the user from the admin group and create a new group with the necessary permissions for the app.
(see trying to run a process from an asp.net application)
I want PDF file print into network print
Following code where used, it work fine in local host (development area) but not worked in IIS serve host
Can given to any rights issue? How to solve the issue ?
private void SendToPrinter()
{
ProcessStartInfo info = new ProcessStartInfo();
info.Verb = "print";
info.FileName = #"c:\output.pdf";
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process p = new Process();
p.StartInfo = info;
p.Start();
p.WaitForInputIdle();
System.Threading.Thread.Sleep(3000);
if (false == p.CloseMainWindow())
p.Kill();
}
It might be an authorization/security problem.
IIS (the server) runs in a context which doesn't have access to the shared printer.
Your local host has it cause it's running in your user's context.
This question already has answers here:
Elevating process privilege programmatically?
(6 answers)
Closed 6 years ago.
I have a Visual Studio Windows app project. I've added code to download an installer update file. The installer after it has finished downloading would need administrator privileges to run. I have added a manifest file.
When user clicks on the DownloadUpdate.exe, UAC prompts the user for Admin permissions. So I assumed that all processes created and called within DownloadUpdate.exe will run in admin capacity. So I made the setup call my downloaded file with the following code:
Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
p.StartInfo.FileName = strFile;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
Try this:
//Vista or higher check
if (System.Environment.OSVersion.Version.Major >= 6)
{
p.StartInfo.Verb = "runas";
}
Alternatively, go the manifest route for your application.
First of all you need to include in your project
using System.Diagnostics;
After that you could write a general method that you could use for different .exe files that you want to use. It would be like below:
public void ExecuteAsAdmin(string fileName)
{
Process proc = new Process();
proc.StartInfo.FileName = fileName;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.Verb = "runas";
proc.Start();
}
If you want to for example execute notepad.exe then all you do is you call this method:
ExecuteAsAdmin("notepad.exe");
This is a clear answer to your question:
How do I force my .NET application to run as administrator?
Summary:
Right Click on project -> Add new item -> Application Manifest File
Then in that file change a line like this:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Compile and run!
var pass = new SecureString();
pass.AppendChar('s');
pass.AppendChar('e');
pass.AppendChar('c');
pass.AppendChar('r');
pass.AppendChar('e');
pass.AppendChar('t');
Process.Start("notepad", "admin", pass, "");
Works also with ProcessStartInfo:
var psi = new ProcessStartInfo
{
FileName = "notepad",
UserName = "admin",
Domain = "",
Password = pass,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process.Start(psi);
This works when I try it. I double-checked with two sample programs:
using System;
using System.Diagnostics;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
Process.Start("ConsoleApplication2.exe");
}
}
}
using System;
using System.IO;
namespace ConsoleApplication2 {
class Program {
static void Main(string[] args) {
try {
File.WriteAllText(#"c:\program files\test.txt", "hello world");
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
}
}
First verified that I get the UAC bomb:
System.UnauthorizedAccessException:
Access to the path 'c:\program
files\test.txt' is denied. //
etc..
Then added a manifest to ConsoleApplication1 with the phrase:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
No bomb. And a file I can't easily delete :) This is consistent with several previous tests on various machines running Vista and Win7. The started program inherits the security token from the starter program. If the starter has acquired admin privileges, the started program has them as well.
Here is an example of run process as administrator without Windows Prompt
Process p = new Process();
p.StartInfo.FileName = Server.MapPath("process.exe");
p.StartInfo.Arguments = "";
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Verb = "runas";
p.Start();
p.WaitForExit();
Process proc = new Process();
ProcessStartInfo info =
new ProcessStartInfo("Your Process name".exe, "Arguments");
info.WindowStyle = ProcessWindowStyle.Hidden;
info.UseShellExecute =true;
info.Verb ="runas";
proc.StartInfo = info;
proc.Start();
Use this method:
public static int RunProcessAsAdmin(string exeName, string parameters)
{
try {
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = CurrentDirectory;
startInfo.FileName = Path.Combine(CurrentDirectory, exeName);
startInfo.Verb = "runas";
//MLHIDE
startInfo.Arguments = parameters;
startInfo.ErrorDialog = true;
Process process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
return process.ExitCode;
} catch (Win32Exception ex) {
WriteLog(ex);
switch (ex.NativeErrorCode) {
case 1223:
return ex.NativeErrorCode;
default:
return ErrorReturnInteger;
}
} catch (Exception ex) {
WriteLog(ex);
return ErrorReturnInteger;
}
}
Hope it helps.
You probably need to set your application as an x64 app.
The IIS Snap In only works in 64 bit and doesn't work in 32 bit, and a process spawned from a 32 bit app seems to work to be a 32 bit process and the same goes for 64 bit apps.
Look at: Start process as 64 bit