Running silent install with iss response file - c#

I need to run a cmd command that silently install a software with a response file, but I can't find the correct syntax and keep having a "the specified path could not be found" error
I tried to run it without the /s and /f1 parameters, and it worked. I can also successfully launch both files, so it doesn't come from their path.
I also tried to put the exe and iss files in the program folder to get rid of the relative paths, but I still have the same error...
string command = "\"\"Executable Folder Path\\setup.exe\"\" /s /f1\"\"Config Path\\conf_file.iss\"\"";
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = false;
using (Process process = new Process())
{
process.StartInfo = procStartInfo;
process.Start();
process.WaitForExit();
string result = process.StandardOutput.ReadToEnd();
Console.WriteLine(result);
}
Does anyone know the correct syntax please ?

This should get your process started:
var setupExe = "Full/Path/To/setup.exe";
var configIss = "Full/Path/To/config.iss";
var procStartInfo = new ProcessStartInfo(setupExe);
procStartInfo.WorkingDirectory = Path.GetDirectoryName(setupExe);
procStartInfo.Arguments = $"/s /f1\"{configIss}\"";

Related

How to restart IIS on remote windows server from windows 7 client machine?

I am trying to restart iis remotely (Windows Servr 2012) from my local machine (Windows 7). The below command in command line doesn't work to restart IIS;
iisreset servername /restart
but the below command works fine when I tried in command line.
psexec iisreset \\servername /restart
Now the issue is when I try with below code in C#,
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "\C psexec iisreset \\servername /restart";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
// capture what is generated in command prompt
var output = process.StandardOutput.ReadToEnd();
If I give any other arguments in the above code like 'ipconfig', it gives me the expected output. But when I try with psexec, it gives empty output. But it works well when tried in command prompt.
I have also tried by using 'psexec.exe' in the filename and by removing '\C psexec' in the arguments. But still no luck.
Could you please anyone help me to resolve this?
Thanks in Advance.
I have found that when using PSexec like this that you Shouldn't use CMD.exe, and you need to ensure that you have the full path to psexec. Even if it is in the same directory as your application exe.
//Assume that psexec.exe is in same location as application
//Get directory of running applications
String AppPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).Replace("file:\\","");
//Set up start infor details
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = false;
//Combine path of running app
startInfo.FileName = Path.Combine(AppPath, "psexec.exe");
startInfo.Arguments = "\\servername c:\path\to\iisreset /restart";
//Execute
Process nProc = Process.Start(startInfo);
nProc.Start();
I hope u need to provide the domain admin credentials to it.
private int ExcecuteCommand(string command, string fileName, bool getResult, string timeout = null)
{
try
{
var secure = new SecureString();
foreach (char c in txtAdminPassword.Text)
{
secure.AppendChar(c);
}
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
pProcess.StartInfo.Domain = txtDomainName.Text;
pProcess.StartInfo.UserName = txtUser.Text;
pProcess.StartInfo.Password = secure;
pProcess.StartInfo.FileName = fileName;// AppDomain.CurrentDomain.BaseDirectory + #"PSTools\PsExec.exe"; ;
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -i -s -accepteula ipconfig /all", ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula netstat -ano",ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula -i CheckURLConnectivity", ipAddress);
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula ping {2}", ipAddress, AppDomain.CurrentDomain.BaseDirectory + #"Installer\CheckURLConnectivity.exe","10.10.10.35");
//pProcess.StartInfo.Arguments = string.Format(#"\\{0} -accepteula cmd /c type C:\ServiceLog.txt", ipAddress);
pProcess.StartInfo.Arguments = command;//string.Format(#"\\{0} -accepteula -c -f {1}", compName, AppDomain.CurrentDomain.BaseDirectory + #"Installer\CheckURLConnectivity.exe");
pProcess.StartInfo.UseShellExecute = false;
Process.StartInfo.RedirectStandardInput = true;
pProcess.StartInfo.RedirectStandardOutput = true;
pProcess.StartInfo.RedirectStandardError = true;
pProcess.StartInfo.CreateNoWindow = true;
logger.log("Query " + command);
pProcess.Start();
if (timeout == null)
pProcess.WaitForExit();
else
pProcess.WaitForExit(Convert.ToInt32(timeout));
string strOutput = string.Empty;
if (pProcess.HasExited == true && pProcess.ExitCode != 0)
{
string _errorMessage = GetWin32ErrorMessage(pProcess.ExitCode);
pProcess.Kill();
return pProcess.ExitCode;
}
else
return 0;
}
catch (Exception)
{
return -1;
}
}
IISreset requires elevated privilege to work.So you have to use the -h switch with psexec
-h If the target system is Vista or higher, has the process run with the account's elevated token, if available.
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = "psexec.exe";
startInfo.Arguments = "-h iisreset \\servername /restart";
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
process.StartInfo = startInfo;
process.Start();
// capture what is generated in command prompt
var output = process.StandardOutput.ReadToEnd();
Thank you all for your valuable response. It works fine with below code :)
startInfo.FileName = #"C:\Windows\Sysnative\PsExec.exe";
startInfo.Arguments = "iisreset \\servername /restart";
Reference: Process.Start in C# The system cannot find the file specified error

C# - Launch application with arguments.

Hello I've to Launch the software CFast for a Parametric Analysis. To do this, I want to create a application in C# that runs the core CFast.exe. If I want run the software from cmd.exe and execute it on the file INPUTFILENAME.in I write in prompt:
CFast.exe INPUTFILENAME
In C# I wrote the following code:
Process firstProc = new Process();
firstProc.StartInfo.FileName = #"C:\Users\Alberto\Desktop\Simulazioni Cfast\D\C\N\A3B1\CFAST.exe";
firstProc.StartInfo.Arguments = #"INPUTFILENAME";
firstProc.EnableRaisingEvents = true;
firstProc.Start();
firstProc.WaitForExit();
With this code CFast run but doesn't analyze anything... Seems like don't accept the argument. Hint for this trouble ?
Solved. Mistake in the filename and in the syntax of the command
// setup cmd process
var command = #"CFAST.exe C:\Users\Alberto\Desktop\Simulazioni_Cfast\D\C\N\A3B1\A3B1";
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.RedirectStandardError = true;
procStartInfo.CreateNoWindow = true;
// start process
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// read process output
string cmdError = proc.StandardError.ReadToEnd();
string cmdOutput = proc.StandardOutput.ReadToEnd();
where A3B1 is the name of the file .IN

C# Run CMD as Administrator

I'm trying to run cmd command as administrator. But the CMD window closes unexpectedly. If CMD window stays I can see the error. I tried to use process.WaitForExit();
I am trying to run the code zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk as administrator.
Here is my code.
//The command that we want to run
string subCommand = zipAlignPath + " -v 4 ";
//The arguments to the command that we want to run
string subCommandArgs = apkPath + " release_aligned.apk";
//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");
//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();
}
Is there a way to keep the CMD window running/showing?
You are starting a process from the runas.exe executable file. That's not how to elevate a process.
Instead you need to use shell execute to start your excutable, but use the runas verb. Along these lines:
ProcessStartInfo psi = new ProcessStartInfo(...); // your command here
psi.UseShellExecute = true;
psi.Verb = "runas";
Process.Start(psi);
Capture the output(s) from your process:
proc.StartInfo = procStartInfo;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.Start()
// string output = proc.StandardOutput.ReadToEnd();
string error = proc.StandardError.ReadToEnd();
proc.WaitForExit();
Then do something with the output.
Note: you shouldn't try to synchronously read both streams at the same time, as there's a deadlock issue. You can either add asyncronous reading for one or both, or just switch back and forth until you're done troubleshooting.
The following method actually works...
private void runCMDFile()
{
string path = #"C:\Users\username\Desktop\yourFile.cmd";
Process proc = new Process();
proc.StartInfo.FileName = path;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.Verb = "runas";
proc.Start();
proc.WaitForExit();
}

How to pass Ctrl+Enter command to Process when using C# StandardInput redirection

Im trying to make C# application that uses hunpos tagger.
Runing hunpos-tag.exe requires three input arguments: model, inputFile, outputFile
In cmd it would look something like this:
hunpos-tag.exe model <inputFile >outputFile
Although, hunpos-tag.exe can be run with just the model, at that point it'll wait for text input (from cmd) which is processed when the tagger receives Ctrl+Enter as input and the results are displayed through standard output. I've been trying to use StandardInput redirection in C# but I don't know how to send the Ctrl+Enter end command (Or if the redirection works at all). The code:
string inputFilePath = path + "\\CopyFolder\\rr";
string pathToExe = path + "\\CopyFolder\\hunpos-tag.exe";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = pathToExe,
UseShellExecute = false,
RedirectStandardInput = true,
WorkingDirectory = Directory.GetDirectoryRoot(pathToExe),
Arguments = path + "\\CopyFolder\\model.hunpos.mte5.defnpout",
};
try
{
Process _proc = new Process();
_proc.StartInfo.FileName = pathToExe;
_proc.StartInfo.UseShellExecute = false;
_proc.StartInfo.RedirectStandardInput = true;
_proc.StartInfo.Arguments = path + "\\CopyFolder\\model.hunpos.mte5.defnpout";
_proc.Start();
var streamReader = new StreamReader(inputFilePath);
_proc.StandardInput.Write(streamReader.ReadToEnd());
_proc.StandardInput.Flush();
_proc.StandardInput.Close();
_proc.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine(e);
}
When I run the following code the tagger has the following output:
model loaded
tagger compiled
Fatal error: exception Sys_error("Bad file description")
The exception is caused by the .Close() command. The file is valid and works when runned from cmd. Any ideas on how could I send the end command or how to emulate cmd command without using redirection?
It wouldn't work with input redirection so I managed it with running cmd procces and passing it the required command.
using (Process process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = #"C:\";
process.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
// Redirects the standard input so that commands can be sent to the shell.
process.StartInfo.RedirectStandardInput = true;
// Runs the specified command and exits the shell immediately.
//process.StartInfo.Arguments = #"/c ""dir""";
process.OutputDataReceived += ProcessOutputDataHandler;
process.ErrorDataReceived += ProcessErrorDataHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// Send a directory command and an exit command to the shell
process.StandardInput.WriteLine(path + "\\CopyFolder\\hunpos-tag.exe " + path + "\\CopyFolder\\model.hunpos.mte5.defnpout <" + path + "\\CopyFolder\\rr >" + path + "\\CopyFolder\\zz");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
}

Write only the output from the console command

I'm trying to build a .net application that will run some console commands (like running phantomJs) and return me the outcome of the operations. But by default I'm getting everything from the starting of cmd.exe to closing it. Any ideas for a quick fix or do I need to play with regexes ?
Here's my code as for now :
System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("cmd.exe");
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
psi.RedirectStandardInput = true;
psi.RedirectStandardError = true;
System.Diagnostics.Process proc = System.Diagnostics.Process.Start(psi);
System.IO.StreamReader sOut = proc.StandardOutput;
System.IO.StreamWriter sIn = proc.StandardInput;
sIn.WriteLine("phantomjs -v");
sIn.WriteLine("EXIT");
proc.Close();
string results = sOut.ReadToEnd().Trim();
sIn.Close();
sOut.Close();
PhantomJS is an executable (according to their docs) - why not execute that directly rather than running cmd.exe? That will avoid the cmd.exe noise.
Or redirect the output of phantomjs to a log file and load the log file.
Or if you absolutely have to use cmd.exe and can't redirect ... I'd maybe throw some echo sentinels around the phantomjs to serve as parse start/stop points.
e.g.,
echo PARSE START
runcommand.exe
echo PARSE STOP
But don't do that.
Instead of using the different streams. Why not use cmd as filename and pass it the -c "phantomjs -v" as argument. Then use proc.StandardOutput.ReadToEnd() to grab everything that is outputted in the console. This should leave out unneeded info as it only reads what the output of the executed command is.
Following code might not work, but should give you the general idea.
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd";
psi.Arguments = "/c \"phantomjs -v\"";
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
// Optional other options
Process proc = Process.Start(psi);
string output = proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
If you are on an unix machine:
sIn.WriteLine("phantomjs -v > /dev/null");
Windows:
sIn.WriteLine("phantomjs -v > NUL");
I hope that the following would be helpful!
{
Process xyProcess = new Process();
xyProcess.StartInfo.FileName = "FilenameYouWant";
xyProcess.StartInfo.UseShellExecute = false;
xyProcess.StartInfo.CreateNoWindow = true;
xyProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
xyProcess.StartInfo.RedirectStandardInput = true;
xyProcess.StartInfo.RedirectStandardOutput = true;
xyProcess.StartInfo.RedirectStandardError = true;
xyProcess.StartInfo.Arguments += "any arg1 you want ";
xyProcess.StartInfo.Arguments += "any arg2 you want ";
xyProcess.EnableRaisingEvents = true;
xyProcess.OutputDataReceived += process_DataReceived;
// Start the process
xyProcess.Start();
xyProcess.BeginErrorReadLine();
xyProcess.BeginOutputReadLine();
xyProcess.WaitForExit();
}
static private void process_DataReceived(object sender, DataReceivedEventArgs e)
{
//Catch the process response here
}

Categories