Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

C# Process.Start() never ends when starting TCC/LE process?

Sep
5
0
I am starting TCC/LE 13.06.77 x64 on Windows 7 using C# and the RunExternalExe() method from [1] to run a .btm file from my C# program. While I was developing and testing I was running with the Visual Studio 2012 debugger and everything worked fine. However, when I try running outside the debugger the TCC/LE process never returns? Once I forcefully terminate my program I can see my .btm file did everything I wanted it to do.

I tried a no-op.btm that looks like this:

@echo off
echo %1 %2
exit​

and the same thing happens.

The Process.StandardOutput Property documentation [2] discusses a possible deadlock issue but the RunExternalExe() method seems to use the suggested technique to avoid it.

I even just tried starting the process and not bothering to capture the script output. The interesting thing is that then my C# program's window suddenly hides itself when I start my TCC/LE process and I have to use the Task Manager to kill it. If I remove the /H startup option, then my window no longer disappears and the process doesn't hang. So it seems that TCC/LE started as a child process thinks my C# window is its window? Looks like a bug to me?

In order to capture the script output, I had to change RunExternalExe() from:
process.StartInfo.CreateNoWindow = true;​
to:
process.StartInfo.CreateNoWindow = false;​

It doesn't matter if the /H startup option is specified or not in this case.

The ProcessStartInfo Class documentation [3] says CreateNoWindow:

"Gets or sets a value indicating whether to start the process in a
new window."​

Things then work, but every time I need to run my .btm file (and it can be many times) a console window opens and then quickly closes.

So my questions are:
  1. Why does my program work with the Visual Studio 2012 debugger, but not outside of it?

  2. Why does the TCC/LE /H startup option hide my C# program window?

  3. Why does starting the process in a new window fix things?

  4. Is there some way to run a TCC/LE .btm file from C# without having a console window flash open and then close?
OT: Just a heads up for anyone else who tries this. My TCC startup command line initially looked like:

/H /C c:\myTCCStartupDir\mybatchfile.btm​

When I was developing I of course had a TCC/LE window open with the Help file displayed. But during further "live" testing, I soon found that I was getting Unknow Command errors for a TCC alias I was using. Seems obvious now, but aliases by default are "global" so my C# launched TCC/LE process was getting its aliases from my open TCC/LE window. My startup command now looks like:

//TCStartPath=c:\myTCCStartupDir /H /L: /S /C c:\myTCCStartupDir\mybatchfile.btm​

where I explicitly say where my TCStartup file (with my aliases) is located. I also use /L: to turn off all global lists for aliases, history, etc. This ensures that my program works the same whether or not a TCC/LE window is open. I added the /S switch in hopes it would solve the process hanging issue but it seems to make no difference.

[1] http://stackoverflow.com/questions/206323/how-to-execute-command-line-in-c-get-std-out-results

I changed:

process.OutputDataReceived += (sender, args) => stdOutput.Append(args.Data);

to:

process.OutputDataReceived +=
(sender, args) => stdOutput.Append(args.Data + Environment.NewLine);

since I noticed that all the output lines were getting jammed together otherwise.

I also added process.Dispose() to avoid memory leaking.​

[2] http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx

[3] http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.aspx
 
I don't know C# and I didn't read very carefully ... ignore me if I'm way off base.

4. (just a guess)TCC is inheriting your app's console window and hiding it (/H).

If you use /K (and not /C) the TCC will not be transient and the console will stay open.
 
I should have been clearer. My program is a C# 4.5 WPF GUI program (wiith menubar, listview, etc, etc). I'm pretty sure using /K is exactly the wrong thing to do. That would force my process to hang since TCC/LE would never exit --- and RunExternalExe() is calling process.WaitForExit().
 
I know about nothing else in the thread, but using /K to start TCC, and using the TCC command EXIT at the end of your batch file, TCC will terminate on executing EXIT.
 
  1. Why does my program work with the Visual Studio 2012 debugger, but not outside of it?
  2. Why does the TCC/LE /H startup option hide my C# program window?
  3. Why does starting the process in a new window fix things?
  4. Is there some way to run a TCC/LE .btm file from C# without having a console window flash open and then close?

1. I don't know -- perhaps an environmental difference?

2. C# feature/bug - TCC/LE definitely does *not* think that the GUI is its window, it only looks for console windows. However, mixed mode apps (containing both a GUI and console window) tend to be treated unpredictably by Windows, and in this case hiding the console window triggers C# into hiding the GUI window as well.

3. See above.

4. Windows unfeature -- you cannot start a console session hidden. You can only start it with a visible console and then immediately hide it. (This has been a royal PITA for 4NT / Take Command / TCC for many years.)
 
4. Windows unfeature -- you cannot start a console session hidden. You can only start it with a visible console and then immediately hide it. (This has been a royal PITA for 4NT / Take Command / TCC for many years.)

Well, as mentioned in my initial post, I can start and run a hidden console session that executes my .btm script, I just can't capture the script output then.

I tried also redirecting stdin, and then writing "exit" to it after reading stderr to completion. Didn't help. Personally, I think something funky is happening with redirecting stdout & stderr on console programs. C# is waiting for one of those to signal EOF or something and they never do unless they have an actual console window attached. RunExternalExe() works fine with normal "command line programs" that just write to stdout & stderr. So console windows or at least TCC/LE are doing something different.

For now I've decided I can live without capturing the script output (oh well) and call my RunExternalExeNoCapture() instead. This works without flashing open/close a console window and without hanging my C# 4.5 WPF GUI program.

If, in the future I decide I really need the script output, I'll keep in mind your information and just grit my teeth that the console window flashing is unavoidable.

I also gather then that switching to Powershell or just using the normal Command Prompt (ugh) wouldn't help?

Thanks for your assistance.
 
Last edited:
Back
Top