Suppose I have a C# WinForms application and it is started by external program simply by using Process.Start(MyModule.exe).
I've tried to debug my code by using My project properties->Debug->Start Action->Start external program (with setting proper Working directory of course).
My enother attempt was Debug->Attach to process
UPDATE: Both my module and external program use one resource. So external program releases it, then calls Process.Start(), waits for my process to exit ans then capture the resource again. So I can't attach when your program is already running.
Both of them failed - breakpoint in Program.cs was never hit.
So, how can I debug my code in such circumstances?
There are two ways I know of to easily solve this problem. The first way is have your program request a debugger attach to it as the first thing it does in Main via Debugger.Launch()
public static void Main(string[] args)
{
Debugger.Launch();
//Rest of your code here
}
This will make a dialog like the following show up
This will allow you to attach to your running visual studio or start a new instance.
The other way to solve this when you can't use the previous method (for example I don't think it works inside services) is put a loop at the start of your code that will loop forever until a debugger is attached, this gives you enough time to do the "Attach to process" method you tried earlier without letting the program progress.
public static void Main(string[] args)
{
while(!Debugger.IsAttached)
{
Thread.Sleep(1000); //Sleep 1 second and then check again.
}
//Rest of your code here
}
There are two different methods you can use System.Diagnostics.Debugger.Launch() or System.Diagnostics.Debugger.Break() The first will attach a debugger (letting you choose which) and then do nothing. In the case where one is already attached nothing will happen.
The latter will do exactly as Launch in the case no debugger is attached and will serve as a break point if one is attached.
So simply write System.Diagnostics.Debugger.Break(); where you want your break point to be.
That will result in a dialog asking you how you wish to debug the program (which of course also means your should remove the line when your done debugging)
In the dialog choose the appropriate instance of VS (or create a new) and the simply continue debugging as usual
Related
I have a console Application Program on Visual Studio 2013.
.NET 4.5
I want the program to quit after doing a Certain task. SO, I use
System.Environment.Exit(0);
but it does not exit. It only displays on the console:
Press any key to continue.
How can i exit the Program?
Thanks in Advance.
Here iam checking if directory is empty, then exit the program, I also tried to put System.Environment.Exit(0); in the main function but it did nothing.
if (Directory.GetFiles(#"Q:\").Length == 0)
{
System.Environment.Exit(0);
}
Press any key to continue
Like a comment above said already, this sounds a lot like what your IDE (presumably Visual Studio) would print out once the process has terminated. On my machine, I get this message when I run a console application without attaching the debugger to it, e.g. by starting it with Ctrl+F5. Once I press a key, the console window spawned by Visual Studio will close. This is expected behaviour.
Try running your program with the debugger attached, e.g. by pressing F5. Or start the program from a command prompt instead of starting it from your IDE. The message shouldn't be displayed then.
Note also that if you have a multi-threaded program, and there are non-background threads running, these can keep a process alive even though the main thread has terminated.
The most graceful way to exit a console application is to return from the Main method.
Simply declare your main method as follows:
public static int Main(string[] args)
and you can use
return x;
to exit the application with the given return code.
try Application.Current.Shutdown()
I just wrote a clever program called helloworld. It's a C#/.NET 4.5 console app. Deep within the twisted nested mazes of logic there's use of Console.WriteLine().
When I'm running this at a command line, it runs and I see the output. I can do other commands and mess around a bit, and later scroll up to see the output again.
Now I'm in Visual Studio, tweaking the source ("Hi" is more efficient than "Hello") and testing by tapping F5. What happens is a console window pops up and immediately vanishes. I have no idea what the program printed. How can I see the output?
I don't want to modify my source at all. After searching for solutions, I find some who say to use Console.ReadKey() - but then it would suck to be using the program at the command line. There's no real reason the user should have to tap a key when the program has already done its work. Even if i go with this, there's the problem of the output disappearing when the console window closes after a key tap.
I don't want to use Debug.WriteLine() which does write to the output window in VS, but doesn't write ordinary output for the end user to see.
I have discovered ctrl-F5, which runs the program as if it had a final Console.ReadKey() line, but there's still the problem of when I tap any key, all the output vanishes along with the window. Three minutes later, I'm thinking "Oh wait, did it print 'Hello' or 'Helo'?" No way to check.
Seems like the Visual Studio IDE should somehow capture all that a freshly built program writes to its stdout or the Microsoft equivalent thereof, and show it in its "Output" panel, or some panel, for later scrutiny. Maybe it does do this, and I don't yet know the trick to it? Seems like this would be a common desire among millions of C# developers.
If you're working on a .NET Core console application (or .NET Framework via the .NET SDK) using Visual Studio 2019, the behaviour of leaving the console window open after the program has executed will now happen by default:
Specifically:
This should prevent the need to add Console.Read() calls to console apps to prevent the console window from closing immediately after the program has finished executing. The launched console window is also re-used for subsequent runs, so if you’re used to using ctrl+f5, you won’t have lots of console windows to close after you’ve launched your application a few times.
The reason it closes automaticly is because it's done running the program. If you want to see what it did, make it need a new command like hitting any key. The Console.ReadKey(); pauses it and waits for a User to hit a key to continue. Put that command after the commands of instruction you are doing and it will pause it until you hit any key.
Console.ReadKey(); // Pauses until you hit any key
You can also run your program pressing F10 (executes one line by one), with F11 (goes inside a function).
The other option you have is to set breakpoints in Visual Studion and run the program by pressing F5 - it will stop at the next breakpoint. And the breakpoints can have conditions - i.e. conditional breakpoints.
Some options are:
1. wrap #if DEBUG around Console.ReadKey()
2. run directly from an open terminal
3. create a Test project - but again you'll need Console.ReadKey() to stop it closing.
I'm writing a small library to help manage some objects in Excel. I'm testing this DLL using a simple console application that makes calls to the library, then prints the results out. I can then end the program in any of the typical fashions, usually by either hitting return (thus completing the ReadLine call) or hitting the window's close button. However, the reference to the Excel instance behaves differently based on how the program exits.
In my program, if no existing reference to Excel can be found, I use the following line:
_app = new ExcelInterop.Application();
where _app is an instance of Microsoft.Office.Interop.Excel.Application in either a static or singleton class (I've tried both, both have the same results).
Assuming the program creates it's own instance (and doesn't find one already open):
The instance will remain open if the program is exited by clicking the close window button:
The instance is released, and no longer appears in the task manager if the program is exited by reaching the end of the code in the Main block
Is there anyway to make all program ends behave like the latter case? Furthermore, this DLL will go on to be used in a WPF application, are there similar concerns in WPF? Or at large, even?
Perhaps most importantly, what are the technical reasons for this behavior?
A console mode program is a pretty hostile place for the COM interop wrapper objects that are needed for an apartment-threaded out-of-process COM server. This program demonstrates the issue:
using System;
class Program {
static void Main(string[] args) {
var prg = new Program();
Console.ReadLine();
}
~Program() {
Console.WriteLine("Clean-up completed");
System.Threading.Thread.Sleep(1500);
}
}
Try it both ways, by pressing Enter and by clicking the Close button. You'll see that the finalizer never gets executed. The operating system terminates the process before it gets a chance to shut down properly when you click the Close button.
Same problem with the finalizers for the COM wrappers. They cannot execute so IUnknown::Release() doesn't get called and the Office program is completely unaware that the client program is no longer there. Windows has its own cleanup for abandoned out-of-process servers but that doesn't work for Office programs for some otherwise mysterious reason.
That explains it, fixing it isn't so easy. You'll have to register a callback that runs when the Close button is clicked. If necessary, set the app reference to null if it is still in scope and force the finalizer to run with GC.Collect() + GC.WaitForPendingFinalizers(). Do keep in mind that this is just a band-aid, not a fix. It won't work when the user aborts your program while you are busy talking to the Office program. Avoiding a console mode project is best.
Nevermind why one might want to do this, I'm just curious to know if it can be done.
Here's my code that doesn't work:
if (!Debugger.IsAttached)
{
try
{
Debugger.Launch();
while (!Debugger.IsAttached)
{
Thread.Sleep(1000);
}
}
catch (System.Security.SecurityException e)
{
Console.WriteLine("exception " + e.Message);
}
}
Basically I was curious to know how to use the Debugger.Launch() method.
Debugger.Launch will launch a debugger or will do nothing is one is already attached. I believe It's not a breakpoint. Debugger.Break() will actually break.
Calling Debugger.Launch() may do different things depending on the machine, for example if Visual Studio is installed or not, etc.
See also a related tech article: How to: Launch the Debugger Automatically
It will launch and attaches a debugger to the process.
For sure do not use it in production . I think that possible use
can be in local machine when error occured and you want automatically run debug.
I think you're misunderstanding what Debugger.Launch() does. It functions like a hard-coded breakpoint.
When your program hits Debugger.Launch(), the Just-In-Time-Debugging window will show (assuming you have Visual Studio installed on the machine. At that point, your program is stopped - it doesn't keep running.
If you choose an instance of VS, it will be launched, and will be stopped on the line with Debugger.Launch(), as if you hit a breakpoint there.
So there is really no reason for the while() loop. You could just call Debugger.Launch() whenever you want to stop the program to look at something.
But the utility of Debugger.Launch() is questionable. You can much more easily use breakpoints, and with breakpoints there is no danger of accidentally leaving it in the finished product.
I'm trying to write a program to test student code against a good implementation. I have a C++ console app that will run one test at a time determined by the command line args and a C# .net forms app that calls the c++ app once for each test. The goal is to be able to detect not just pass/fail for each test, but also "infinite" (>5secs) loop and exceptions (their code dying for whatever reason).
The problem is that not all errors kill the C++ app. If they corrupt the heap the system calls __debugbreak which pops up a window saying Debug Error! HEAP CORRUPTION DETECTED... My C# app is using Process.WaitForExit(5000) to wait, but this error doesn't count as an exit, so I see a timeout.
So my question is, how can I either get the C# app to detect that this is an error OR how can I get the C++ app to die when this error occurs rather than giving a dialog box and asking if I want to debug?
Edit:
Here's the error that pops up: Debug Error
Here's the normal application failed dialog that pops up if I press retry in the previous dialog: Windows Error. The debug option goes away if you turn off the JIT debugger.
You should turn of JIT debugging, this page has instructions for how to turn it on or off.
Edit You can also use the _CrtSetReportMode and _CrtSetReportFile functions inside the C++ program to change the behaviour of the debug asserts (in particular, you can use _CRTDBG_MODE_FILE to write the contents of the message to a file instead of popping up a dialog.
If you're compiling the program as part of your tests, then you can just add your own .cpp file which includes a global class that does the work in it's constructor. Something like this:
// AssertModify.cpp
class AssertModify
{
public:
AssertModify()
{
::_CrtSetReportMode(...);
::_CrtSetReportFile(...);
}
};
AssertModify am;
This'll cause the code to run before main() is entered which should catch all possible cases (unless the student overrides your value themselves, but you can add a check for any calls to _CrtSetReportMode in their submitted code before you compile it)
I think you need to compile the C++ app in "release" mode. You're probably running "debug" builds which include asserts. Those asserts pop up MessageBoxes which is what you're seeing.
Since you want to catch the assertion failures, you can either modify the code when compiling it (as codeka suggests) or run the programs under a debugger. It's not that hard to make a C# app into a debugger using Mike Stall's wrapper, but it isn't exactly the easiest solution.