I have WPF desktop application, witch contains mail link. If you click on the link, the default mail client opens. But if the machine does not have a configured e-mail client, the program crashes with a critical exception
System.NullReferenceException: The object reference does not point to an instance of the object.
at Nvx.ReDoc.DesktopUi.View.Tray.Sections.About.AboutWindow.OnRequestNavigate(Object sender, RequestNavigateEventArgs e)
<Other:ReDocHyperlinkLite NavigateUri="mailto:mail#mail.com?subject=sampleText" RequestNavigate="OnRequestNavigate">
<Run Text="mail#mail.com"/></Other:ReDocHyperlinkLite>
OnRequestNavigate implementation is
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
How to check if there is an installed mail client on the computer, and catch an exception?
You can check whether an application is registered to handle the mailto URI scheme (and additionally check if the given application really exists):
private bool IsSchemeRegistered(string scheme)
{
using (var schemeKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(scheme))
{
if (schemeKey == null)
return false;
if (schemeKey.GetValue("") == null || !schemeKey.GetValue("").ToString().StartsWith("URL:"))
return false;
using (var shellKey = schemeKey.OpenSubKey("shell"))
{
if (shellKey == null)
return false;
using (var openKey = shellKey.OpenSubKey("open"))
{
if (openKey == null)
return false;
using (var commandKey = openKey.OpenSubKey("command"))
{
if (commandKey == null)
return false;
var command = commandKey.GetValue("") as string;
if (string.IsNullOrEmpty(command) || !File.Exists(command.Split(new[] { '"' }, StringSplitOptions.RemoveEmptyEntries).First()))
return false;
}
}
}
}
return true;
}
This method be called like this:
if ( !IsSchemeRegistered("mailto") )
{
MessageBox.Show("No mail client installed/configured");
}
else
{
//...
}
Related
Im trying to read receiving email from gmail and I did it.
If emails receive one by one it works perfectly.But if emails receive three or four at the same time.I miss at least two of them.
I hope describe my issue properly.
Here is my code for reading;
private void StartReceiving()
{
Task.Run(() =>
{
using (ImapClient client = new ImapClient("imap.gmail.com", 993, txtEmail.Text, txtSifre.Text, AuthMethod.Login, true))
{
if (client.Supports("IDLE") == false)
{
MessageBox.Show("server crash");
return;
}
client.NewMessage += new EventHandler<IdleMessageEventArgs>(OnNewMessage);
while (true) ;
}
});
}
static void OnNewMessage(object sender,IdleMessageEventArgs e)
{
//MessageBox.Show("mesaj geldi");
MailMessage m = e.Client.GetMessage(e.MessageUID, FetchOptions.Normal);
f.Invoke((MethodInvoker)delegate
{
f.txtGelen.AppendText("Body: " + m.Body + "\n");
});
}
What should I do ? Im kinda newbie at this,i have to read at least 4 emails at same time.
I never worked with gmail, but I had a similar problem when I was reading a TCP/IP log file, and it kept sending messages while I was processing.
The way I resolved it was to use a LIST of strings, and then process it in a background worker. Changing a string in place could be an issue in a race situation.
This is cut and pasted out of my code, and modified without checking my syntax, but it goes something like this:
private System.ComponentModel.BackgroundWorker backgroundWorkerReadMail;
private List<string> messagesToBeRead = null;
/****************************************************************
* readPassedMessage(string str)
* Puts message in queue, and calls background worker
****************************************************************/
private void readPassedMessage(string str)
{
string stringToRead = str;
if (messagesToBeRead == null) messagesToBeRead = new List<string>();
messagesToBeRead.Add(stringToRead);
if (backgroundWorkerReadMail != null && backgroundWorkerReadMail.IsBusy == false)
{
backgroundWorkerReadMail.RunWorkerAsync();
}
else if (backgroundWorkerReadMail == null)
{
// need to create it
}
}
private void backgroundWorkerReadMail_DoWork(object passedObj, DoWorkEventArgs e)
{
if (messagesToBeRead == null || messagesToBeRead.Count == 0) return;
if (backgroundWorkerReadMail.CancellationPending)
{
messagesToBeRead.Clear();
e.Cancel = true;
}
else
{
bool messagesLeftToRead = true;
while (messagesLeftToRead)
{
string curString = messagesToBeRead[0];
// < ADD CODE HERE TO DO WHATEVER YOU WANT WITH YOUR MESSAGE > //
messagesToBeRead.RemoveAt(0);
if (messagesToBeRead.Count == 0 || backgroundWorkerVoiceAssist.CancellationPending)
break;
} // while (messagesLeftToRead) end brace
}
}
I am getting this error dialog even after logging in successfully using Microsoft login.
Here is the code to authenticate :
#region IMicrosoftLogin implementation
public async System.Threading.Tasks.Task<Xamarin.Auth.Account> LoginAsync()
{
window = UIApplication.SharedApplication.KeyWindow;
viewController = window.RootViewController;
var auth = new OAuth2Authenticator(
"key_here",//for non- prod
//for production
"openid email https://graph.microsoft.com/user.read",
new Uri("https://login.microsoftonline.com/common/oauth2/V2.0/authorize"),
new Uri("https://myapp_redirect_url"),// for non- prod
null
)
{
AllowCancel = true
};
auth.Completed += Microsoft_Auth_Completed;
var tcs1 = new TaskCompletionSource<AuthenticatorCompletedEventArgs>();
d1 = (o, e) =>
{
try
{
if (e.IsAuthenticated)
{
viewController.DismissViewController(true, null);
tcs1.TrySetResult(e);
}
else
{
viewController.DismissViewController(true, null);
}
}
catch (Exception)
{
tcs1.TrySetResult(new AuthenticatorCompletedEventArgs(null));
}
};
try
{
auth.Completed += d1;
if (viewController == null)
{
while (viewController.PresentedViewController != null)
viewController = viewController.PresentedViewController;
viewController.PresentViewController(auth.GetUI(), true, null);
}
else
{
viewController.PresentViewController(auth.GetUI(), true, null);
UserDialogs.Instance.HideLoading();
}
var result = await tcs1.Task;
return result.Account;
}
catch (Exception)
{
return null;
}
finally
{
auth.Completed -= d1;
}
//auth.Error += (object sender, AuthenticatorErrorEventArgs eventArgs) => {
// auth.IsEnabled = false;
//};
}
private void Microsoft_Auth_Completed(object sender, AuthenticatorCompletedEventArgs e)
{ /// Break point here is not getting triggered.
var authenticator = sender as OAuth1Authenticator;
if (authenticator != null)
{
authenticator.Completed -= Microsoft_Auth_Completed;
}
if (e.IsAuthenticated)
{
var a = e.Account;
}
else
{
}
}
Login async called on button click like this :
btnSignIn.Clicked += async (object sender, EventArgs e) =>
{
if (networkConnection != null && networkConnection.CheckNetworkConnection())
{
UserDialogs.Instance.ShowLoading("Loading", null);
var loginresult = await MicrosoftLogin.LoginAsync();
.....
MicrosoftLogin.cs
namespace projectnamescpace
{
public interface IMicrosoftLogin
{
Task<Account> LoginAsync();
}
}
Please help me.
I have already saw following link solutions and they aren't working for me.
https://forums.xamarin.com/discussion/5866/xamarin-auth-and-infinite-error-alerts
Authentication Error e.Message = OAuth Error = Permissions+error
https://forums.xamarin.com/discussion/95176/forms-oauth-error-after-authenticated-unable-to-add-window-token-android-os-binderproxy
The issue might be caused by the HostName been blocked because of Area Policy .
You could solve this by modifying the DNS (to 8.8.8.8 as an example) for your Mac as well.
Your device, Settings/Wi-Fi
Choose connected Wi-Fi pot
Press DHCP/DNS
Set to 8.8.8.8
Or you could connect phone to the VPN for your apps deployed to device to see corporate servers.
I try to sign in to Skype For Business via my application.
When I'm with UI on, I can sign in.
When I set UI Suppression, my client is stuck at the signing in the state. Neither credentials event nor SigninCallback event nor SignInDelayed event is fired.
Can you help me?
Here is my code:
public void StartUpSkype()
{
try
{
_LyncClient = LyncClient.GetClient();
if (_LyncClient == null)
{
throw new Exception("Unable to obtain client interface");
}
if (_LyncClient.InSuppressedMode == true)
{
if (_LyncClient.State == ClientState.Uninitialized)
{
Object[] _asyncState = { _LyncClient };
_LyncClient.BeginInitialize(InitializeCallback, _asyncState);
}
}
_LyncClient.SignInDelayed += _LyncClient_SignInDelayed;
_LyncClient.StateChanged += _Client_ClientStateChanged;
_LyncClient.CredentialRequested += _LyncClient_CredentialRequested;
}
catch (NotStartedByUserException h)
{
DisplayErrorMessage("Lync is not running");
}
catch (Exception ex)
{
DisplayErrorMessage("General Exception");
}
}
void _Client_ClientStateChanged(Object source, ClientStateChangedEventArgs data)
{
if (data != null)
{
if (data.NewState == ClientState.SignedIn)
{
DisplayErrorMessage("Signed in");
UserIsSignedIn?.Invoke(_LyncClient);
}
if (data.NewState == ClientState.SignedOut)
{
string login = ConfigurationManager.AppSettings["loginSkypeClient"];
string password = ConfigurationManager.AppSettings["pwdSkypeClient"];
_LyncClient.SignInConfiguration.ForgetMe(login);
try
{
// starts the sign in process asynchronously
IAsyncResult asyncResult = _LyncClient.BeginSignIn(login, login, password, SigninCallback, _LyncClient);
// But wait for the results because the events cannot be registered within a worker thread.
asyncResult.AsyncWaitHandle.WaitOne();
}
catch (Exception e)
{
throw e;
}
}
}
}
void _LyncClient_CredentialRequested(object sender, CredentialRequestedEventArgs e)
{
string login = ConfigurationManager.AppSettings["loginSkypeClient"];
string password = ConfigurationManager.AppSettings["pwdSkypeClient"];
if (e.Type == CredentialRequestedType.SignIn)
{
e.Submit(login, password, false);
}
}
private void SigninCallback(IAsyncResult ar)
{
if (ar.IsCompleted == true)
{
try
{
((LyncClient)ar.AsyncState).EndSignIn(ar);
}
catch (RequestCanceledException re)
{
throw re;
}
}
}
private void InitializeCallback(IAsyncResult ar)
{
if (ar.IsCompleted == true)
{
object[] asyncState = (object[])ar.AsyncState;
((LyncClient)asyncState[0]).EndInitialize(ar);
//_ThisInitializedLync is part of application state and is
//a class Boolean field that is set to true if this process
//initialized Lync.
_ThisInitializedLync = true;
}
}
The login + password are correct because I can sign in with them when the UI is on.
The problem only happens when the UI is suppressed.
I've tried many things, I am desperate right now.
Please check the version of SkypeForBusiness. If it is 2016 then it is happening due to ModernAuthentication enabled on both client and tenant office365.
In case ModernAuthentication is enabled, the LyncSDK is not capable enough to handle ModernAuth as SDK doesn't support and Microsoft has no plans to upgrade the SDK.
Every time I try to Response.Redirect("tothepageIwant.aspx"); tt takes me to ~/Account/Logon.aspx
Why is this happening? I'm using Forms Authentication, with a custom method of authenticating, using PrincipalContext.ValidateCredentials.
If the credentials are valid, I want to Redirect.Response to the page I'm allowing the user to reach.
Instead, anytime I successfully login, it redirects me to the old Account/Logon.aspx.
Any suggestions? Anything I need to look out for when using Forms Authentication with custom method of authenticating?
EDIT (add code):
protected void Submit1_Click(object sender, EventArgs e)
{
var auth = new AuthClass();
var result = auth.ValidateCredentials(UserEmail.Text, UserPass.Text);
if (result)
{
Response.Redirect("~/Members/RollReport.aspx");
}
else
{
Msg.Text = "Not authorized to access this page.";
}
}
public bool ValidateCredentials(string user, string pass)
{
using (var pc = new PrincipalContext(ContextType.Domain, "Domain.name"))
{
// validate the credentials
try
{
var isValid = pc.ValidateCredentials(user, pass);
if (isValid)
{
var isAuth = AuthorizeUser(user);
return isAuth;
}
else
{
return false;
}
}
catch (ActiveDirectoryOperationException)
{
throw;
}
}
}
private bool AuthorizeUser(string user)
{
var isAuth = false;
var authList = (List<string>)HttpContext.Current.Cache["AuthList"];
foreach (var id in authList)
{
if (id == user)
{
isAuth = true;
}
}
return isAuth;
}
var userName = Request.ServerVariables["LOGON_USER"];//or some other method of capturing the value from the username
var pc = new PrincipalContext(ContextType.Domain);
var userFind = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, userName);
if(userFind != null)
{
HttpContext.Current.Session["username"] = userFind.DisplayName;
}
If you want to check and redirect.. store the value inside a session variable inside the Global.asax
protected void Session_Start(object sender, EventArgs e)
{
//declare and Initialize your LogIn Session variable
HttpContext.Current.Session["username"] = string.Empty;
}
On the Page_Load of your login page assign the value if the code above succeeds
if(HttpContext.Current.Session["username"] == null)
{
//Force them to redirect to the login page
}
else
{
Response.Redirect("tothepageIwant.aspx");
}
if you want to do the same thing inside a using(){} statement
string fullName = null;
using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
{
using (UserPrincipal user = UserPrincipal.FindByIdentity(context,"yourusernamehere")) //User.Identity.Name
{
if (user != null)
{
fullName = user.DisplayName;
}
}
}
use the debugger and inspect all of the user. Properties ok
On my windows phone 7 Mango app I use the Microsoft.Live and Microsoft.Live.Controls references to download and upload on Skydrive. Logging in and uploading files works fine but whenever I call the "client.GetAsync("/me/skydrive/files");" on the LiveConnectClient the Callback result is empty just containing the error: "An error occurred while retrieving the resource. Try again later."
I try to retrieve the list of files with this method.
This error suddenly occured without any change on the source code of the app (I think..) which worked perfectly fine for quite a while until recently. At least I didn't change the code section for up- or downloading.
I tried out the "two-step verification" of Skydrive, still the same: can log in but not download.
Also updating the Live refercences to 5.5 didn't change anything.
Here is the code I use. The error occurs in the "getDir_Callback" in the "e" variable.
Scopes (wl.skydrive wl.skydrive_update) and clientId are specified in the SignInButton which triggers "btnSignin_SessionChanged".
private void btnSignin_SessionChanged(object sender, LiveConnectSessionChangedEventArgs e)
{
if (e.Status == LiveConnectSessionStatus.Connected)
{
connected = true;
processing = true;
client = new LiveConnectClient(e.Session);
client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(UploadCompleted);
client.DownloadCompleted += new EventHandler<LiveDownloadCompletedEventArgs>(OnDownloadCompleted);
client.DownloadProgressChanged += new EventHandler<LiveDownloadProgressChangedEventArgs>(client_DownloadProgressChanged);
infoTextBlock.Text = "Signed in. Retrieving file IDs...";
client.GetAsync("me");
}
else
{
connected = false;
infoTextBlock.Text = "Not signed into Skydrive.";
client = null;
}
}
private void OnGetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
if (e.Error == null)
{
client.GetCompleted -= new EventHandler<LiveOperationCompletedEventArgs>(OnGetCompleted);
client.GetCompleted += getDir_Callback;
client.GetAsync("/me/skydrive/files");
client_id = (string)e.Result["id"];
if (e.Result.ContainsKey("first_name") && e.Result.ContainsKey("last_name"))
{
if (e.Result["first_name"] != null && e.Result["last_name"] != null)
{
infoTextBlock.Text = "Hello, " +
e.Result["first_name"].ToString() + " " +
e.Result["last_name"].ToString() + "!";
}
}
else
{
infoTextBlock.Text = "Hello, signed-in user!";
}
}
else
{
infoTextBlock.Text = "Error calling API: " +
e.Error.ToString();
}
processing = false;
}
public void getDir_Callback(object s, LiveOperationCompletedEventArgs e)
{
client.GetCompleted -= getDir_Callback;
//filling Dictionary with IDs of every file on SkyDrive
if (e.Result != null)
ParseDir(e);
if (!String.IsNullOrEmpty(e.Error.Message))
infoTextBlock.Text = e.Error.Message;
else
infoTextBlock.Text = "File-IDs loaded";
}
Yo shall use client.GetAsync("me/SkyDrive/files", null) in place of client.GetAsync("me");
This is my code and it works fine.
private void btnSignIn_SessionChanged(object sender, Microsoft.Live.Controls.LiveConnectSessionChangedEventArgs e)
{
try
{
if (e.Session != null && e.Status == LiveConnectSessionStatus.Connected)
{
client = new LiveConnectClient(e.Session);
client.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(client_GetCompleted);
client.UploadCompleted += new EventHandler<LiveOperationCompletedEventArgs>(client_UploadCompleted);
client.GetAsync("me/SkyDrive/files", null);
client.DownloadAsync("me/SkyDrive", null);
canUpload = true;
ls = e.Session;
}
else
{
if (client != null)
{
MessageBox.Show("Signed out successfully!");
client.GetCompleted -= client_GetCompleted;
client.UploadCompleted -= client_UploadCompleted;
canUpload = false;
}
else
{
canUpload = false;
}
client = null;
canUpload = false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
void client_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
try
{
List<System.Object> listItems = new List<object>();
if (e.Result != null)
{
listItems = e.Result["data"] as List<object>;
for (int x = 0; x < listItems.Count(); x++)
{
Dictionary<string, object> file1 = listItems[x] as Dictionary<string, object>;
string fileName = file1["name"].ToString();
if (fileName == lstmeasu[0].Title)
{
folderID = file1["id"].ToString();
folderAlredyPresent = true;
}
}
}
}
catch (Exception)
{
MessageBox.Show("An error occured in getting skydrive folders, please try again later.");
}
}
It miraculously works again without me changing any code. It seems to be resolved on the other end. I have no clue what was wrong.