Similar question was asked at least a dozen times on SO and it looks that now I have exhausted most of the proposed solutions but still unable to complete the task successfully.
So what I have is the following command that I want to run in cmd:
xcopy /q C:\fileName.txt \\VMNAME\C$\destFolder /Y /E
But I need it to be executed with certain credentials. So what I was doing manually is entering the below command first:
runas /user:<domainName>\<userName> cmd
That was opening a separate cmd window and I was running the first (xcopy) command in that window.
What I have at the moment:
string strCmdText = string.Format(#"xcopy /q {0} {1} /Y /E", source, destination);
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.RedirectStandardError = true;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.FileName = "runas";
procStartInfo.Arguments = String.Format(#"/user:<domainName>\<userName> cmd " + strCmdText);
Process.Start(procStartInfo);
Where the source and destination are of the below structure:
source = "C:\\somePath\\fileName.txt"
destination = "\\\\<VMName>\\C$\\somePath\\"
I have also tried defining procStartInfo with:
procStartInfo.Verb = "runas";
Instead of:
procStartInfo.FileName = "runas";
With similar results.
At the moment, when I run the above code, it does not return any error but doesn't do what's expected either. Am I missing something or this approach is wrong?
Related
I am creating a C# app that changes Windows Server edition from Standard Evaluation to Standard. I am trying to get a output of the CMD command, but when the DISM command is completed, it asks you if you want to restart the computer and you need to enter "y" or "n". I tried it doing by passing "echo n | " before the command and by using process.StandardInput.Write, but none of this works. The function works perfectly with other commands that doesn´t require user input. Do you have any idea what am I doing wrong? Thanks
public static string get_cmd_output(string cmd)
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/C echo n | " + cmd;
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
string q = "";
while (!process.HasExited)
q += process.StandardOutput.ReadToEnd();
return q;
}
get_cmd_output("DISM /Online /Set-Edition:ServerStandard /ProductKey:" + key + " /AcceptEula");
In the docs for DISM, one of the global parameters you can pass is /NoRestart:
/NoRestart
Suppresses reboot. If a reboot is not required, this command does
nothing. This option will keep the application from prompting for a
restart (or keep it from restarting automatically if the /Quiet option
is used).
So it should work if you do this:
get_cmd_output("DISM /Online /Set-Edition:ServerStandard /ProductKey:" + key + " /AcceptEula /NoRestart");
I am currently trying to make an application that uses the command net share from the CMD. However, when I press on the button that runs the code, it gives me the following error:
An unhandled exception of type 'System.ComponentModel.Win32Exception' occurred in System.dll.
Here's the code I'm using:
Process cmd = new Process();
cmd.StartInfo.FileName = "net share";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.Arguments = txt_shareName + "=" + path;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.Start();
txt_Logs.Text = cmd.StandardOutput.ReadToEnd();
But when you put ipconfig into the FileName part and /all into the Arguments part, it works perfectly.
The issue is with the StartInfo.File, "net share" is not a valid filename.
Try this
Process cmd = new Process()'
cmd.StartInfo.FileName = "net";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.Arguments = "share " + txt_shareName + "=" + path;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.Start();
If the path contain spaces, you will need to quote it.
Process cmd = new Process();
cmd.StartInfo.FileName = "net";
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.Arguments = "share";
cmd.StartInfo.RedirectStandardOutput = true;
cmd.Start();
net is a exe in sys32.. share is an argument.. add it to your aguments..
It is because net share requires Administrative privilege to run this command.
When you try to run only Net Share it will perfectly and it doesn't require any special privilege. But when you try run the command with parameters in the command prompt it will give error stating
System error 5 has occurred.
Access is denied.
So you need to run as administrator
The possible solution might be that you could run the Visual Studio as administrator
To run the command with administrator privilege whereas if the OS is Vista or higher you can do it like below
if (System.Environment.OSVersion.Version.Major >= 6)
{
p.StartInfo.Verb = "runas";
}
As mentioned by #Mohit, this is a problem of admin rights. You can run process as administrator from C# by adding following:
cmd.StartInfo.Verb = "runas";
"net" it's a programm and "share" argument. Try this:
cmd.StartInfo.FileName = "net";
cmd.StartInfo.Arguments = "share " + txt_shareName + "=" + path;
I'm currently trying to do a basic mysqlcheck through the command prompt. The mysql.exe file itself is within a bin that the working directory is pointing towards to use as part of the commands though the cmd.
Right now I'm getting stuck to where it is stopping while opening the shell. It doesn't proceed to initiate the standardinput.
{
Process proc = new Process();
proc.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
proc.StartInfo.WorkingDirectory = #"C:\Program Files (x86)\MySQL\bin";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.Arguments = #"Mysqlcheck -u root -c -ppassword database";
proc.Start();
string output = proc.StandardOutput.ReadToEnd();
proc.StandardInput.WriteLine("Mysqlcheck -u root -c -ppassword database");
proc.WaitForExit();
}
Add the /C option before the name of the executable
proc.StartInfo.Arguments = #"/C Mysqlcheck.exe -u root -c -ppassword database";
Without this argument the cmd shell doesn't execute the command but exits immediately.
You can see other arguments for the CMD.exe opening a command prompt and typing CMD /?
I want to run tabcmd.exe utility to publish views in tableau server. Manual step to do this is as follows, log file will be updated for every step in the location
"C:\Users[UserName]\AppData\Roaming\Tableau\tabcmd.log"
In the same session I have to perform this steps manually one by one order
Run cmd.exe
log in by using the command tabcmd login -s "http:/sales-server:8000" -t Sales -u administrator -p p#ssw0rd!
Create Project Name using the command tabcmd createproject -n "Quarterly_Reports" -d "Workbooks showing quarterly sales reports."
Publish views by using the command tabcmd publish "analysis.twbx" -n "Sales_Analysis" --db-user "jsmith" --db-password "p#ssw0rd"
Refresh by using the command tabcmd refreshextracts --workbook "My Workbook"
Log out by using the command tabcmd logout
Now I am trying to automate this steps from my .Net win form, so I used below code as a try and It is not working.
String path = #"C:\Program Files (x86)\Tableau\Tableau Server\7.0\bin\tabcmd.exe"
ProcessStartInfo startInfo = new ProcessStartInfo ();
startInfo.FileName = "\""+path+ "\"";
startInfo.Arguments = String.Format("login -s http://Server1:8000 --db-user "jsmith" --db-password "p#ssw0rd");
startInfo.UseShellExecute = false ;
startInfo.CreateNoWindow = false;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardError = true;
Process p = new Process();
p.StartInfo = startInfo;
p.Start();
using (StreamWriter sw = p.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
sw.WriteLine("createproject -n \"MyProject\" -d \"MyProjectWorkbook\"");
//sw.WriteLine("My next Command");
//sw.WriteLine("My next Command");
}
}
I am able to log in successfully and I am not able to proceed consequent steps further, I have no clue how to proceed on this further, so I am looking forward some help on this.
Thanks in advance!
I'm unsure if this is of use to you or not but you could try creating a batch file with all of those commands and the execute the batch file from command prompt like this :-
//Build Commands - You may have to play with the syntax
string[] cmdBuilder = new string[5]
{
#"tabcmd login -s 'http:/sales-server:8000' -t Sales -u administrator -p p#ssw0rd!",
#"tabcmd createproject -n 'Quarterly_Reports' -d 'Workbooks showing quarterly sales reports.'",
#"abcmd publish 'analysis.twbx' -n 'Sales_Analysis' --db-user 'jsmith' --db-password 'p#ssw0rd'",
#"tabcmd refreshextracts workbook 'My Workbook'",
#"tabcmd logout"
};
//Create a File Path
string BatFile = #"\YourLocation\tabcmd.bat";
//Create Stream to write to file.
StreamWriter sWriter = new StreamWriter(BatFile);
foreach (string cmd in cmdBuilder)
{
sWriter.WriteLine(cmd);
}
sWriter.Close();
//Run your Batch File & Remove it when finished.
Process p = new Process();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = "C:\\cmd.exe";
p.StartInfo.Arguments = #"\YourLocation\tabcmd.bat";
p.Start();
p.WaitForExit();
File.Delete(#"\YourLocation\tabcmd.bat")
I'll leave the output section to yourself. You could try this, it is not exactly clean but will automate the main steps. It's either this, or opening a process for each command as the last process exits?
Hope this is of help.
Here is my code:
try
{
ProcessStartInfo procStartInfo = new ProcessStartInfo(
"cmd.exe",
"/c " + command);
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
procStartInfo.Verb = "runas";
procStartInfo.Arguments = "/env /user:" + "Administrator" + " cmd" + command;
///command contains the command to be executed in cmd
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I want to keep
procStartInfo.UseShellExecute = true
procStartInfo.RedirectStandardInput = false;
Is it possible to execute the command without using process.standardinput?
I try to execute command I've passed in argument but the command does not executes.
As #mtijn said you've got a lot going on that you're also overriding later. You also need to make sure that you're escaping things correctly.
Let's say that you want to run the following command elevated:
dir c:\
First, if you just ran this command through Process.Start() a window would pop open and close right away because there's nothing to keep the window open. It processes the command and exits. To keep the window open we can wrap the command in separate command window and use the /K switch to keep it running:
cmd /K "dir c:\"
To run that command elevated we can use runas.exe just as you were except that we need to escape things a little more. Per the help docs (runas /?) any quotes in the command that we pass to runas need to be escaped with a backslash. Unfortunately doing that with the above command gives us a double backslash that confused the cmd parser so that needs to be escaped, too. So the above command will end up being:
cmd /K \"dir c:\\\"
Finally, using the syntax that you provided we can wrap everything up into a runas command and enclose our above command in a further set of quotes:
runas /env /user:Administrator "cmd /K \"dir c:\\\""
Run the above command from a command prompt to make sure that its working as expected.
Given all that the final code becomes easier to assemble:
//Assuming that we want to run the following command:
//dir c:\
//The command that we want to run
string subCommand = #"dir";
//The arguments to the command that we want to run
string subCommandArgs = #"c:\";
//I am wrapping everything in a CMD /K command so that I can see the output and so that it stays up after executing
//Note: arguments in the sub command need to have their backslashes escaped which is taken care of below
string subCommandFinal = #"cmd /K \""" + subCommand.Replace(#"\", #"\\") + " " + subCommandArgs.Replace(#"\", #"\\") + #"\""";
//Run the runas command directly
ProcessStartInfo procStartInfo = new ProcessStartInfo("runas.exe");
procStartInfo.UseShellExecute = true;
procStartInfo.CreateNoWindow = true;
//Create our arguments
string finalArgs = #"/env /user:Administrator """ + subCommandFinal + #"""";
procStartInfo.Arguments = finalArgs;
//command contains the command to be executed in cmd
using (System.Diagnostics.Process proc = new System.Diagnostics.Process())
{
proc.StartInfo = procStartInfo;
proc.Start();
}
why are you initializing the process object with arguments and then later on override those Arguments? and btw: the last bit where you set Arguments you concatenate 'command' right upto 'cmd', that doesn't make much sense and might be where it fails (looks like you're missing a space).
Also, you are currently using the standard command line, you might want to look into using the runas tool instead. you can also call runas from command line.
Also, why are you running 'command' from the command line? why not start it directly from Process.Start with admin privileges supplied then and there? here's a bit of pseudocode:
Process p = Process.Start(new ProcessStartInfo()
{
FileName = <your executable>,
Arguments = <any arguments>,
UserName = "Administrator",
Password = <password>,
UseShellExecute = false,
WorkingDirectory = <directory of your executable>
});