I am getting the following exception when I call CompositionCapabilities.GetForCurrentView.
System.UnauthorizedAccessException: 'Access is denied. (Exception from
HRESULT: 0x80070005 (E_ACCESSDENIED))'
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
// Exception happens here.
var capabilities = CompositionCapabilities.GetForCurrentView();
}
The weird thing is the code compiles OK so I assume the API is available. Do I need to declare any capabilities in Package.appxmanifest?
You don't need to declare anything. The method is simply called too early.
So instead of calling it in the constructor, call it right after the Window is created -
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 4))
{
var capabilities = CompositionCapabilities.GetForCurrentView();
var areEffectsSupported = capabilities.AreEffectsSupported();
var areEffectsFast = capabilities.AreEffectsFast();
}
base.OnWindowCreated(args);
}
Note you will want to add a check to see if that API is supported too, like in the code above.
Related
I found several topics on this already, but somehow they all managed to avoid the real problem solution/assumed the obvious.
(e.g. here, here, here, here, here)
I am checking for and creating new event log + source during installation, and specifying them to be used during operation, but still somehow "EventSourceName" events end up in Application Log.
Why is that?
Here are snippets out of my code:
Installer:
namespace Service_Name
{
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
if (!System.Diagnostics.EventLog.SourceExists("EventSourceName"))
{
System.Diagnostics.EventLog.CreateEventSource(
"EventSourceName", "EventLogName");
}
InitializeComponent();
}
private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
}
}
}
Service:
public Service_Name()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ServiceEventLog = new EventLog();
ServiceEventLog.Source = "EventSourceName"; // This is different from Service Name
ServiceEventLog.Log = "EventLogName"; // This is different from Service Name
..
ServiceEventLog.WriteEntry("Service Init");
Worker = new Thread(CodeWorker);
Worker.Start();
}
private void CodeWorker()
{
//.. operational code
while (true)
{
try
{
//.. operational code
ServiceEventLog.WriteEntry("<operational event data here>", (EventLogEntryType)4, 0);
}
catch (Exception Error)
{
ServiceEventLog.WriteEntry(string.Format("<error event data here>", (EventLogEntryType)1, 0);
throw;
}
//.. operational code
}
}
As it turns out, the code works perfectly as is, however there is important thing to remember when working with event log;
EventLog.CreateEventSource Method has an important footnote:
If a source has already been mapped to a log and you remap it to a new
log, you must restart the computer for the changes to take effect.
I had mapped the source prior, to another event log which was named the same as Service itself. Using same name as the service itself caused multiple other issues and I ended up fixing that by using another log name, but did not restart test system prior to doing tests on new code version.
But as Caius Jard pointed out below, parts of the code are redundant:
ServiceEventLog.Log = "EventLogName" does not need to be specified as Source is already registered to Log.
The documentation states "If you change the Log property after the Source property has been set, writing a log entry throws an exception.".
The sample code on MSDN just sets the Source property and then calls WriteEvent, it does not then set the Log beforehand or after setting Source
I recommend you remove the call to setting the Log property; I suspect your call to WriteEvent is crashing, and being in a try catch the call in the catch is also crashing. Perhaps it's not an ideal code structure to "try writing to this log and if it fails, try writing to this log" if it's the "writing to log" that is failing
I'm working on a UWP project and there's something funky going on with how errors are being presented to me. I don't know if it's VS2017 or how UWP is set up.
I have a piece of code that goes online and retrieves json content, sometimes the code works and sometimes it doesn't. It works when I use Expander control from UWP Community toolkit, and fails when I want to switch to GridView. When it doesn't work, it fails on GetStringAsync method of HttpClient. The strange behavior is that the exception isn't thrown in the method where the problem occurs, the code actually redirects me back without giving an error and as soon as it gets to the property that's supposed to have a value that isn't null, I get a null exception.
This is where the problem happens:
string httpContent = "";
using (HttpClient httpClient = new HttpClient())
{
try
{
httpContent = await httpClient.GetStringAsync(uri);
}
catch (Exception e)
{
// TODO: handle errors
var x = "";
}
}
This piece of code is called from within the view model. It starts with a constructor and RefreshServerKanesWrathDataAsync is the method where json is parsed.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
cnconline.RefreshServerKanesWrathDataAsync();
}
The second I get to GetStringAsync, the code just goes back to the constructor like nothing happened, however the method never completes, it just exits back to the constructor, and therefore fails to update observable collections with data. I then get a null exception.
I wanted to test this with VS2015, but I updated some controls that are apparently only supported withing VS2017, so I can't run the code in other versions.
I also ran into an issue with the code prior to this problem, where I tried to access files in a directory without using a token. The behavior was exactly the same, the code wasn't telling me that I didn't have access to the directory I wanted to read, it was just throwing me out of the method back into the location that made the call to read the directory. Just like with the current problem, I would then run into a null exception, which wasn't where the main problem was.
I added Template10 and UWP community toolkit to the project, if that matters.
You shouldn't call an async method from a constructor unless you're willing to provide a callback.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task<string>
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task<string> task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
var result = task.Result;
}
}
Here's a sample where RefreshServerKanesWrathDataAsync() returns just Task (not Task<result>)
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
}
}
On a side note, you may also need to have Visual Studio 2017 break when any exception is thrown. In VS2017, go to Debug->Windows->Exception Settings and make sure Common Language Runtime Exceptions has a check. If it has a filled box, click the box until it turns into a checkmark.
Also..., you can tap into an event raised when any task has an unobserved exception. You can do so in the constructor of App.xaml.cs
public App()
{
TaskScheduler.UnobservedTaskException += OnUnobservedException;
}
private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
{
// Put break point here.
var ex = e.Exception;
// This will keep your app alive, but only do it if it's safe to continue.
e.SetObserved();
}
Related to this question, I would like to force CLR to let my .NET 4.5.2 app catch Corrupted State Exceptions, for the sole purpose of logging them and then terminating the application. What's the correct way to do this, if I have catch (Exception ex) at several places around the app?
So, after I specify the <legacyCorruptedStateExceptionsPolicy> attribute, if I understood correctly, all the catch (Exception ex) handlers will catch exceptions like AccessViolationException and happily continue.
Yeah, I know catch (Exception ex) is a Bad Idea™, but if CLR would at least put the correct stack trace into the Event Log, I would be more than happy to explain to the customer that his server app failing fast at 1AM and being offline for the night is a good thing. But unfortunately, CLR logs an unrelated exception into the Event Log and then closes the process so that I cannot find out what actually happened.
The question is, how to make this happen, process wide:
if the exception thrown is a Corrupted State Exception:
- write the message to the log file
- end the process
(Update)
In other words, this would probably work for most exceptions in a simple app:
[HandleProcessCorruptedStateExceptions]
[SecurityCritical]
static void Main() // main entry point
{
try
{
}
catch (Exception ex)
{
// this will catch CSEs
}
}
But, it won't work for:
Unhandled app domain exceptions (i.e. thrown on non-foreground threads)
Windows Service apps (which don't have an actual Main entry point)
So it seems like <legacyCorruptedStateExceptionsPolicy> is the only way to make this work, in which case I don't know how to fail after logging the CSE?
Instead of using <legacyCorruptedStateExceptionsPolicy> it would be better to use [HandleProcessCorruptedStateExceptions] (and [SecurityCritical]) as stated here:
https://msdn.microsoft.com/en-us/magazine/dd419661.aspx
Following that, your Main method should look something like this:
[HandleProcessCorruptedStateExceptions, SecurityCritical]
static void Main(string[] args)
{
try
{
...
}
catch (Exception ex)
{
// Log the CSE.
}
}
But be aware that this doesn't catch the more serious exceptions like StackOverflowException and ExecutionEngineException.
Also finally of involved try blocks will not be executed:
https://csharp.2000things.com/2013/08/30/920-a-finally-block-is-not-executed-when-a-corrupted-state-exception-occurs/
For other unhandled appdomain exceptions you can use :
AppDomain.CurrentDomain.UnhandledException
Application.Current.DispatcherUnhandledException
TaskScheduler.UnobservedTaskException
(Please do a search for the details when a specific handler is appropriate for your situation. TaskScheduler.UnobservedTaskException for example is a bit tricky.)
If you don't have access to the Main method, you can also mark your AppDomain exception handler to catch the CSE:
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
...
[HandleProcessCorruptedStateExceptions, SecurityCritical]
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// AccessViolationExceptions will get caught here but you cannot stop
// the termination of the process if e.IsTerminating is true.
}
The last line of defense could be an unmanaged UnhandledExceptionFilter like this:
[DllImport("kernel32"), SuppressUnmanagedCodeSecurity]
private static extern int SetUnhandledExceptionFilter(Callback cb);
// This has to be an own non generic delegate because generic delegates cannot be marshalled to unmanaged code.
private delegate uint Callback(IntPtr ptrToExceptionInfo);
And then somewhere at the beginning of your process:
SetUnhandledExceptionFilter(ptrToExceptionInfo =>
{
var errorCode = "0x" + Marshal.GetExceptionCode().ToString("x2");
...
return 1;
});
You can find more information about the possible return codes here:
https://msdn.microsoft.com/en-us/library/ms680634(VS.85).aspx
A "specialty" of the UnhandledExceptionFilter is that it isn't called if a debugger is attached. (At least not in my case of having a WPF app.) So be aware of that.
If you set all the appropriate ExceptionHandlers from above, you should be logging all exceptions that can be logged. For the more serious exceptions (like StackOverflowException and ExecutionEngineException) you have to find another way because the whole process is unusable after they happened. A possible way could perhaps be another process that watches the main process and logs any fatal errors.
Additional hints:
In the AppDomain.CurrentDomain.UnhandledException you can safely cast the e.ExceptionObject to Exception without having to worry - at least if you don't have any IL code that throws other objects than Exception: Why is UnhandledExceptionEventArgs.ExceptionObject an object and not an Exception?
If you want to suppress the Windows Error Reporting dialog, you can take a look here: How to terminate a program when it crashes? (which should just fail a unit test instead of getting stuck forever)
If you have a WPF application with multiple dispatchers you can also use a Dispatcher.UnhandledException for the other dispatchers.
Thanks to #haindl for pointing out that you can also decorate handler methods with the [HandleProcessCorruptedStateExceptions]1 attribute, so I made a little test app just to confirm if things really work as they are supposed to.
1 Note: Most answers state that I should also include the [SecurityCritical] attribute, although in the tests below omitting it didn't change the behavior (the [HandleProcessCorruptedStateExceptions] alone seemed to work just fine). However, I will leave both attributes below since I am presuming all these folks knew what they were saying. That's a school example of "Copied from StackOverflow" pattern in action.
The idea is, obviously, to remove the <legacyCorruptedStateExceptionsPolicy> setting from app.config, i.e. only allow our outermost (entry-level) handler(s) to catch the exception, log it, and then fail. Adding the setting will allow your app to continue, if you catch the exception in some inner handler, and this is not what you want: the idea is just to get the accurate exception info and then die miserably.
I used the following method to throw the exception:
static void DoSomeAccessViolation()
{
// if you have any questions about why this throws,
// the answer is "42", of course
var ptr = new IntPtr(42);
Marshal.StructureToPtr(42, ptr, true);
}
1. Catching exceptions from Main:
[SecurityCritical]
[HandleProcessCorruptedStateExceptions]
static void Main(string[] args)
{
try
{
DoSomeAccessViolation();
}
catch (Exception ex)
{
// this will catch all CSEs in the main thread
Log(ex);
}
}
2. Catching all exceptions, including background threads/tasks:
// no need to add attributes here
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
// throw on a background thread
var t = new Task(DoSomeAccessViolation);
t.Start();
t.Wait();
}
// but it's important that this method is marked
[SecurityCritical]
[HandleProcessCorruptedStateExceptions]
private static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// this will catch all unhandled exceptions, including CSEs
Log(e.ExceptionObject as Exception);
}
I would recommend using just the latter approach, and removing the [HandleProcessCorruptedStateExceptions] from all other places to make sure the exception doesn't get caught at the wrong place. I.e. if you have a try/catch block somewhere and an AccessViolationException is thrown, you want CLR to skip the catch block and propagate to the UnhandledException before ending the app.
Is party over? not so fast
Microsoft: "Use application domains to isolate tasks that might bring down a process."
The program below will protect your main application/thread from unrecoverable failures without risks associated with use of HandleProcessCorruptedStateExceptions and <legacyCorruptedStateExceptionsPolicy>
public class BoundaryLessExecHelper : MarshalByRefObject
{
public void DoSomething(MethodParams parms, Action action)
{
if (action != null)
action();
parms.BeenThere = true; // example of return value
}
}
public struct MethodParams
{
public bool BeenThere { get; set; }
}
class Program
{
static void InvokeCse()
{
IntPtr ptr = new IntPtr(123);
System.Runtime.InteropServices.Marshal.StructureToPtr(123, ptr, true);
}
// This is a plain code that will prove that CSE is thrown and not handled
// this method is not a solution. Solution is below
private static void ExecInThisDomain()
{
try
{
var o = new BoundaryLessExecHelper();
var p = new MethodParams() { BeenThere = false };
Console.WriteLine("Before call");
o.DoSomething(p, CausesAccessViolation);
Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); //never stops here
}
catch (Exception exc)
{
Console.WriteLine($"CSE: {exc.ToString()}");
}
Console.ReadLine();
}
// This is a solution for CSE not to break your app.
private static void ExecInAnotherDomain()
{
AppDomain dom = null;
try
{
dom = AppDomain.CreateDomain("newDomain");
var p = new MethodParams() { BeenThere = false };
var o = (BoundaryLessExecHelper)dom.CreateInstanceAndUnwrap(typeof(BoundaryLessExecHelper).Assembly.FullName, typeof(BoundaryLessExecHelper).FullName);
Console.WriteLine("Before call");
o.DoSomething(p, CausesAccessViolation);
Console.WriteLine("After call. param been there? : " + p.BeenThere.ToString()); // never gets to here
}
catch (Exception exc)
{
Console.WriteLine($"CSE: {exc.ToString()}");
}
finally
{
AppDomain.Unload(dom);
}
Console.ReadLine();
}
static void Main(string[] args)
{
ExecInAnotherDomain(); // this will not break app
ExecInThisDomain(); // this will
}
}
I am developing a WP8 application. I created a web service on out-systems and then I am calling those web service methods in my app:
ServiceReference1.WebServiceClient ws = new WebServiceClient();
try
{
ws.FetchInboxAsync(EmailId);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
Now if the server is down, I expect the control to go into the catch block but it does not and I get the following exception:
An exception of type 'System.ServiceModel.CommunicationException'
occurred in System.ServiceModel.ni.dll but was not handled in user
code.
I do realize that the web service call method is asynchronous, so its exception would not be caught in try catch. On forums, people suggest using await keyword. But when I write
await ws.FetchInboxAsync(EmailId);
I get an error : Cannot await void.
I tried something mentioned in answers here, but still I get the same exception
You can subscribe to FetchInboxCompleted event:
ServiceReference1.WebServiceClient ws = new WebServiceClient();
ws.FetchInboxCompleted += new EventHandler<ServiceReference1.FetchInboxCompletedEventArgs>(c_FetchInboxCompleted);
ws.FetchInboxAsync(EmailId);
And in event handler, check the result:
static void c_FetchInboxCompleted(object sender, serviceReference1.FetchInboxCompletedEventArgs e)
{
// check e.Error which contains the exception, if any
}
If the auto-generated WCF client proxy supports it, you should be able to await a method ending with TaskAsync:
await ws.FetchInboxTaskAsync(EmailId);
If the auto-generated WCF client proxy doesn't define this method, then you can define it yourself as described on MSDN:
public static Task FetchInboxTaskAsync(this ServiceReference1.WebServiceClient client, string emailId)
{
return Task.Factory.FromAsync(client.BeginFetchInbox, client.EndFetchInbox, emailId, null);
}
I am developing Windows Phone 7 Silverlight Application. I want to do Application Level error handling instead of writing try...catch... in all methods. I need to extract Method Name, Class Name and Line Number where the actual error occurred. Below is the demo code. In Application_UnhandledException event, I am expecting Method = "GenerateError" and Class = "ExceptionTesting". Also, I want to get LineNumber where the actual error occurred (this is not shown in code).
Code to generate Error:
public partial class ExceptionTesting : PhoneApplicationPage
{
// Generate Error to Test Exception Handling
private void GenerateError()
{
Int16 i = Convert.ToInt16("test");
}
}
Code that Handles Application Level Exception:
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
StackTrace st = new StackTrace();
var query = st.GetFrames() // get the frames
.Select(frame => new
{
Method = frame.GetMethod(),
Class = frame.GetMethod().DeclaringType
});
foreach (var q in query)
{
if (q.Method.Name.Contains("GenerateError"))
{
MessageBox.Show("Class: " + q.Class + ", Method: " + q.Method);
}
}
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
The Application_UnhandledException method is not called from your method where the exception happens, so new StrackTrace() will not be meaningful, as you have discovered.
To get the stack trace for the place where the exception occurred, use e.Exception.StackTrace.
Note that the real exception may be wrapped inside another exception, possibly several layers deep (e.Exception.InnerException).
You could also use BugSense to get this information.
Disclaimer: I am one of the cofounders