I'm making an application where I have to enable and disable the UWF in Windows 10.
But I want to intercept the success or failure, the problem is that when I only displays a letter.
string output = string.Empty;
string error = string.Empty;
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/c uwfmgr.exe volume protect c:");
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.UseShellExecute = false;
processStartInfo.Verb = "runas";
Process process = Process.Start(processStartInfo);
using (StreamReader streamReader = process.StandardOutput)
{
output = streamReader.ReadToEnd();
}
using (StreamReader streamReader = process.StandardError)
{
error = streamReader.ReadToEnd();
}
if (!string.IsNullOrEmpty(error))
{
MessageBox.Show("Error: " + error);
return;
}
MessageBox.Show("OK: " + output);
Here comes the message box "OK U"
Thanks
Thank you for your reply.
I tried to read the articles but given my lack of experience I can apply what it says, Could you give me a little extra help?
The thing I noticed is that I can enable the UWF only if you use the following code
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/k uwfmgr.exe volume protect " + cmbBox_Disk.SelectedItem.ToString().Substring(0, 2) + " & exit");
processStartInfo.CreateNoWindow = false;
processStartInfo.WindowStyle = ProcessWindowStyle.Normal;
processStartInfo.UseShellExecute = true;
processStartInfo.Verb = "runas";
Process process = Process.Start(processStartInfo);
processStartInfo = new ProcessStartInfo("cmd", "/k uwfmgr.exe filter enable & exit");
processStartInfo.CreateNoWindow = false;
processStartInfo.WindowStyle = ProcessWindowStyle.Normal;
processStartInfo.UseShellExecute = true;
processStartInfo.Verb = "runas";
process = Process.Start(processStartInfo);
but the problem is that in this way if there is an error I can not agree with the user.
You can read the output of the shell, see this answer:
Process.start: how to get the output?
Unfortunately there is no good way to detect errors using process.
It would be better to use WMI and UWF's WMI provider:
See:
https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/uwf-wmi-provider-reference
Make sure you read the docs thoroughly though. For example, in order to protect a volume you need to run Protect(); on an instance which has 'currentSession = false'. This instance needs to be created by yourself.
It has some small caveats here an there.
Related
I am having trouble with the Process class to pipe a command on a Linux system.
I want to execute the following command: rpm2cpio repo.rpm | cpio -divm
I've tried
process.StartInfo.FileName = "rpm2cpio;
rocess.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.Arguments = "repo.rpm | cpio - idmv";
But the program hangs.
Similarly, I tried saving the output from rpm2cpio to a string or an output file and then pass that as the argument for the cpio command, but it also hangs.
process.StartInfo.FileName = "cpio";
rocess.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.Arguments = "-idvm < output.txt";
// or
process.StartInfo.Arguments = "-idvm < " + rp2cpio_output;
What are some ways I can get this working? I saw this post with a solution, but it is on a Window's system. How do the same thing on Linux?
Setting process.StartInfo.RedirectStandardOutput=true will cause the program to redirect standard output to the stream process.StartInfo.StandardOutput. When this happens the program will hang until you read from standard output.
To get the behavior I think you are looking for, you just need to set RedirectStandardOutput=false. That way the pipes and redirects in your command will work as expected.
Rather than directly writing to a file, you can simply use a StreamWriter to fetch the output in a stream buffer and then use that to write to the file. If the process still hangs, simply use the timeout command of linux to terminate the process.
The following snippet may help after making a few changes:
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName = "/bin/bash";
processStartInfo.WorkingDirectory = "/";
string cmd = "timeout 1 cat > temp.txt";
var escapedArgs = cmd.Replace("\"", "\\\"");
processStartInfo.Arguments = $"-c \"{escapedArgs}\"";
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.StandardErrorEncoding = System.Text.Encoding.UTF8;
processStartInfo.StandardInputEncoding = System.Text.Encoding.UTF8;
processStartInfo.StandardOutputEncoding = System.Text.Encoding.UTF8;
processStartInfo.UseShellExecute = false;
process.StartInfo = processStartInfo;
process.Start();
stdIOWriter = process.StandardInput;
stdIOWriter.WriteLine("Hey Fellas");
String error = process.StandardError.ReadToEnd();
String output = process.StandardOutput.ReadToEnd(); ```
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
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
}
I am using lame for transcoding for one of my project. The issue is that when I call lame from C#, a DOS window pops out. Is there any way I can suppress this?
Here is my code so far:
Process converter =
Process.Start(lameExePath, "-V2 \"" + waveFile + "\" \"" + mp3File + "\"");
converter.WaitForExit();
Did you try something like:
using( var process = new Process() )
{
process.StartInfo.FileName = "...";
process.StartInfo.WorkingDirectory = "...";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.Start();
}
Assuming you are calling it via Process.Start, you can use the overload that takes ProcessStartInfo that has its CreateNoWindow property set to true and its UseShellExecute set to false.
The ProcessStartInfo object can also be accessed via the Process.StartInfo property and can be set there directly before starting the process (easier if you have a small number of properties to setup).
Process bhd = new Process();
bhd.StartInfo.FileName = "NSOMod.exe";
bhd.StartInfo.Arguments = "/mod NSOmod /d";
bhd.StartInfo.CreateNoWindow = true;
bhd.StartInfo.UseShellExecute = false;
Is another way.
This is my code that does a similar thing, (and also reads the output and return code)
process.StartInfo.FileName = toolFilePath;
process.StartInfo.Arguments = parameters;
process.StartInfo.UseShellExecute = false; // needs to be false in order to redirect output
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true; // redirect all 3, as it should be all 3 or none
process.StartInfo.WorkingDirectory = Path.GetDirectoryName(toolFilePath);
process.StartInfo.Domain = domain;
process.StartInfo.UserName = userName;
process.StartInfo.Password = decryptedPassword;
process.Start();
output = process.StandardOutput.ReadToEnd(); // read the output here...
process.WaitForExit(); // ...then wait for exit, as after exit, it can't read the output
returnCode = process.ExitCode;
process.Close(); // once we have read the exit code, can close the process
How to hide cmd window while running a batch file?
I use the following code to run batch file
process = new Process();
process.StartInfo.FileName = batchFilePath;
process.Start();
If proc.StartInfo.UseShellExecute is false, then you are launching the process and can use:
proc.StartInfo.CreateNoWindow = true;
If proc.StartInfo.UseShellExecute is true, then the OS is launching the process and you have to provide a "hint" to the process via:
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
However the called application may ignore this latter request.
If using UseShellExecute = false, you might want to consider redirecting standard output/error, to capture any logging produced:
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += new DataReceivedEventHandler(ProcessOutputHandler);
proc.StartInfo.RedirectStandardError = true;
proc.ErrorDataReceived += new DataReceivedEventHandler(ProcessOutputHandler);
And have a function like
private void ProcessOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data)) // use the output outLine.Data somehow;
}
There's a good page covering CreateNoWindow this on an MSDN blog.
There is also a bug in Windows which may throw a dialog and defeat CreateNoWindow if you are passing a username/password. For details
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98476
http://support.microsoft.com/?kbid=818858
According to the Process properties, you do have a:
Property: CreateNoWindow
Notes: Allows you to run a command line program silently.
It does not flash a console window.
and:
Property: WindowStyle
Notes: Use this to set windows as hidden.
The author has used ProcessWindowStyle.Hidden often.
As an example!
static void LaunchCommandLineApp()
{
// For the example
const string ex1 = "C:\\";
const string ex2 = "C:\\Dir";
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "dcm2jpg.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "-f j -o \"" + ex1 + "\" -z 1.0 -s y " + ex2;
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// Log error.
}
}
Use:
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
This is what worked for me,
When you redirect all of the input and output, and set the window hidden it should work
Process p = new Process();
p.StartInfo.RedirectStandardError = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
try with this and this where the c# code is embedded into the batch files:
#echo off
echo self minimizing
call getCmdPid.bat
call windowMode.bat -pid %errorlevel% -mode minimized
echo --other commands--
pause
Though it might be not so easy to unhide the window.