Calling jhead from a Console Application via Process does nothing - c#

[Updated]
Turns out it couldn't not find the path to jpegtran. When you start a new process it does not seem to use the system's path variable.
I figured it out. I needed to add proc.StartInfo.WorkingDirectory = #"c:\ImageMagick";
This way it knows where to find the other program.
I've been banging my head on the desk. Based on all the examples I've seen it should be so simple.
I'm trying to run jhead.exe to auto rotate a bunch of images. I don't care if I do it one at a time or all at once. So I'm basically executing the
jhead.exe -autorot c:\RotateMe\imagename001.jpg
So to do this I've implemented the following code.
private void button3_Click(object sender, EventArgs e)
{
string strTarget = #"C:\RotateMe";
DirectoryInfo dir = new DirectoryInfo(strTarget);
int maxFiles = dir.GetFiles("*.jpg").Length;
System.Diagnostics.Process proc = new System.Diagnostics.Process();
foreach (FileInfo f in dir.GetFiles("*.jpg"))
{
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = #"c:\ImageMagick\jhead.exe";
//added this line
proc.StartInfo.WorkingDirectory = #"c:\ImageMagick";
proc.StartInfo.Arguments = string.Format(#"-autorot {0}", f.FullName.ToString());
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
proc.WaitForExit();
}
}
Nothing happens.. If I set CreateNoWindow to False I get cmd boxes popping up. But too fast to see anything.
I've tried getting the StandardOutput to write to the console so I can at least see what happens. But I get nothing there either.
I know this isn't a whole lot to go on. But it seems simple enough... and I'm not getting it.

Related

Is there a way to run a program if its path exceeds MAX_PATH?

I need to spawn processes from my C# program, but in some cases full path to an executable can be more then 256 characters.
I have studied several related topics on this site, as well as this article #MSDN. According to that information this should be possible by using \\?\ prefix, but I still couldn't make it work. It looks like system tries to start the process, but fails. I am getting "SmartScreen has stopped working" message instead.
Am I missing something? Here is my code:
private void button2_Click(object sender, EventArgs e)
{
ProcessStartInfo start = new ProcessStartInfo();
start.Arguments = "";
start.FileName = #"\\?\c:\11111111111111111111111111111111111111111111\222222222222222222222222222222222222222222222\3333333333333333333333333333333333333333333333\444444444444444444444444444444444444444444444\5555555555555555555555555555555555555555555555\6666666666666666666666666666666666666666666666\test.exe";
start.WindowStyle = ProcessWindowStyle.Normal;
start.CreateNoWindow = true;
int exitCode;
using (Process proc = Process.Start(start))
{
proc.WaitForExit();
exitCode = proc.ExitCode;
MessageBox.Show(String.Format("Exit code: {0}", exitCode));
}
}
I am running this on Windows 10, version 1703 (OS Build 15063.1387).

Redirecting Input of a process (notepad)

I am trying to open a Notepad process and write strings into it after initialization.
This is just a "POC" for my real goal which is to start a process, a user terminal of some sort, and completely control it through my app.
I searched the question here in different forms and found this link which was exactly what I was searching for!
Unfortunately, it doesn't work :/
This is the simple code:
static void Main(string[] args)
{
ProcessStartInfo ProcessInfo = new ProcessStartInfo("notepad");
ProcessInfo.RedirectStandardInput = true;
ProcessInfo.RedirectStandardOutput = true;
ProcessInfo.RedirectStandardError = true;
ProcessInfo.UseShellExecute = false;
ProcessInfo.ErrorDialog = false;
Process aProcess = new Process();
aProcess.StartInfo = ProcessInfo;
aProcess.Start();
StreamWriter processWriter = aProcess.StandardInput;
StreamReader processReader = aProcess.StandardOutput;
StreamReader processError = aProcess.StandardError;
while (!aProcess.Responding)
{
System.Threading.Thread.Sleep(5000);
}
processWriter.WriteLine("OMG IT FINALLY WORKED");
aProcess.WaitForExit();
}
The notepad process opens up but the information I tried to write with my processWriter is not present.
Does anyone have any idea why it's not working and how to make it work without walkarounds like using keystrokes and stuff?
Thanks in advance!

Trigger Apache Nutch Crawl Programmatically

I'm trying to create a ASP.NET web api to trigger a crawl event to happen. I can't seem to get cygwin to process any of the commands I give it. The only thing I can really do is get it to open a terminal. Once the terminal is open I'd have to redirect the pwd to another location and then trigger my command I want.
Process p = new Process();
ProcessStartInfo info = new ProcessStartInfo();
info.CreateNoWindow = false;
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.FileName = "C:\\cygwin64\\bin\\mintty.exe";
p.StartInfo = info;
p.Start();
StreamWriter sw = p.StandardInput;
if (sw.BaseStream.CanWrite)
{
sw.WriteLine(#"cd C:\Users\UName\Desktop\apache-nutch-2.3-mongodb\runtime\local\");
sw.WriteLine("bin/autoCrawl");
}
sw.Close();
p.WaitForExit();
I've tried many approaches, this is the last one I've tried but it just does nothing. Is there a way to launch this crawl from my .NET application? I've looked into the NutchApi about creating a new job with a type of crawl but I'm not sure if that applies here or not.
I ended up figuring out how to use the NutchApi to answer my question.

Print standard output of a process to a text box WHILE process is running?

I have a C# GUI from which I run a python script that takes about 2 minutes. Rather than direct the output of the Python script to a file, I'd like to have GUI show all the print-outs that the Python script makes, say, in a text box, as the process is running. Any solution I've found typically waits for the process to end before redirecting the standard output to the text box, and I'm not sure if I'm searching for a solution correctly. Does anyone have an idea about how to do this? Here's some code for reference:
using (Process proc = new Process())
{
debug_output.AppendText("All debug output will be listed below\n");
string pyFileName = "hello.py";
string args = "arg1";
proc.StartInfo.FileName = "C:\\Python27\\python.exe";
proc.StartInfo.Arguments = string.Format("{0} {1}", pyFileName, args);
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.OutputDataReceived += new DataReceivedEventHandler(MyProcOutputHandler);
proc.Start();
proc.BeginOutputReadLine();
while (!proc.HasExited)
{
Application.DoEvents();
}
}
With The following Handler:
private void MyProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
{
if (debug_output.InvokeRequired)
{
debug_output.BeginInvoke(new DataReceivedEventHandler(MyProcOutputHandler), new[] { sendingProcess, outLine });
}
else
{
debug_output.AppendText(outLine.Data);
debug_output.AppendText("\n");
}
}
Console.WriteLine(outLine.Data);
}
As an update, I tried the solution from this post since it looks like the exact same problem, but I still don't get it working. My output ends up in the right place, but only after the whole script is done running. Please help.

How to pass the arguments to a batch file?

I have requirement to run a set of *.sql files using batch file like this.
private void btn_Execute_Click(object sender, EventArgs e)
{
try {
//Creating A batch file to execute the scripts using SQLPLUS....
FileInfo fi5 = new FileInfo("c:/EMPSCRIPTS/execute.bat");
StreamWriter sw2 = fi5.CreateText();
sw2.WriteLine("#Echo Off \r \nsqlplus scotte/tiger#emp #\"c:/EMPSCRIPTS/RUNALL.sql\" \r \nEXIT ");
sw2.Close();
System.Diagnostics.Process proc; // Declare New Process
proc = System.Diagnostics.Process.Start(ConfigurationManager.AppSettings["BatFilePath"].ToString()); // run test.bat from command line.
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.Arguments = "/c" + ConfigurationManager.AppSettings["BatFilePath"].ToString();
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
proc.Close();
}
catch (Exception ex) {
MessageBox.Show("Insertion Completed");
}
}
But I want to stop some files being executed unnecessarily. I found the option for passing the parameters. I want to give the parameters to the files staticly. Based on the users input that parameter has to execute. Could any one help me?
Thanks in Advance.
You're changing the values of StartInfo after the process has been started, which has no effect on the process. See the "Remarks" section here for more information.
Create a new instance of ProcessStartInfo, set it up with what you need, then pass it into the overload of Start that takes an instance of this type.
In addition, once you change your code around, you can probably skip writing the command line to the batch file. Your executable filename is sqlplus and your arguments are scotte/tiger#emp #\"c:/EMPSCRIPTS/RUNALL.sql\"
You're misusing Process.Start.
You need to create a new ProcessStartInfo object, set all of its properties, then pass it to Process.Start.
Modifying the StartInfo of an already-running process, as your code is doing, has no effect.

Categories

Resources