With the code below I can only start Visual Studio 2008 Command Prompt, but now I have to publish a web site to a target path on my local drive.
I need c# code which does something like the following command:
msbuild /target:Build /p:BuildingProject=true;OutDir=C:\Temp\build\
ccosapp.sln My first attempt (fails - doesn't do anything):
Below is the code I tried, which doesn't do anything:
ProcessStartInfo oInfo = new ProcessStartInfo(#"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat", #"msbuild C:\Users\Johan\Documents\Visual Studio 2008\Projects\PRJAPP\PRJAPP.sln");
oInfo.UseShellExecute = false;
oInfo.ErrorDialog = false;
oInfo.CreateNoWindow = true;
oInfo.RedirectStandardOutput = true;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(oInfo);
System.IO.StreamReader oReader2 = p.StandardOutput;
string sRes = oReader2.ReadToEnd();
oReader2.Close();
Another attempt (also fails):
string strCmdText = "/k \"C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\vcvarsall.bat\" && msbuild /p:OutDir=C:\\Temp\\build \"C:\\Users\\Johan\\Documents\\Visual Studio 2008\\Projects\\CCOSApp\\ccosapp.sln\"";
System.Diagnostics.Process.Start("CMD.exe", strCmdText);
I'm getting the error in my CMD window:
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
The last attempt (fails as well - getting the same error as in my 2nd attempt):
/// <span class="code-SummaryComment"><summary></span>
/// Executes a shell command synchronously.
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="command">string command</param></span>
/// <span class="code-SummaryComment"><returns>string, as output of the command.</returns></span>
public void ExecuteCommandSync(object command)
{
try
{
// create the ProcessStartInfo using "cmd" as the program to be run,
// and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows,
// and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo =
new System.Diagnostics.ProcessStartInfo("cmd", "/k " + command);
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = false;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
// Display the command output.
Console.WriteLine(result);
}
catch (Exception objException)
{
// Log the exception
}
}
/// <span class="code-SummaryComment"><summary></span>
/// Execute the command Asynchronously.
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name="command">string command.</param></span>
public void ExecuteCommandAsync(string command)
{
try
{
//Asynchronously start the Thread to process the Execute command request.
System.Threading.Thread objThread = new System.Threading.Thread(new ParameterizedThreadStart(ExecuteCommandSync));
//Make the thread as background thread.
objThread.IsBackground = true;
//Set the Priority of the thread.
objThread.Priority = ThreadPriority.AboveNormal;
//Start the thread.
objThread.Start(command);
}
catch (ThreadStartException objException)
{
// Log the exception
}
catch (ThreadAbortException objException)
{
// Log the exception
}
catch (Exception objException)
{
// Log the exception
}
}
string cmdStr = #" ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat""
cd ""C:\Users\Johan\Documents\Visual Studio 2008\Projects\CCOSApp""
msbuild /target:Build /p:BuildingProject=true;OutDir=C:\Temp\build
ccosapp.sln";
new VsFunctions().ExecuteCommandAsync(cmdStr);
I came with this workaround:
StreamWriter w = new StreamWriter(#"C:\temp\publish.bat");
w.WriteLine(#"call ""C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat""");
w.WriteLine(#"call cd ""C:\Users\Johan\Documents\Visual Studio 2008\Projects\CCOSApp""");
w.WriteLine(#"call msbuild /target:Build /p:BuildingProject=true;OutDir=C:\Temp\build ccosapp.sln");
w.Close();
System.Diagnostics.Process proc = new System.Diagnostics.Process();
ProcessStartInfo psi = new ProcessStartInfo(#"publish.bat");
psi.WorkingDirectory = #"C:\temp\";
proc.StartInfo = psi;
proc.Start();
I create a .bat file.
I write the commands in it.
Finally I start the .bat file as a Process.
C:\Program' is not recognized as an internal or external command,
operable program or batch file.
you are getting this error because there is space in your path, between Program and File
try placing double quotation mark at the start and end of your path
Instead of passing the whole path of the executable, try to changing the directory to "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\" via
oInfo.WorkingDirectory = #"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\";
Then just call the vcvarsass.bat
Hopefully that helps
Does it work when you use the Arguments property of StartInfo
Process cmd = new Process();
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.StartInfo.FileName = #"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat";
cmd.StartInfo.Arguments = #"msbuild C:\Users\Johan\Documents\Visual Studio 2008\Projects\PRJAPP\PRJAPP.sln";
cmd.Start();
cmd.WaitForExit();
ie like in this example: Using cmd.exe from C#
Related
The command line I need to execute is
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe" /Run "C:\unity\unity\MRTK Tutorial\Builds\MRTK Tutorial.sln"
This works from a windows command line without issues,
I formatted it into a string for visual studio
When running from C# this command never executes and the contents of result are ""
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("C:\\Program Files(x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\devenv.exe", " /Run \"C:\\unity\\unity\\MRTK Tutorial\\Builds\\MRTK Tutorial.sln\"");
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
You can try the following code to use c# to execute devenv.exe.
var devEnvPath = #"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\devenv.exe";
string SolutionFile = #"D:\Test\testconsole\testconsole.sln";
ProcessStartInfo startInfo = new ProcessStartInfo(devEnvPath);
startInfo.Arguments = "/Run " + SolutionFile;
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
Console.ReadKey();
Based on my test, the above code will open vs2019 and open the startup project.
I want to run a gpu accelerated python script on windows using conda environment (dlwin36).
I’m trying to activate dlwin36 and execute a script:
1) activate dlwin36
2) set KERAS_BACKEND=tensorflow
3) python myscript.py
If I manually open cmd on my machine and write:"activate dlwin36"
it works.
But when I try opening a cmd from c# I get:
“activate is not recognized as an internal or external command, operable program or batch file.”
I tried using the following methods:
Command chaining:
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&python myscript.py";
Process.Start(start).WaitForExit();
(I’ve tested several variations of UseShellExecute, LoadUserProfile and WorkingDirectory)
Redirect standard input:
var commandsList = new List<string>();
commandsList.Add("activate dlwin36");
commandsList.Add("set KERAS_BACKEND=tensorflow");
commandsList.Add("python myscript.py");
var start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.UseShellExecute = false;
start.RedirectStandardInput = true;
var proc = Process.Start(start);
commandsList.ForEach(command => proc.StandardInput.WriteLine(command));
(I’ve tested several variations of LoadUserProfile and WorkingDirectory)
In both cases, I got the same error.
It seems that there is a difference between manually opening cmd and opening it from c#.
The key is to run activate.bat in your cmd.exe before doing anything else.
// Set working directory and create process
var workingDirectory = Path.GetFullPath("Scripts");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
RedirectStandardInput = true,
UseShellExecute = false,
RedirectStandardOutput = true,
WorkingDirectory = workingDirectory
}
};
process.Start();
// Pass multiple commands to cmd.exe
using (var sw = process.StandardInput)
{
if (sw.BaseStream.CanWrite)
{
// Vital to activate Anaconda
sw.WriteLine("C:\\PathToAnaconda\\anaconda3\\Scripts\\activate.bat");
// Activate your environment
sw.WriteLine("activate your-environment");
// Any other commands you want to run
sw.WriteLine("set KERAS_BACKEND=tensorflow");
// run your script. You can also pass in arguments
sw.WriteLine("python YourScript.py");
}
}
// read multiple output lines
while (!process.StandardOutput.EndOfStream)
{
var line = process.StandardOutput.ReadLine();
Console.WriteLine(line);
}
You need to use the python.exe from your environment. For example:
Process proc = new Process();
proc.StartInfo.FileName = #"C:\path-to-Anaconda3\envs\tensorflow-gpu\python.exe";
or in your case:
start.Arguments = "/c activate dlwin36&&set KERAS_BACKEND=tensorflow&&\"path-to-Anaconda3\envs\tensorflow-gpu\python.exe\" myscript.py";
I spent a bit of time working on this and here's the only thing that works for me: run a batch file that will activate the conda environment and then issue the commands in python, like so. Let's call this run_script.bat:
call C:\Path-to-Anaconda\Scripts\activate.bat myenv
set KERAS_BACKEND=tensorflow
python YourScript.py
exit
(Note the use of the call keyword before we invoke the activate batch file.)
After that you can run it from C# more or less as shown above.
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = "cmd.exe";
start.Arguments = "/K c:\\path_to_batch\\run_script.bat";
start.UseShellExecute = false;
start.RedirectStandardOutput = true;
start.RedirectStandardError = true;
start.WorkingDirectory = "c:\\path_to_batch";
string stdout, stderr;
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
stdout = reader.ReadToEnd();
}
using (StreamReader reader = process.StandardError)
{
stderr = reader.ReadToEnd();
}
process.WaitForExit();
}
I am generating the batch file on the fly in C# to set the necessary parameters.
If this is gonna help anyone in the future. I found that you must run the activation from C:\ drive.
I have a batch file that copy file from one folder to another folder. So I would like to run this file from a C# windows services then I would like to read if the script generate an error or it works correctly.
This is my code for lunch it but I don't Know how to read the message of the script:
SCRIPT CODE:
REM
REM This script moves files with results from GOLD server and saves them on MES06 server on .
REM IMPORT folder.
REM
REM Robocopy Options:
REM /R:2 Two retries on failed copies (default is 1 million)
REM /W:5 Wait 5 seconds between retries (default is 30 sec).
REM
REM GOLD QAS Inbound Folder: \\goldqas01.app.pmi\limscihome$\RootDirectory
REM
for /f "delims=: tokens=2,3" %%j in (F:\MES2GOLD\copy_list_test.txt) do ROBOCOPY.EXE %%j %%j\..\BACKUP *.* /R:2 /W:5 /log+:%%j\..\LOGS\MES2GOLD.log & ROBOCOPY.EXE %%j %%k *.* /R:2 /W:5 /MOV /log+:%%j\..\LOGS\MES2GOLD.log
PAUSE
C# Code:
public void execute(string workingDirectory, string command)
{
// create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
// Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd.exe", #"/c C:\Users\mcastrio\Desktop\GOLD2MES.bat");
procStartInfo.WorkingDirectory = workingDirectory;
//This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
//This means that it will be redirected to the Process.StandardError StreamReader. (same as StdOutput)
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
//This is importend, else some Events will not fire!
proc.EnableRaisingEvents = true;
// passing the Startinfo to the process
proc.StartInfo = procStartInfo;
// The given Funktion will be raised if the Process wants to print an output to consol
proc.OutputDataReceived += DoSomething;
// Std Error
proc.ErrorDataReceived += DoSomethingHorrible;
// If Batch File is finished this Event will be raised
proc.Exited += Exited;
}
Can we help me?
You can use the code below inside your loop:
var startInfo = p.StartInfo;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.UseShellExecute = false;
startInfo.StandardOutputEncoding = Encoding.GetEncoding("ibm850");
startInfo.RedirectStandardOutput = true;
startInfo.FileName = filebatch;
startInfo.Arguments = arguments;
p.Start();
var output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Or just use ProcessHelper.Run from TestSharp library:
ProcessHelper.Run(string exePath, string arguments = "", bool waitForExit = true)
I am not able to pass some parameters to my Dev cmd prompt for vs, I can do it with the classic cmd but not with this one. And I need it because I want to execute CodedUITests from an executable.
This is what my code looks like:
String Path = #"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Visual Studio 2012\Visual Studio Tools\Developer Command Prompt for VS2012.lnk";
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = Path;
proc.UseShellExecute = true;
proc.Arguments = #"/c MSTest/h";
Process.Start(proc);
It starts, but no args are inserted,what am I doing wrong ?
EDIT 1 - None of these are working
Process.Start(Path, #"/c "+"MSTest/h"); - err : invalid path - in dev cmd prompt
OR
Process.Start(Path, #"/c ""MSTest/h"); - err: invalid path - in dev cmd prompt
OR
Process.Start(Path, #"/c MSTest/h"); - nothing
OR
Process.Start(Path, "/c MSTest/h"); -nothing
OR
Process.Start(Path, "MSTest/h"); -nothing
EDIT 2 - This is how my final code looks like, partially working, dev cmd starting, but no way to parse args into it because any args I pass they go straight to cmd not to dev-cmd
// ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", #"%comspec% /k ""C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Tools\VsDevCmd.bat""");
ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", #"%comspec% /k ""C:\Users\butoiu.edward\Desktop\VsDevCmd1.bat");
procStartInfo.UseShellExecute = false;
// procStartInfo.Arguments = "/k MSTest";
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
Did you try this way?
void OpenWithArguments()
{
Process.Start("IExplore.exe", "www.northwindtraders.com");
Process.Start("path to exe", "argument");
}
-- FMI MSDN LINK
Update:
I assume it will work this way... but not sure
Open sys default cmd prompt.. and give first param as batch file path (C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Tools\VsDevCmd.bat) and give a space and add next attribute.
Process.Start("Path to EXE", "arg1 arg2")
lnk" file it is actually a link of visual studio cmd prompt. Instead of this location you try original file located at "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
String Path = #"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat";
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = Path;
proc.UseShellExecute = true;
proc.Arguments = #"/c MSTest/h";
Process.Start(proc);
I hope this will help you.
When i try to run BCDEDIT from my C# application i get the following error:
'bcdedit' is not recognized as an internal or external
command,
operable program or batch file.
when i run it via elevated command line i get as expected.
i have used the following code:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = #"CMD.EXE";
p.StartInfo.Arguments = #"/C bcdedit";
p.Start();
string output = p.StandardOutput.ReadToEnd();
String error = p.StandardError.ReadToEnd();
p.WaitForExit();
return output;
i have also tried using
p.StartInfo.FileName = #"BCDEDIT.EXE";
p.StartInfo.Arguments = #"";
i have tried the following:
Checking path variables - they are fine.
running visual studio from elevated command prompt.
placing full path.
i am running out of ideas,
any idea as to why i am getting this error ?
all i need is the output of the command if there is another way that would work as well.
thanks
There is one explanation that makes sense:
You are executing the program on a 64 bit machine.
Your C# program is built as x86.
The bcdedit.exe file exists in C:\Windows\System32.
Although C:\Windows\System32 is on your system path, in an x86 process you are subject to the File System Redirector. Which means that C:\Windows\System32 actually resolves to C:\Windows\SysWOW64.
There is no 32 bit version of bcdedit.exe in C:\Windows\SysWOW64.
The solution is to change your C# program to target AnyCPU or x64.
If you are stuck with x86 application on both 32it/64bit Windows and You need to call bcdedit command, here is a way how to do that:
private static int ExecuteBcdEdit(string arguments, out IList<string> output)
{
var cmdFullFileName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows),
Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess
? #"Sysnative\cmd.exe"
: #"System32\cmd.exe");
ProcessStartInfo psi = new ProcessStartInfo(cmdFullFileName, "/c bcdedit " + arguments) { UseShellExecute = false, RedirectStandardOutput = true };
var process = new Process { StartInfo = psi };
process.Start();
StreamReader outputReader = process.StandardOutput;
process.WaitForExit();
output = outputReader.ReadToEnd().Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();
return process.ExitCode;
}
usage:
var returnCode = ExecuteBcdEdit("/set IgnoreAllFailures", out outputForInvestigation);
Inspiration was from this thread and from How to start a 64-bit process from a 32-bit process and from http://www.samlogic.net/articles/sysnative-folder-64-bit-windows.htm