I want to start a php script with my local php.exe and don't want to see the cmd-window that appears when I do so.
This is my code:
System.Diagnostics.Process.Start(AppDomain.CurrentDomain.BaseDirectory + #"php.exe", "script.php");
What argument can I use to make the php.exe invisible?
I read something about a "php-win.exe" but I have to do it with the normal php.exe and already tried some other methods (like hide.exe) but none of them would work.
Pass a Process start info to Process.Start instead.
var info = new ProcessStartInfo(AppDomain.CurrentDomain.BaseDirectory + #"php.exe", "script.php")
{
// check the various properties to define your process. For example:
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
};
Process.Start(info);
Related
I'm writing an application, and at one point it launches win-acme and needs to pass some parametres to it. I'm successfully opening powershell and launching win-acme, but it doesn't pass arguments to it. So, I have this code:
Process wacsProcess = Process.Start(new ProcessStartInfo
{
FileName = #"C:\Windows\System32\WindowsPowershell\v1.0\powershell.exe",
Arguments = (#"cd C:\inetpub\letsencrypt ; .\wacs.exe ; N"),
RedirectStandardOutput = true,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
});
File.WriteAllText(".\\OutPutAfterFirstLaunch.txt",
wacsProcess.StandardOutput.ReadToEnd());
It opens command-line utility, but doesn't give it the last parametr "N". I guess that is because I'm passing this parametr to the powershell, but it's still working with win-acme.
It looks like this:
Is there a way to pass an argument to the command line utility using C#?
This is how this application is designed. It is meant to be interactive for new certificates. Please see the documentation with all of the allowed command-line arguments: https://www.win-acme.com/reference/cli
Is there a particular reason that you must launch the process from powershell?
You should be able to read the stdout of the process if you launch it directly the same way as if you were reading the output from your powershell window (the output powershell displays is just the stdout of the process anyways.)
You can also try passing the N parameter with the executable,
Arguments = (#"cd C:\inetpub\letsencrypt ; .\wacs.exe N;"),
I'm firing off a Java application from inside of a C# .NET console application. It works fine for the case where the Java application doesn't care what the "default" directory is, but fails for a Java application that only searches the current directory for support files.
Is there a process parameter that can be set to specify the default directory that a process is started in?
Yes!
ProcessStartInfo Has a property called WorkingDirectory, just use:
...
using System.Diagnostics;
...
var startInfo = new ProcessStartInfo();
startInfo.WorkingDirectory = // working directory
// set additional properties
Process proc = Process.Start(startInfo);
Use the ProcessStartInfo.WorkingDirectory property to set it prior to starting the process. If the property is not set, the default working directory is %SYSTEMROOT%\system32.
You can determine the value of %SYSTEMROOT% by using:
string _systemRoot = Environment.GetEnvironmentVariable("SYSTEMROOT");
Here is some sample code that opens Notepad.exe with a working directory of %ProgramFiles%:
...
using System.Diagnostics;
...
ProcessStartInfo _processStartInfo = new ProcessStartInfo();
_processStartInfo.WorkingDirectory = #"%ProgramFiles%";
_processStartInfo.FileName = #"Notepad.exe";
_processStartInfo.Arguments = "test.txt";
_processStartInfo.CreateNoWindow = true;
Process myProcess = Process.Start(_processStartInfo);
There is also an Environment variable that controls the current working directory for your process that you can access directly through the Environment.CurrentDirectory property .
Just a note after hitting my head trying to implement this.
Setting the WorkingDirectory value does not work if you have "UseShellExecute" set to false.
Use the ProcessStartInfo.WorkingDirectory property.
Docs here.
The Process.Start method has an overload that takes an instance of ProcessStartInfo. This class has a property called "WorkingDirectory".
Set that property to the folder you want to use and that should make it start up in the correct folder.
Use the ProcessStartInfo class and assign a value to the WorkingDirectory property.
When I try to run cmd command 'efwmgr C: -commit' from C#, got empty log file without any information, and when check manually 'ewfmgr C:', got 'Boot Command NO_CMD', so commit not run.
Same code just changed Arguments = "/C chkdsk C:" it runs and works well, inserted whole output into my log.
Method which I used.
public static void StartProcess()
{
var procStartInfo = new ProcessStartInfo
{
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Normal,
FileName = "cmd",
Arguments = "/C ewfmgr C: -commit",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true
};
var process = new Process { StartInfo = procStartInfo, EnableRaisingEvents = true };
using (StreamWriter writer = new StreamWriter(#"D:\commitFile.txt"))
{
process.OutputDataReceived += (sender, e) =>
{
writer.WriteLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
process.WaitForExit();
}
}
This is the nearly example I found on https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e014365-8e8f-4f93-998a-156f2e55ebab/how-to-get-and-write-ewf-current-to-text-file-using-c?forum=csharpgeneral
You probably getting an error in process error output stream. Append your log in ErrorDataReceived event handler. And for the 'ewfmgr' is not recognized as an internal or external command you should edit process environment variable or specify full path to your application.
This is how you code should look like:
var procStartInfo = new ProcessStartInfo
{
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Normal,
FileName = "cmd",
//Append PATH environment variable bellow if you use this
Arguments = "/C ewfmgr C: -commit",
//Or use full path to application without changing environment variable
//Arguments = "/C c:\full\path\to\application\ewfmgr C: -commit",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardInput = true,
RedirectStandardError = true
};
procStartInfo.EnvironmentVariables["PATH"] += #";c:\full\path\to\application\";
var process = new Process { StartInfo = procStartInfo, EnableRaisingEvents = true };
using (StreamWriter writer = new StreamWriter(#"D:\commitFile.txt"))
{
process.OutputDataReceived += (sender, e) =>
{
writer.WriteLine(e.Data);
};
process.ErrorDataReceived+= (sender, e) =>
{
writer.WriteLine(e.Data);
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
}
Just wanted to point out an update regarding this issue for anyone that might encounter this, or any other file "missing" from Windows/System32 directory:
First things to check is your system architecture, and your process architecture:
There are several posts about this feature (although I prefer to call it issue), I can safely say that this one explains it correclty, and that ewfmgr.exe works just fine if you set your architecture correclty.
In order not to rely on another post/link, I'll rewrite/copy the answer from David there:
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.
As a side note I'd like to also add that by default, VS projects for C# are set as "Any CPU" configuration, however there's checkbox ticked in project properties on the build tab, that says "Prefer 32-bit": This needs to be unchecked/disabled, or "Any cpu" build will result in 32 bit application as well.
Other than that, I've successfully implemented fully working EWF manager into our service application. Unfortunatelly I haven't had any luck using pInvoke and ewfapi dll, since it didn't seem to return correct results. I'm not sure yet whether there was an issue in implementation, or whether the EWF api itself is broken (to be honest, its really buggy and unreliable. For us specifically, the "Disable" command does nothing - after reboot, ewf is still enabled. The only way to disable it is to Disable and Commit, or use CommitAndDisableLive, which both unfortunatelly commit current state onto the drive, so I had to use fallback and reboot the machine before disabling protection, to be sure its in clean state), so I went the route to call it using command line, and parse response parameters to control it. Unfortunatelly it was time critical and I needed production ready solution, so I had to make a workaround, but I'll post a separate question about the pInvoke, and then put on GitHub altogether as a final solution.
I'll come back and edit this post to include the GitHub link once I have the time to upload it. Should someone need it right away, I'm happy to send it over as-is.
Hope it helps.
I need to run an elevated command in my c# application and get the output.
I'm creating a new System.Diagnostics.Process instance, coupled with a new System.Diagnostics.ProcessStartInfo instance.
The command is being sent to cmd.exe, and unfortunately may require elevated user access (meaning UseShellExecute = true and Verb = "runas" must be present).
As a result of using UseShellExecute = true, RedirectStandardOutput will not work.
It's important I record the output of the command, but the only way I can see of getting this is adding something like > output.txt to the argument list, then calling System.IO.File.ReadAllText to read the result.
Can anyone think of less hacky way?
I have a windows form application
Lets call it B
Now i have another application. Lets call it A
A will start B as a new process
Now i want to pass named parameter list to B and use them in B
How can i do that ?
What i mean is example parameter list
{job:"computer engineer",age:"32",experience:"3 years"}
Also these parameter list should be optional. Sometimes i may pass 5 parameters sometimes 0
And how will i read these parameters at start up on B application
So what is the way of doing this ? thank you
c#
Assuming you're calling your "B" process with Process.Start, the following should work:
System.Diagnostics.Process.Start(string fileName, string arguments)
And your "B" processes main thread should accept an array to house possible arguments that you can then iterate over.
static void Main(string[] args)
{
//your code to decipher arguments here
}
There are two ways I can think of doing this.
First is to use command line arguments. If you were to call you process (from the command line) as:
your.exe -job "computer engineer" -age 32 -experience "3 years"
You would then duplicate this in your code by settings the arguments in your process's start options. You would then have to set up your process to look for all of these flags, remembering that they can all be optional, and so on.
The second option (and this is a bit more flexible) is to make a file that holds the values you are passing over, and read it from your launched process. You could make this XML, or straight values.
Edit: here is an example of the first option
Process p = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "your exe path";
startInfo.Arguments = "your argument list";
p.StartInfo = startInfo;
p.Start();
I don't want to tell you how to format your argument string; that should be up to you to decide. However, I will recommend a library to use that might make the parsing on the receiving end a bit easier.