Catch run time exception of windows application - process

I have some windows applications. I will run all those Apps one by one from a console application. If any application produces run time exception, then it should save that exception's details and need to move to the next application.
I have tried the solution given in the below link:
catch another process unhandled exception.
But it is not solving my problem.
For Ex:
From my console app, calling the windows app named 'App1.exe'. If the App1 gives run time exception, it should be logged by console app and continue the rest.
Please anyone provide an optimal solution or an idea to get the unhandled exceptions's details of the applications which are all providing exception at run time.

Your options are one or the combination of those:
use the return code of your app in you console app
catch and log exceptions (like in a file or wathever) from the app itself and process log file in the console app.
Here is the code of a console app that starts another app and waits to get the return code of the app process. If the exception you mention occurs in the app you get an error code of 255, 0 if no error.
static void Main(string[] args)
{
try
{
var process = Process.Start("WpfApplication1.exe");
process.WaitForExit();
Console.WriteLine("App exited with code " + process.ExitCode);
Console.ReadKey();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
If you don't want exceptions to be shown in a UI within the app, you have to catch them in the app itself (and log them to process them in the console app if needed).

Related

Minimal Hosting Model: Exited from Program.Main with exit code = '0'

After migrating an ASP.NET Core 6 app from the legacy Program/Startup to use the new minimal hosting model, I am receiving a non-descript set of errors.
Error Messages
I have explicitly enabled UseDeveloperExceptionPage() to be safe, but all I am receiving in the browser is the generic:
HTTP Error 500.30 - ASP.NET Core app failed to start
In the Event Viewer, Event 1011 gets logged:
Application '/LM/W3SVC/2/ROOT' with physical root 'C:\Code' has exited from Program.Main with exit code = '0'. Please check the stderr logs for more information.
Followed by Event 1007:
Application '/LM/W3SVC/2/ROOT' with physical root 'C:\Code' failed to load coreclr.
Exception message:
CLR worker thread exited prematurely
No further information is available in the debug console when running either IIS Express or Kestrel. I am, however, able to see other startup processes from my Program being logged, so know they're loading correctly.
Code
This is a simplified version of my Program file, with custom components removed:
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.ViewComponents;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Should be implicit in Debug mode, but explicitly including to be safe
app.UseDeveloperExceptionPage();
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
Previous Threads
As these are really general errors, there are quite a few previous threads available related to this issue—but none that seem applicable to this case. (Many have to do with the ASP.NET Core Hosting Bundle, which I am not using.)
Question
Are there common causes for this issue? Alternatively, are there other approaches for debugging this scenario?
The error messages aren't terribly intuitive, but this error essentially means that the application ran, and then immediately exited. A common cause of this is when you neglect to add the Run() command at the end of the Program:
app.Run();
Background
This is easy to miss if you're focused on migrating your ConfigureServices() and Configure() methods from your Startup class. While most of your previous configuration code likely lives in that class, the Run() method is one of a few pieces that needs to be migrated from your legacy Program class. You might recognize it from your legacy Main() method; e.g.,
public static void Main(string[] args) => CreateHostBuilder(args).Build().Run();
In the new ASP.NET Core 6 minimal hosting model, this gets translated to:
var builder = WebApplication.CreateBuilder(args);
// Configuration from Startup.ConfigureService()
var app = builder.Build();
// Configuration from Startup.Configure()
app.Run();
When it exits from Program.Main() with exit code 0, that's telling you that your Program ran correctly—and, thus, seeing logging for your configuration code—but then it stopped without ever actually launching your web application.
Simple fix once you know to look for it.

How to restart Kestrel Hosted in Windows Service?

I want to restart Kestrel (asp.net core 3.1) via an authorized http request.
Kestrel is contained in a Windows service configured to restart itself automatically upon failure.
As far as i know the simplest way is to return an exit code different from 0, windows will do all the rest.
In light of that, the code I wrote is actually simple:
public MaintenanceController(IHostApplicationLifetime hostLifetime)
{
this.HostLifetime = hostLifetime ?? throw new ArgumentNullException(nameof(hostLifetime));
}
[HttpPost]
[Route("service/restart")]
[Authorize("AdminOnly")]
public ActionResult RestartService()
{
Program.IsRestart = true; //see below
this.HostLifetime.StopApplication();
//this does not work!
if (HostLifetime is WindowsServiceLifetime lifetime)
{
lifetime.ExitCode = 1;
}
//neither this!
Environment.ExitCode = 1;
return Ok();
}
The only way to make windows restarts the service is just actually call
Environment.Exit(1);
without HostLifetime.StopApplication();
But the issue with Environment.Exit called alone is it causes a non graceful shutdown, something I want absolutely to avoid.
Another approach I tried, to force an exit code different from 0, which did not work, was to put in Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime)
{
[...]
applicationLifetime.ApplicationStopped.Register(() =>
{
//this can be set in the controller
if (Program.IsRestart)
{
Environment.Exit(1);
}
});
}
but, when called after ApplicationStopped, Environment.Exit(1) does apparently nothing, in fact even inside event viewer there is no trace of the services' shutdown with error, so windows does nothing.
UPDATE
Going back to classic, I changed the Main entry point to return an int and returned 1.
Still windows does not restart the service nor a failure entry is written to event viewer. It looks like is always stopped gracefully
Everything is working like it should. You may want to consider writing a wrapper batch file or watcher process.
Your watcher would wait for the process to exit, and if a flag file (e.g. .staydown) is present, it would exit gracefully. If the file doesn't exist, it would then restart the process.
In your RestartService method, use Environment.Exit(0) which would be a graceful shutdown, but since the .staydown file doesn't exist, your watcher would then restart the server. Your watcher would only stop running if the .staydown file exists and then the server is stopped, or the Windows Service itself is stopped.
When your app starts up, be sure to delete .staydown if present.
If you have node installed, you might be able to use a utility like forever in place of the watcher batch file.
You need to check the 'Enable actions for stops with errors' on the service, or run 'sc failureflag "My Service" 1'
More info here: https://blog.stephencleary.com/2020/06/servicebase-gotcha-recovery-actions.html
(this is a very strange behaviour on Windows part I think, honouring exit codes should be default!)

connection refused by server error when codenameone project is copied to another machine

I have a very strange problem:
I have created a project in Intellij using the Codename One plugin.
In this project I access a Google Sheet using Oauth2 authentication
following these directions from the Codename One site.
https://www.codenameone.com/google-login.html
My code to do this works fine on my computer (Windows 10).
If I copy that code to another computer (Windows 10 or OS X) and try to access the Google Sheet, I get a "Connection refused by server" error.
Specifically, I get the error after I click on the "Allow" button in
the Google Login dialog box.
I have tried this on several computers.
I receive the error no matter what network/ISP I am using when I try to access the Google Sheet.
The stack trace relating to the error looks like this:
java.lang.Throwable: Connection refused by server
at javafx.scene.web.WebEngine$LoadWorker.describeError(WebEngine.java:1461)
at javafx.scene.web.WebEngine$LoadWorker.dispatchLoadEvent(WebEngine.java:1400)
at javafx.scene.web.WebEngine$LoadWorker.access$1200(WebEngine.java:1278)
at javafx.scene.web.WebEngine$PageLoadListener.dispatchLoadEvent(WebEngine.java:1265)
at com.sun.webkit.WebPage.fireLoadEvent(WebPage.java:2443)
at com.sun.webkit.WebPage.fwkFireLoadEvent(WebPage.java:2287)
at com.sun.webkit.network.URLLoader.twkDidFail(Native Method)
at com.sun.webkit.network.URLLoader.notifyDidFail(URLLoader.java:883)
at com.sun.webkit.network.URLLoader.lambda$didFail$102(URLLoader.java:866)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Process finished with exit code 0
The code that is being executed when the error is generated is:
public void oauth2GoogleLogin()
{
String clientId = "xxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";
String redirectURI = "http://localhost:8080";
String clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxx";
Login gc = GoogleConnect.getInstance();
gc.setClientId(clientId);
gc.setRedirectURI(redirectURI);
gc.setClientSecret(clientSecret);
gc.setScope("https://www.googleapis.com/auth/spreadsheets");
gc.setCallback(new LoginCallback() {
#Override
public void loginFailed(String errorMessage) {
super.loginFailed(errorMessage);
}
#Override
public void loginSuccessful() {
super.loginSuccessful();
System.out.println("Logged in.");
token = gc.getAccessToken().getToken();
//saveData();
}
});
if(!gc.isUserLoggedIn()){
gc.doLogin();
}else{
....some code to do stuff...
}
}
As I have said, this code works fine on the computer where I wrote it, but if I transfer the Intellij/Codename One project to another computer, it no longer works.
It seems to me that the problem is probably in the callback, and that the server that is refusing the connection is probably my own computer being accessed via the http://localhost:8080. But I'm not sure. Can anyone enlighten me?
If both machines no longer work that makes more sense that a regression in newer versions of JavaFX's web browser broke the Google OAuth2 process.
Unfortunately, that's a huge problem. We can't fix JavaFX and if they push out a broken update we are stuck.
A workaround might be to try an older version of the VM e.g. 1.8.67 or something.

Getting exception details from failing ASP.NET Core Configure() method in Azure

I'm hosting an ASP.NET Core app in a Windows Azure Web Site. I'm wondering how to get details of an exception occuring in the Startup.Configure() method? All I see is An error occurred while starting the application..
One thing that DOES work is adding an app setting of ASPNETCORE_ENVIRONMENT="Development".
Then I get System.Exception... at X.Startup.Configure() as expected.
But this is not a feasible solution. Azure is my Staging environment, and I'm already using the environment concept to substitute my connection strings (as suggested in almost every ASP.NET Core documentation I have ever read).
Things I have tried without any effect:
Adding app.UseDeveloperExceptionPage() (not surrounded by any if statement).
Adding <customErrors mode="Off"/> to Web.config, as suggested here https://stackoverflow.com/a/29539669/268091
Adding ASPNET_DETAILED_ERRORS="true" to Web.config, as suggested here https://stackoverflow.com/a/32094245/268091
Enabling Detailed error messages in Azure portal / Diagnostics logs
Adding a try-catch, writing a manual response, as suggested here https://stackoverflow.com/a/29524042/268091
Deleting everything and redeploying.
Is there really no other way to achieve this, than hijacking the environment concept altogether?
I don't know if this would work for you, but we've decided to report these using Application Insights.
public void Configuration(IAppBuilder app)
{
var ai = new Microsoft.ApplicationInsights.TelemetryClient();
ai.TrackEvent("Application Starts");
try
{
//Amazing code here
}
catch ( Exception ex )
{
ex = new Exception("Application start up failed.", ex);
ai.TrackException(ex);
throw;
}
}

Recovering from a CommunicationObjectFaultedException in WCF

I have a client app that tries every 10 seconds to send a message over a WCF web service. This client app will be on a computer on board a ship, which we know will have spotty internet connectivity. I would like for the app to try to send data via the service, and if it can't, to queue up the messages until it can send them through the service.
In order to test this setup, I start the client app and the web service (both on my local machine), and everything works fine. I try to simulate the bad internet connection by killing the web service and restarting it. As soon as I kill the service, I start getting CommunicationObjectFaultedExceptions--which is expected. But after I restart the service, I continue to get those exceptions.
I'm pretty sure that there's something I'm not understanding about the web service paradigm, but I don't know what that is. Can anyone offer advice on whether or not this setup is feasible, and if so, how to resolve this issue (i.e. re-establish the communications channel with the web service)?
Thanks!
Klay
Client service proxies cannot be reused once they have faulted. You must dispose of the old one and recreate a new one.
You must also make sure you close the client service proxy properly. It is possible for a WCF service proxy to throw an exception on close, and if this happens the connection is not closed, so you must abort. Use the "try{Close}/catch{Abort}" pattern. Also bear in mind that the dispose method calls close (and hence can throw an exception from the dispose), so you can't just use a using like with normal disposable classes.
For example:
try
{
if (yourServiceProxy != null)
{
if (yourServiceProxy.State != CommunicationState.Faulted)
{
yourServiceProxy.Close();
}
else
{
yourServiceProxy.Abort();
}
}
}
catch (CommunicationException)
{
// Communication exceptions are normal when
// closing the connection.
yourServiceProxy.Abort();
}
catch (TimeoutException)
{
// Timeout exceptions are normal when closing
// the connection.
yourServiceProxy.Abort();
}
catch (Exception)
{
// Any other exception and you should
// abort the connection and rethrow to
// allow the exception to bubble upwards.
yourServiceProxy.Abort();
throw;
}
finally
{
// This is just to stop you from trying to
// close it again (with the null check at the start).
// This may not be necessary depending on
// your architecture.
yourServiceProxy = null;
}
There was a blog article about this, but it now appears to be offline. A archived version is available on the Wayback Machine.