i am working with services using C#, and for some stuff i need to get deepfreeze state of the station (frozen or thawed), for this found this on Faronic's documentation , when i use the following command in command prompt : C:\WINDOWS\syswow64\DFC.exe get /ISFROZEN it works and returns "THAWED." or "FROZEN." so i decided in my C# program to run a command prompt and redirect the Standard output to get the result of the command into a string variable , but it has not worked, i tried with any other commands and it works , i do not understand where is the problem.
there is the DFC.exe download link if it does not exists ( complete the captcha and click to download)
It is my third day on it so i need help .. thank's for everyone , there is sample code :
string pathDf = #"C:\WINDOWS\syswow64\DFC.exe";
string cmdline = string.Format("{0} get /ISFROZEN ", pathDf);
string msg = "";
if (File.Exists(pathDf))
{
Process cmd = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.FileName = "cmd.exe";
startInfo.CreateNoWindow = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
cmd.StartInfo = startInfo;
cmd.Start();
cmd.StandardInput.WriteLine(cmdline);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
Console.ReadKey();
}
the command still not works .. but i found another way to get deepfreeze state , using registry key
private static string GetDeepFreezeState()
{
string result = "";
try
{
RegistryKey key = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\WOW6432Node\Faronics\Deep Freeze 6");
if (key != null)
{
Object o = key.GetValue("DF Status");
if (o != null)
{
result = o.ToString();
}
}
}
catch (Exception ex)
{
//react appropriately
FilesUtilities.WriteLog(ex.Message,FilesUtilities.ErrorType.Error);
}
return result;
}
Maybe it will help someone.
On the other hand i still not able to run deepfreeze command line on my C# program, if someone has an answer , please help...
Another way to get Deepfreeze state using registry key
$path = 'HKLM:\SOFTWARE\WOW6432Node\Faronics\Deep Freeze 6'
$Key = 'DF Status'
$State = Get-ItemPropertyValue -path $path -name $Key -ErrorAction SilentlyContinue
if ($State='Frozen') {Echo "Deepfreeze is currently Frozen"} else {Echo "Deepfreeze is currently UN-Frozen"}
pause
Related
I am trying to execute netstat command from my C# code and get "File Not Found" error.
Do I have to specify where "netstat.exe" is?
If so, how would I do it if (hypothetically) netstat and findstr are in two different folders?
Process cmd = new Process();
cmd.StartInfo.FileName = "netstat -a | findstr 5840";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
try
{
cmd.Start();
}
catch (System.ComponentModel.Win32Exception ex)
{
Console.WriteLine(ex.Message);
}
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
StreamReader reader = cmd.StandardOutput;
string output = reader.ReadToEnd();
Console.WriteLine(output);
This is what fixed the problem:
// create the ProcessStartInfo using "cmd" as the program to be run and "/c " as the parameters.
// /c tells cmd that we want it to execute the command that follows and then exit.
string command = "netstat -a | findstr " + sTCPPort;
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + 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 = true;
// Now we create a process, assign its ProcessStartInfo and start it
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
// Get the output into a string
result = proc.StandardOutput.ReadToEnd();
Without seeing the exact it is hard to know the exact issue, but it looks like you may need to cmd.exe and pass your command to it as an argument.
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
I have a cmd command to start/stop application pool in server/windows and it works:
My problem is same code doesnt work in c#, code returns no error or info.
C# Code:
public static string StopAppPoolCmd
{
get { return "cd %SYSTEMROOT%/System32/inetsrv & appcmd stop apppool /apppool.name:\"{0}\""; }
}
public static string StartAppPoolCmd
{
get { return "cd %SYSTEMROOT%/System32/inetsrv & appcmd start apppool /apppool.name:\"{0}\""; }
}
// Run Commands
var cmd = new System.Diagnostics.Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
/* execute "dir" */
cmd.StandardInput.WriteLine(string.Format(start ? StartAppPoolCmd : StopAppPoolCmd, serviceName));
//flush object
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
//
// OUTPUT
var result = Tools.CleanShellOutput(cmd.StandardOutput.ReadToEnd());
Console.WriteLine(result);
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.
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
}