UserNotificationListener: The remote procedure call failed - c#

I could not figure out why I get error on second line. On some PC everything works on other not.
I use WPF with Microsoft.Windows.SDK.Contracts 10.0.22621.755 installed.
UserNotificationListener notifiacationListener = UserNotificationListener.Current;
notifiacationListener.NotificationChanged += Listener_NotificationChanged;
System.Exception: 'The remote procedure call failed. (Exception from HRESULT: 0x800706BE)'
I can request notification access without any trouble, but when I try to subscribe I will get the error.
UserNotificationListener notifiacationListener = UserNotificationListener.Current;
if (notifiacationListener.GetAccessStatus() == UserNotificationListenerAccessStatus.Allowed)
{
notifiacationListener.NotificationChanged += Listener_NotificationChanged;
}
I also tried called this before notification usage.
notificationStatus = await notifiacationListener.RequestAccessAsync()

Related

C# WinForms Application exits unexpectedly with no exception, but only when the API piece is not on the same machine

I am developing an application which is to run as a WinForms thick-client, accessing both an API to be running in the cloud (Azure), and a local SQL Server DB for data.
To allow users to log in, the login screen is triggered as a Modal prompt when the application starts up with the following code in the HomeScreen form which is the 'main' page of the application:
using (Form loginScreen = new LoginForm())
{
loginScreen.ShowDialog(this);
}
Once the login screen has been passed, the user can see the home screen, if they cancel it, the application closes. Once they get to the home screen, another API call is run to retrieve data about the user from the API for display on the home screen.
All API calls execute the same code, which is below (this is very early code for a 'working prototype' and I am aware there are probably issues with it that require a refactor, at this point I'm really only interested in understanding what is causing my call to PostAsJsonAsync to fail:
public async Task<ApiResponse> sendApiRequest(RequestDetail reqDet)
{
//create a variable to track if the action was done or we need to retry after a timeout and login
bool actionDone = false;
//instantiate a variable for the ApiResponse so it can be used later outside of the scope of the actionDone loop
ApiResponse res = null;
while (actionDone == false)
{
//populate the main SessionKey of the packet from the GlobalData var (for initial dev, to be refactored out)
reqDet.SessionKey = GlobalData.SessionKey;
//populate the SessionKey in the array underneath the main object (for future use)
reqDet.strParameters["SessionKey"] = GlobalData.SessionKey;
//instantiate a new ApiRequest object to hold the main request body
ApiRequest req = new ApiRequest("ClientRequest", reqDet);
//Create HttpClient class for communication with the server
HttpClient client = new HttpClient();
//Set URL and Headers (URL will be in a config file in future
client.BaseAddress = new Uri("https://removed.the.url.for.se/api/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
//actually call the service, wait for the response, and read it out into the response object
HttpResponseMessage response = await client.PostAsJsonAsync((string)req.requestBody.ApiLocation, req);
res = await response.Content.ReadAsAsync<ApiResponse>();
//check if the response was successful or we need to show an error
if (res.responseType == "Success")
{
//set action done to TRUE so we exit the loop
actionDone = true;
}
else
{
//Use the MessageService to dispaly the error
Error err = res.responseError;
MessagesService ms = new MessagesService();
await ms.displayErrorPrompt(err);
//trigger a login screen and restart the service call if the user's session has expired
if (err.ErrorText.Equals("Session has expired, please log in again"))
{
using (Form login = new LoginForm())
{
login.ShowDialog();
} // Dispose form
}
else
{
// set ActionDone to True if it's not a login error so we don't endlessly call the service
actionDone = true;
}
}
}
//return the final result
return res;
}
When running the entire stack locally, this all works perfectly, I can login and traverse the rest of my application as normal. When running the client locally in VS and the API in Azure, the first call to the Login API succeeds (I can call it multiple times e.g. with a wrong password and it behaves as normal), however the second call to get the user's data to paint on the home screen fails.If I put a breakpoint on the PostAsJsonAsync line, I can see that the line executes once and continues as normal, but immediately after stepping over the line the second time for the user details call, the entire application exits without executing the subsequent code.
What is strange about this is that it exits with a 0x0 return code, does not throw an exception, or in any way behave abnormally other than shutting down after just that line.
I have tried manually calling the APIs on the Azure service in Postman and they all return exactly the same (correct) results I get when running it locally, so I know it is not the deployment to the App Service that is the issue.
Things I have tried to fix it after Googling, reading other SE posts and looking at comments on this question
I have tried enabling first-chance exceptions in Visual Studio for all CLR exceptions. Nothing is caught or thrown that I can see.
Here is a screenshot of my settings in case I've done something wrong
I have tried wrapping just that line in a try-catch block that catches all exceptions. It still immediately stops executing after the PostAsJsonAsync and never reaches the Catch block
Adding the following code to my Program.cs file to catch unhandled exceptions (is never run when I put a breakpoint on it and nothing is written to the console that I can see):
static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new HomeScreen());
}
static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception)args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
}
Setting a DumpFolder that is writable by all users, and a DumpType of 2 in a key named after my executable at Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\ - I've tried both keys named MyApplication and MyApplication.exe and neither results in a file being produced when the app crashes.
The Windows Event Viewer after the 'crash' (nothing from my application)
Reviewing the request/response in Fiddler - the first 'login' request and response is shown correctly, but the second is not shown at all, so it looks like it's crashing before even sending the request
I'd be extremely grateful for any suggestions you can provide, even if it is only a workaround or 'patch' to resolve the issue. It's extremely strange to me both that it exits the program with no exception and without running the subsequent code, that it only does this when the API piece is running in Azure, not when running locally, and finally that it's only when it gets to the subsequent request after the login.
Update
I have tried commenting out the line that runs the RefreshScreen() function to call the web service again and the application still exits in the same way after the login, but just without hitting my breakpoint a second time. However again only when the application is running against the Azure API and not locally. If I break at the last line of the HomeScreen constructor and keep stepping, it goes back to my Main() method and ends the application. Is there something I'm doing wrong here?
I think the PostAsJsonAsync may have been a red herring so have taken it out of the title.
public HomeScreen()
{
InitializeComponent();
if(GlobalData.SessionKey == null)
{
using (Form loginScreen = new LoginForm())
{
loginScreen.ShowDialog(this);
}
// Dispose form
}
refreshScreen();
}
public async Task refreshScreen()
{
ApiService srv = new ApiService();
ApiResponse res = await srv.sendApiRequest(new Sessions_GetUserDetailsRequest());
if (res.responseType == "Success")
{
foreach (dynamic usrItem in JsonConvert.DeserializeObject(res.responseContent))
{
lblUserName.Text = usrItem.UserGivenName + " " + usrItem.UserSurname;
lblSiteName.Text = usrItem.TenantName;
}
}
}
So after doing some research to answer the helpful comments on this question, I stumbled across the answer.
I have an event in the application that is designed to close the entire application if the user exits the login page without logging in, since otherwise it would return to the 'home screen' form in an invalid state. It contained the following code, designed to close the application if the user didn't have a token (i.e. had cancelled the page):
Because my login process is asynchronous (code above) when I was stepping through the process in VS, I was getting to the "PostAsJsonAsync" step, and it was closing the application without showing me it was running the 'on close' event. However, unknown to me when testing locally, the code had a race condition where it would jump ahead to the 'close form' bit while still awaiting the web service call, and therefore execute the following code:
private void DoOnFormClosing(object sender, FormClosingEventArgs e)
{
if(GlobalData.SessionKey == null || GlobalData.SessionExpiry <= DateTime.Now)
{
Application.Exit();
}
}
The solution was to remove this event as part of the login process, after the login had been validated, meaning this code would never be called if the user had successfully logged in.

Wpf Application Crash on Client Machine

My application is an "Offline System"
We can download appointments in that application and can use those application in offline mode, and that data can be upload when we have internet available.
But my Issue is: On client system our application crash with or without internet and i do not understand the reason. Below is the image or error message. That message is from Login screen when user try to login in offline mode
Any Suggestions please.
Thanks in advance.
This indicates some kind of network connectivity issue. The best way to find out why, is to check the inner exception as mentioned in your stacktrace:
See inner exception, if present, for more details
Assuing you have this kind of code:
var httpClient = new HttpClient();
var message = httpClient.GetAsync(url).Result;
Re-write doing something like this:
try {
var httpClient = new HttpClient();
var message = httpClient.GetAsync(url).Result;
} catch (Exception ex) {
ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}
Since it is expected to have these exceptions while offline, when you get it, you should wait and retry later on.
Alternatively, you can use the network availability change to spin up your upload function
NetworkChange.NetworkAvailabilityChanged
+= new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);

prevent application crashes when sending data over a closed websocket connection

The ASP.NET Core application uses websocket connection on the client side and Microsoft.AspNetCore.WebSockets.Server 0.1.0 (latest stable version on nuget as I know) on the server side. The simple sending code is
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
the problem is this line throws error when it is a closed connection. I would like that method to return a Boolean if process was successful. I already check if the connection is open like this:
_ws.State == WebSocketState.Open
But this does not work if user has
unplugged the network cable or disconnected his device(almost all situations except closing the browsers).
As an extra, I do not know how to simulate network connection loss for one of two clients and I suppose WebSocketState is readonly, please warn me if I am wrong and I do not think shorter pings will solve this problem.
I have two ideas:
I may use the sender code in a try catch block. (I am not comfortable with using try catch in production code)
I may set interval on the client side, and ask the server like "what is new for me". I feel bad with this because it is away from being a websocket(closer to http).
Is there any way to fix this without using try catch? I know that this is not a qualified question but a qualified problem for me. I can share full code if needed.
Update 1
after using server-side logging:
While messaging is working well in production environment, I disconnect the client by unplugging the network cable and send data to the client. I use try catch and no catch. then i get this error.
This means I cant detect lost connection by using try catch. and i think i can solve this by handling this throw.
How can I handle this error?
update2
I have noticed that "Exceptions from an Async Void Method Can’t Be Caught with Catch" and "it's possible to use await in catch" since c# 6 link however I can not catch the throw. I may try running synchronously await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk).runsynchronously(); if I cant fix in this way
update3
running synchronously does not help. using try catch does not differ. as a result question, asp.net core websocket how to ping
update4
my log file when using Microsoft.aspnetcore.websockets.server 0.1.0
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HL1940BSEV8O": An unhandled exception was thrown by the application.
System.IO.IOException: Unexpected end of stream
at Microsoft.AspNetCore.WebSockets.Protocol.CommonWebSocket.<EnsureDataAvailableOrReadAsync>d__38.MoveNext()
my log file when using Microsoft.aspnetcore.websockets 1.0.0
fail: Microsoft.AspNetCore.Server.Kestrel[13]
Connection id "0HL19H5R4CS21": An unhandled exception was thrown by the application.
System.Net.WebSockets.WebSocketException (0x80004005): The remote party closed the WebSocket connection without completing the close handshake. ---> System.IO.IOException: Error -4077 ECONNRESET connection reset by peer ---> Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4077 ECONNRESET connection reset by peer
I might be missing something, but why can't wrap the sending operation in a method that returns bool in the following manner:
private async Task<bool> DoSend()
{
bool success = true;
try
{
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
}
catch (Exception ex)
{
// Do some logging with ex
success = false;
}
return success;
}
I also suggest reading about Async All The Way, it should clear some of the confusion with async void, async Task and async Task<T>
Until C# 6.0 to capture an exceptions from async methods you should use the ExceptionDispatchInfo type. Then the code will look like this:
private async Task<bool> DoSend()
{
bool success = true;
ExceptionDispatchInfo capturedException = null;
try
{
await _ws.SendAsync(new ArraySegment<byte>(arrbr), WebSocketMessageType.Text, true, ctk);
}
catch (Exception ex)
{
capturedException = ExceptionDispatchInfo.Capture(ex);
}
if (capturedException != null)
{
await ExceptionHandler();
if (needsThrow)
{
capturedException.Throw();
}
}
success = capturedException == null;
return success;
}

System.UnauthorizedAccessException when trying to accept audio call in Lync 2013

I have a problem with my Lync client that I am designing. I am running Lync 2013 in UI Suppression mode and I am able to send/receive IM's just fine, and begin audio calls. But a problem occurs when I try to receive an audio conversation from someone else. I get a System.UnauthorizedAccessException when I try to call this line of code:
conv.Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityCallback, asyncState);
It runs perfectly fine otherwise, and the call goes through okay and I can hear and talk to the other side just fine, but my User Interface freezes and I can't control anything due to this error. Even when the other side hangs up, I have to kill the process in Task Manager.
Here is my InitiateAVStream method, based on the MSDN Join Lync conversation example:
public bool InitiateAVStream()
{
Console.WriteLine("InitiateAVStream");
if (conv.State == ConversationState.Terminated)
{
return false;
}
if (conv.Modalities[ModalityTypes.AudioVideo].CanInvoke(ModalityAction.Connect))
{
conv.Modalities[ModalityTypes.AudioVideo].ModalityStateChanged += _AVModality_ModalityStateChanged;
conv.Modalities[ModalityTypes.AudioVideo].ActionAvailabilityChanged += _AVModality_ActionAvailabilityChanged;
//Accept the notification. If Lync UI is enabled, incoming call notification is closed.
conv.Modalities[ModalityTypes.AudioVideo].Accept();
//Connect the AV modality and begin to send and received AV stream.
object[] asyncState = { conv.Modalities[ModalityTypes.AudioVideo], "CONNECT" };
try
{
conv.Modalities[ModalityTypes.AudioVideo].BeginConnect(ModalityCallback, asyncState);
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
return true;
}
return false;
}
The output message:
A first chance exception of type 'System.UnauthorizedAccessException' occurred in Microsoft.Lync.Model.dll
at Microsoft.Office.Uc.ModalityClass.Connect(ModalityConnectOptions _options, Object _modalityCallback, Object _state)
at Microsoft.Lync.Model.Conversation.Modality.BeginConnect_private(ModalityConnectOptions options, AsyncCallback modalityCallback, Object state)
at Microsoft.Lync.Model.Conversation.Modality.BeginConnect(AsyncCallback modalityCallback, Object state)
at UIPrototype.MeetingForm.InitiateAVStream() in c:\Users\morrissi\Documents\Visual Studio 2012\Projects\UIPrototype\UIPrototype\MeetingForm.cs:line 758
Any input would be greatly appreciated. And it's strange to me that it only occurs when I try accepting an incoming audio call. Everything else works fine. I have not started work on video calls yet, but I will once I get audio working.
Thanks
Edit:
Replacing BeginConnect with BeginRetrieve still throws the same error and produces the same results. Still not sure what to do.
Where are you running your application from? I had a very similar stacktrace and moving the application into "C:\Users\MyUser" resolved the problem for me.
I was able to solve the problem. Apparently when you are connecting just an audio call, the only line you need is
conv.Modalities[ModalityTypes.AudioVideo].Accept();
You do not need to call BeginConnect to connect the audio. Removing BeginConnect prevents the error from being thrown and the audio connects just fine still. BeginConnect is used to connect video.
My problem with the form not loading completely and freezing is unrelated, it appears. That is being caused because I am trying to create a new form within ConversationManager_ConversationAdded. If I try creating a new form on a button click, it loads just fine and works, but it seems to be the event that is preventing it from working properly.
I'm not good enough at this to recognize when an error is being caused by Lync or C# yet.

MSMQ Remote Private: UnsupportedFormatNameOperation after one use

I am new to MSMQ and suspect I either have my queues configured wrong or programmatically (is that a word?)causing them to get hung up.
When everything starts I can send one message and that works wonderfully. I can see (ie via mmc on that machine) the message in the remote machine queue. I then go to access it and I get my UnsupportedFormatNameOperation error. If I try to send another message I get the same error in the send method that just worked a few seconds earlier.
What is even more frustrating is that my catch is NOT picking up the exception so I was unaware and looking elsewhere (read wasting time) till I explored the queue object in the debugger.
Now if I reset the Message Service on remote I lose my message in the queue and still get the same error. If I reboot same result.
On local (dev machine) if I reset the Message Service I still get the error. If I reboot something gets recycled and I can send exactly one message again.
Further after reboot of dev machine and exploring the queue object on the first run I find that I am getting the error the FIRST time around but it still sends the message.
So I am clearly doing something wrong but clueless as to what.
Here is my send code:
private void SendLoginMessage(...bunch of parms)
{
//hardcoded path? yup!!
MessageQueue msmq = new MessageQueue(#"FormatName:DIRECT=OS:W2K8R2_SQL2K8R2\private$\best_simulator");
try
{
LoginStatusMessage LgnMsg = new LoginStatusMessage()
{
...assign parms to my
};
msmq.Send(LgnMsg);
}
catch (MessageQueueException msmqex)
{
MessageBox.Show(msmqex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
msmq.Close();
}
}
The description for UnsupportedFormatNameOperation is
The requested operation for the specified format name is not supported.
Message Queuing returns this error when the requested operation is not supported for the specified format name. Operations include trying to open a queue to receive messages by specifying a direct format name.
So I guess your problem may be at your receive code.

Categories

Resources