Start second instance of Application as Admin - c#

I want my application not to need an Admin to use it.
I should be usable for a normal user.
When a user wants to change some settings of the app I need Admin Rights.
So I want to launch a second instance of the application which requires Admin Rights.
(with user agreement request and so on)
Is there any way to accomplish that?
I tried:
Process p = new Process();
p.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p.StartInfo.FileName = Application.ExecutablePath;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
if (System.Environment.OSVersion.Version.Major >= 6)
{
p.StartInfo.Verb = "runas";
}
p.Start();
But it seems not to work.

You can to create an account with admin rights,
Then populate the user,password properties on the ProcessStartInfo instance with the corresponding values for the admin account.
Something like:
var psi = new ProcessStartInfo
{
FileName = "notepad.exe",
UserName = "admin",
Domain = "",
Password = pass,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process.Start(psi);

Turns out i have to use the UseShellExecute in the ProcessStartInfo and not the Process.
More explanation here.
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.WorkingDirectory = Environment.CurrentDirectory;
proc.FileName = Application.ExecutablePath;
proc.Verb = "runas";
try
{
Process.Start(proc);
}
catch
{
return; //U have a BIG problem!
}

Related

C# How to run exe in PowerShell

I want to run mc.exe using by PowerShell as I write below.
How can I do that? I tried to add in Filename but it doesn't work.
var mcExe = #"C:\Users\developer\Desktop\Example\mc.exe ";
var proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = mcExe;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Verb = "runas";
proc.StartInfo.Arguments = String.Format("{0}{1}{2}", "./mc alias set myCloud http://localhost:9000", "admin", "123456");
proc.Start();
Did you try set proc.StartInfo.UseShellExecute = true; ?
Because this property responsible for using powershell
Starting Powershell directly might work for you, e.g. :
using System.Diagnostics;
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = #"powershell.exe",
Arguments = #"& 'C:\Users\developer\Desktop\Example\mc.exe' #('./mc alias set myCloud http://localhost:9000', 'admin', '123456')",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
Verb = "runas",
};
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
string output = process.StandardOutput.ReadToEnd();
string errors = process.StandardError.ReadToEnd();

Installing a MSI as administrator silently

I am trying to create an application which will install the msi from the c# windows application, here i wanna take the input from user for UserName, Domain and password so that i can run the application in that user account. in the below code if i only give startInfo.Verb = "runas" its working but i want to provide the user name and password of admin and run it. can you guyz help me out.
private void InstallProbe()
{
try
{
bool gdfg= IsRunAsAdmin();
//processObj.InitializeProcess(txtUserName.Text, txtPassword.Text);
string installcmd = "/c msiexec /i \"{0}\" /quiet TARGETDIR=\"{1}\" HOST=\"{2}\" PORT=\"{3}\" USEHTTPS=\"{4}\" STEALTHMODE=\"{5}\" ORGCODE=\"{6}\"";
installcmd = string.Format(installcmd, txtFilePath.Text, #"%PROGRAMFILES%\ProHance Mate", "services.jamochatech.com", "8080", false, 0, "PHSALE");
string uname, domain = string.Empty;
//RunCommand("cmd", installcmd, processObj);
if (txtUserName.Text.IndexOf("\\") > 0)
{
string[] strarr = txtUserName.Text.Split('\\');
uname = strarr[1];
domain = strarr[0];
}
else
{
uname = txtUserName.Text;
domain = ".";
}
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
//startInfo.Verb = "runas";
startInfo.Domain = domain;
startInfo.UserName = uname;
startInfo.Password = ToSecureString(txtPassword.Text);
startInfo.FileName = "cmd";
startInfo.Arguments = installcmd;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
MessageBox.Show(installcmd);
process.StartInfo = startInfo;
process.Start();
process.WaitForExit(60000);
}
catch (Exception ex)
{
MessageBox.Show("Exception occured while installing the ProHance Mate " + ex.Message);
}
}
Disregarding the MSI context, you are simply trying to launch a new process (msiexec.exe) under a specific user context. Check the thread below and others alike.
In Windows: How do you programatically launch a process in administrator mode under another user context?

.Net Core open external terminal

I'm migrating batch script to .Net core and I'm trying to open another terminal from current terminal and run a command (I don't need stderr o stout).
With batch only needs this command: start cmd /K gulp. I'm trying to do the same with .Net core but only found the way to run the command inside current terminal.
private static string Run (){
var result = "";
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "cmd.exe";
startInfo.Arguments = $"/c \"gulp browserSync\"";
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
using (Process process = Process.Start(startInfo))
{
result = process.StandardError.ReadToEnd();
process.WaitForExit();
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
Console.ReadKey();
}
return result;
}
I'm trying changing this properties in order to open in another terminal:
startInfo.RedirectStandardOutput = false;
startInfo.RedirectStandardError = false;
startInfo.UseShellExecute = true;
But make an exception:
UseShellExecute must always be set to false.
From the MSDN docs:
UseShellExecute must be false if the UserName property is not null or an empty string, or an InvalidOperationException will be thrown when the Process.Start(ProcessStartInfo) method is called.
startInfo.UserName = null;
edit: I'm not sure why you have to pass in the arguments, but if all you want is a new CMD window try this:
try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = #"C:/users/replace/where_gulp_is_located",
Arguments = #"/c gulp", // add /K if its required, I don't know if its for gulp for to open a new cmd window
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true
};
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
if (showOut)
{ ///code }
}catch(Exception ex)
{
Console.WriteLine(ex);
}
You wont need startInfo.UserName in this case because you are specifying a working directory.
Thanks to #bender-bending answer I found a way to solve it. Due security limitations need user/password credentials in order to autorice current terminal to open a new one.
WorkingDirectory, user, password and domain are required.
Create no window, redirect output and redirect error must be false, in order to see command result in new window.
public static void Sample(){
try
{
Console.Write("Password: ");
StringBuilder password = new StringBuilder();
while (true)
{
var key = System.Console.ReadKey(true);
if (key.Key == ConsoleKey.Enter) break;
password.Append(key.KeyChar);
}
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = "C:/path_to/Gulp",
Arguments = $"/c \"gulp browserSync\"",
UseShellExecute = false,
RedirectStandardOutput = false,
RedirectStandardError = false,
UserName = Machine.User(),
PasswordInClearText = password.ToString(),
Domain = Machine.Domain(),
CreateNoWindow = false
};
Process proc = new Process();
proc.StartInfo = startInfo;
proc.Start();
//proc.WaitForExit();
} catch (Exception ex)
{
System.Console.WriteLine(ex);
System.Console.ReadKey();
}
}
.Net Core doesn't have a method to obtain user and domain. We can use this class to get this values from environment variables.
public static class Machine
{
public static string User(){
return Environment.GetEnvironmentVariable("USERNAME") ?? Environment.GetEnvironmentVariable("USER");
}
public static string Domain(){
return Environment.GetEnvironmentVariable("USERDOMAIN") ?? Environment.GetEnvironmentVariable("HOSTNAME");
}
}
Hope it helps!

How to give 2nd input to a '.exe' file after the Process.start method is called?

I have to execute a '.exe' file which produces a output and asks for another input again. I am able to run the first part but I am not able to pass the second parameter to complete the process.
Here is my code:
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Context.exe";
startInfo.Arguments = "xyz";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
Process.Start(startInfo);
I would use StandardInput in conjunction with RedirectStandardInput. You can pass any data that a user would enter on the command line using this StandardInput StreamWriter object. If this application has a user interface, you may need to do something else entirely.
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = #"C:\Context.exe";
startInfo.Arguments = "xyz";
startInfo.UseShellExecute = false;
startInfo.CreateNoWindow = true;
startInfo.RedirectStandardInput = true;
var p = Process.Start(startInfo);
// Write whatever data you need to send to the application here.
p.StandardInput.Write("y");
You can use startInfo.RedirectStandardInput. See here for more details

What is wrong in how I start the process?

When I run the following from cmd it runs ok
>mysql -h 134.86.157.132 -u sas vm < c:\vm.sql
When I try to do the same from code it does not work
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
info.Domain = "134.86.157.132";
info.UserName = "sas";
info.Arguments = #"vm < c:\vm.sql";
info.UseShellExecute = false;
Process.Start(info);
What am I doing wrong here? It does not work and I get some wrong password exception?
Edit:
I run it like this now
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.UseShellExecute = false;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
Process.Start(info);
and get following error The system cannot find the file specified
"-h 134.86.157.132 -u sas vm" are the arguments, don't use domain and username.
You also need to redirect the standard input stream to pass your vm.sql file in. See this example: ProcessStartInfo.RedirectStandardInput Property
Try it like this:
ProcessStartInfo info = new ProcessStartInfo("mysql");
info.Arguments = #"-h 134.86.157.132 -u sas vm < c:\vm.sql";
info.UseShellExecute = false;
Process.Start(info);
You're setting UseShellExecute to false, but it's the shell that interprets the "<" part to redirect stdin from a file.
Unless there's a specific reason why you need UseShellExecute to be false, set it to true. Alternatively, redirect standard input for the new process, and give it the data directly.
EDIT: As specified in other answers, keep the original arguments, and don't set Domain/UserName on the ProcessStartInfo. Those refer to Windows usernames and domains, not MySQL ones.
At that point you'll be able to set UseShellExecute to true with no ill effects, with any luck.
How about something like from this post:
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = "cmd.exe";
info.RedirectStandardInput = true;
info.UseShellExecute = false;
p.StartInfo = info;
p.Start();
using (StreamWriter sw = new StreamWriter(p.StandardInput))
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("mysql -h 134.86.157.132 -u sas vm < c:\vm.sql");
}
}

Categories

Resources