I'm having an issue with the following code:
private void Form1_Load(object sender, EventArgs e)
{
cmdOutput = new StringBuilder("");
cmdProcess = new Process();
cmdProcess.StartInfo.WorkingDirectory = #"C:\android-sdk\tools";
cmdProcess.StartInfo.FileName = #"java";
cmdProcess.StartInfo.Arguments = #"-Xmx512m -Djava.ext.dirs=lib\;lib\x86_64 -Dcom.android.monkeyrunner.bindir=..\framework -jar lib\monkeyrunner.jar";
cmdProcess.StartInfo.UseShellExecute = false;
cmdProcess.StartInfo.CreateNoWindow = true;
cmdProcess.StartInfo.RedirectStandardOutput = true;
cmdProcess.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
cmdProcess.StartInfo.RedirectStandardInput = true;
cmdProcess.Start();
cmdStreamWriter = cmdProcess.StandardInput;
cmdProcess.BeginOutputReadLine();
// Even if i fire this later it doesn't work.
cmdStreamWriter.WriteLine(#"print 'Hello World'");
}
The issue is that:
cmdStreamWriter.WriteLine(#"print 'Hello World'");
Is not doing anything. Nothing is being written to the java process.
The output appears to be working fine (tested by loading a script directly to monkeyrunner.jar. But after trying many times I'm not getting any input.
This does work fine if I change the process to "cmd"
I have managed to solve the issue:
From another issue I had I worked out that Jline (A java based command line extension) was being used. After some Googling I found that starting the Java app with:
cmdProcess.StartInfo.Arguments = #"-Xmx512m -Djava.ext.dirs=lib\;lib\x86_64 -Dcom.android.monkeyrunner.bindir=..\framework
-Djline.terminal=jline.UnsupportedTerminal -jar lib\monkeyrunner.jar";
The Amendment Being:
-Djline.terminal=jline.UnsupportedTerminal
This stopped Jline being loaded and allowed the standard input to work correctly again.
More information on -Djline.terminal argument can be found here:
http://jline.sourceforge.net/ - Installation.
Related
I'm currently working on a Winforms program from Visual Studio that acts as a control panel for a whole bunch of TeraTerm macros. I did a dumb and didn't add my first working version to version control, and now it's stopped working and I have no idea why/how to get back to what I had.
The function is question is
using System;
using System.IO.Ports;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Diagnostics;
...
namespace Test
{
public partial class MainWindow : Form
{
...
private void ImagesButton_Click(object sender, EventArgs e)
{
RunMacro("F:\\Users\\Isaac\\Documents\\LED Sign Commands\\Macros\\StartDisplayImages.ttl");
}
....
private void RunMacro(string userArgument)
{
panel1.Enabled = false;
StatusLabel.Visible = true;
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo()
{
WindowStyle = ProcessWindowStyle.Hidden,
#if DEBUG
FileName = "F:\\Users\\Isaac\\Documents\\LED Sign Commands\\teraterm\\ttpmacro.exe",
#else
FileName = "..\\teraterm\\ttpmacro.exe",
#endif
Arguments = userArgument
};
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
panel1.Enabled = true;
StatusLabel.Visible = false;
}
...
}
}
When run, I see that ttpmacro.exe does start, and if I omit the Arguments assignment then it will prompt me to select a macro; if I select StartDisplayImages.ttl, it will run as expected. If I include it as an argument as above, however, then ttpmacro still opens but immediately closes. No error comes up (and RedirectStandardOutput/Error produce nothing), it's as if ttpmacro accepts the file but won't do anything with it. I've confirmed both filepaths are valid and correct.
While I didn't add version control, I did extract the main file using ILSpy, and my original functions in the working version were:
private void ImagesButton_Click(object sender, EventArgs e)
{
RunMacro("/V ..\\Macros\\StartDisplayImages.ttl");
}
private void RunMacro(string userArgument)
{
panel1.Enabled = false;
StatusLabel.Visible = true;
Process process = new Process();
ProcessStartInfo startInfo = (process.StartInfo = new ProcessStartInfo
{
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "..\\teraterm\\ttpmacro.exe",
Arguments = userArgument
});
process.Start();
process.WaitForExit();
panel1.Enabled = true;
StatusLabel.Visible = false;
}
Being from the published release, the filepaths are relative to the folder of the application. Other than that, the only difference seems to be minor syntax in how process.StartInfo is assigned, but I tried reverting that with no luck. Target framework is .NET Core 3.1. The /V flag isn't the issue; removing it simply makes the ttpmacro window visible for the fraction of a second it runs before closing. If I use a commandline execution of the same file (eg start "F:/Users/.../ttpmacro.exe" "F:/.../StartDisplayImages.ttl"), it also runs as expected.
It turned out the problem was the spaces in the full macro filepath, and surrounding it with escaped double quotes resolved the issue. TeraTerm just wasn't telling me that it wasn't finding the file. Should have been obvious, but I was sure it had been working previously when I was debugging, without requiring the quotes.
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).
I'm quite newbie in C#. I'm trying to call a "subprocess" and retrieve its standard output. In the example above, I perform several tests. Some tests are done in VisualStudio (in "Debug" mode) and everything work as expected, no exception :)
The final application is compiled then launched. And the problems arrive...
the 1st part, with ...Start(si) works fine
the 2nd part, with ...Start() show the terminal command and no text (OK), but I never retrieve any text from standard output/error (proc_output and proc_error are empty)
If I change the String cmd_arg... from "git" with "systeminfo", recompile and restart, this time the 2nd part works ! (proc_output contains lots of text)
So, as far I can understand, the 2nd part is OK for "systeminfo" but not for "git". I have observed that "git" starts a sub-process (thread), but I don't know if this is the root cause.
I would greatly appreciated any help :) TIA
Code
//==============================================================================================//
String cmd_exe = "cmd.exe"; //
String cmd_arg = String.Format("/c \"{0}\"", "systeminfo"); //
//==============================================================================================//
System.Diagnostics.ProcessStartInfo si = new ProcessStartInfo(); //Always work, terminal window appears and text visible
si.FileName = cmd_exe ; //
si.Arguments = cmd_arg ; //
si.UseShellExecute = false ; //
si.WindowStyle = ProcessWindowStyle.Normal ; //
si.WorkingDirectory = Pack.SIM_DIR.Replace('/','\\'); //
System.Diagnostics.Process.Start(si); //Standardoutput is sent to screen
//==============================================================================================//
System.Diagnostics.Process proc = new System.Diagnostics.Process(); //Work within VisualStudio, DOES NOT work when the C# application is called as "sub" process
proc.StartInfo = si ; // Take exactly the same information as previous
proc.StartInfo.RedirectStandardOutput = true ; // Redirect output
proc.StartInfo.RedirectStandardError = true ; // Redirect error
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived); //
proc.ErrorDataReceived += new DataReceivedEventHandler(proc_ErrorDataReceived); //
proc_output = ""; proc_output_empty = true; //
proc_error = ""; proc_error_empty = true; //
proc.Start(); //VisualStudio=OK MSim=KO
proc.BeginOutputReadLine(); //
proc.BeginErrorReadLine(); //
proc.WaitForExit(10 * 1000); //
proc.Close(); //
//==============================================================================================//
I am trying to start excel with a file. It works fine when I run it with the same user. But with different user, only excel starts and that also with unknown error.
private void button1_Click(object sender, EventArgs e)
{
SecureString securePwd = new SecureString();
string password = "P#ssw0rd1";
SecureString sec_pass = new SecureString();
Array.ForEach(password.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = "c:\\Program Files\\Microsoft Office\\Office15\\EXCEL.EXE";
ps.Arguments = "c:\\test_folder\\test.xlsx";
ps.WorkingDirectory = "c:\\test_folder";
ps.Domain = "test.local";
ps.UserName = "testuser";
ps.Password = sec_pass;
ps.UseShellExecute = false;
Process.Start(ps);
}
The very same code works perfectly fine by changing the process from
ps.FileName = "c:\Program Files\Microsoft Office\Office15\EXCEL.EXE";
to
ps.FileName = "notepad.EXE";
had there be any rights issue even notepad.exe also should not work.
Knowing that it's an old post, still leaving a reply for someone like me with a similar problem.
Looking at your code, it seems that you may need to set the "ps.UseShellExecute" as "true". I tried a similar code (given below) with a button in my WPF app, and it opens the excel file without issues.
private void Button_Click(object sender, RoutedEventArgs e)
{
string myPath = #"C:\Users\Lenovo\Documents\MyFile.xlsx";
ProcessStartInfo ps = new ProcessStartInfo();
ps.FileName = "excel"; // "EXCEL.EXE" also works
ps.Arguments = myPath;
ps.UseShellExecute = true;
Process.Start(ps);
}
And of course, don't forget to add the following line at the top of your .cs script.
using System.Diagnostics;
Well then, Happy coding :)
There doesn't seem to be any problem withe the code. As without changing a bit, it just started working fine again. Simply nothing. This just opens up a question like what the problem was.?
Any suggestions.?
This is very normal thing. if you working for example in company and you open share Excel file with your friend one of you will get information "File is open by another user" you can resolve this situation copy this file to for example C:/Temp and later replace it on share space.
[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.