Get UserName in a Windows 10 C# UWP Universal Windows app - c#

I am struggling with yet another simple task in the Windows 10 UWP world.
I simply need the UserName of the current Windows user. Environment.UserName is just not a thing in UWP. And no amount of searching the web has helped so far. Hence my post here.
Anyone? Is this just not possible now?

Add "User Account Information" capability to your app in the Package.appxmanifest
Use this code to get user display name:
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
IReadOnlyList<User> users = await User.FindAllAsync();
var current = users.Where(p => p.AuthenticationStatus == UserAuthenticationStatus.LocallyAuthenticated &&
p.Type == UserType.LocalUser).FirstOrDefault();
// user may have username
var data = await current.GetPropertyAsync(KnownUserProperties.AccountName);
string displayName = (string)data;
//or may be authinticated using hotmail
if(String.IsNullOrEmpty(displayName))
{
string a = (string)await current.GetPropertyAsync(KnownUserProperties.FirstName);
string b = (string)await current.GetPropertyAsync(KnownUserProperties.LastName);
displayName = string.Format("{0} {1}", a, b);
}
text1.Text = displayName;
}

// get username
public string UserNameStr { get; set; } = WindowsIdentity.GetCurrent().Name;
This will get you the full domain\username.

As I can see, there is a User class available (UWP): https://msdn.microsoft.com/en-us/library/windows/apps/windows.system.user.aspx
Try this:
var users = await User.FindAllAsync(UserType.LocalUser);
var name = await users.FirstOrDefault().GetPropertyAsync(KnownUserProperties.AccountName);

You can also pickup the User who launched the app from the Application.OnLaunched method see here.
You still need to declare the User Information capability in you manifest though.
quick example (Ellipses denote non applicable generated code):
sealed partial class App : Application
{
...
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
User currentUser = e.User;
...
}
...
}

Related

How to request Contacts and Calendar Permissions on XamarinMac?

I'm trying to access the ContactStore of MacOS App, did the following implementation
public void Contacts()
{
//Starting
var store = new CNContactStore();
store.RequestAccess(CNEntityType.Contacts, async (bool granted, NSError error) =>
{
if (granted)
{
//Query things
}
});
}
The thing is that the Authorize screen never popup, and the Permission always say denied.
If I go to settings to remove that record, the app is not there.
Can someone please point me to the light?
It works for me with those two lines:
var contactStore = new CNContactStore();
var status = CNContactStore.GetAuthorizationStatus(CNEntityType.Contacts);
It could be also that you need to set NSContactsUsageDescription in info.plist.

How to pass a variable from one class to another in a URI?

This is what I have so far which calls a GetCoordinates method and navigates to the map on a button click. I'm wondering though how I would pass over the coordinate data.
Does anyone know how I could pass the MyGeoPosition variable of type GeoPosition to the OnNavigatedTo method of my map class? I know how to call a method from another class but not how to pass data such as a variable.
private async Task GetCoordinates(string name = "My Car")
{
await Task.Run(async () =>
{
// Get the phone's current location.
Geolocator MyGeolocator = new Geolocator();
//need to pass the below variable containing coordinate data..
MyGeolocator.DesiredAccuracyInMeters = 5;
Geoposition MyGeoPosition = null;
try
{
MyGeoPosition = await MyGeolocator.GetGeopositionAsync(TimeSpan.FromMinutes(1), TimeSpan.FromSeconds(10));
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Location is disabled in phone settings or capabilities are not checked.");
}
catch (Exception ex)
{
// Something else happened while acquiring the location.
MessageBox.Show(ex.Message);
}
});
}
//sets location of parking space using the GetCoordinates method
//opens map
private async void setLocationBtn_Click(object sender, RoutedEventArgs e)
{
await this.GetCoordinates();
NavigationService.Navigate(new Uri("/Maps.xaml", UriKind.Relative));
}
Try something like this
FirstPage
this.NavigationService.Navigate(new Uri(string.Format("LocationView.xaml?GeoX={0}&GeoY={1}", GeoX, GeoY), UriKind.Relative));
secondPage
if (NavigationContext.QueryString.ContainsKey("GeoX") && NavigationContext.QueryString.ContainsKey("GeoY"))
{
double GeoX =Convert.ToDouble(NavigationContext.QueryString["GeoX"].ToString());
double GeoY = Convert.ToDouble(NavigationContext.QueryString["GeoY"].ToString());
....
}
You could use PhoneApplicationservice to pass data between pages in windows phone application.
Here is good example about PhoneApplicationservice. Here is a short example how PhoneApplicationService works, may this will help you.
private async void setLocationBtn_Click(object sender, RoutedEventArgs e)
{
await this.GetCoordinates();
PhoneApplicationService.Current.State["Data"] = your data;
NavigationService.Navigate(new Uri("/Maps.xaml", UriKind.Relative));
}
//On Second page
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var data =PhoneApplicationService.Current.State["Data"] as Cast your type
PhoneApplicationService.Current.State.Remove("Data");
}
You can pass data by four ways which is clearly explained in following post
http://nishantcop.blogspot.in/2011/08/passing-data-between-pages-in-windows.html
Found another way in my searching for another issue:
http://msdn.microsoft.com/en-us/library/windows/apps/hh771188.aspx
Scroll down to: Passing information between pages
Its a lot simpler than my solution above, but my solution has other requirements hence why I chose that one, but for your needs, this is a better way.
I had a similar issue where I was passing user credentials between classes and I decided to use IsolatedStorageSettings class. But I have read that Windows will be depreciating this class in the future as it moves to merge Windows and Windows Phone code.
SO, this is the class I believe Microsoft want you to use so that you dont get stuck with a depreciated class in the future, and its called Windows.storage.
Hope this helps.
My case as said if for passing username and password along with if the user was a premium user and if when the app starts if they are already logged on. It would then re-log the user on automatically.
Here I create the storage in MainPage class
IsolatedStorageSettings myUserSettings = IsolatedStorageSettings.ApplicationSettings;
Here is the MainPage class method:
private void GetUserData()
{
// System.Diagnostics.Debug.WriteLine("Grabbing Data");
if (IsolatedStorageSettings.ApplicationSettings.Contains("userLoggedIn"))
{
string isLoggedIn = IsolatedStorageSettings.ApplicationSettings["userLoggedIn"] as string;
if (isLoggedIn.EndsWith("rue"))
isLoggedOn = true;
else
isLoggedOn = false;
// System.Diagnostics.Debug.WriteLine("log in data " + isLoggedIn + " " + isLoggedOn);
}
else
{
myUserSettings.Add("userLoggedIn", "false");
isLoggedOn = false;
}
if (IsolatedStorageSettings.ApplicationSettings.Contains("fullAccess"))
{
string hasFullAccess = IsolatedStorageSettings.ApplicationSettings["fullAccess"] as string;
if (hasFullAccess.EndsWith("rue"))
fullAccess = true;
else
fullAccess = false;
}
else
{
myUserSettings.Add("fullAccess", "false");
fullAccess = false;
}
if (IsolatedStorageSettings.ApplicationSettings.Contains("username"))
{
username = IsolatedStorageSettings.ApplicationSettings["username"] as string;
}
else
{
myUserSettings.Add("username", "");
username = "me";
}
if (IsolatedStorageSettings.ApplicationSettings.Contains("password"))
{
password = IsolatedStorageSettings.ApplicationSettings["password"] as string;
}
else
{
myUserSettings.Add("password", "");
password = "v";
}
myUserSettings.Save();
}
Now in my Login Class I have to create the storage variable again
IsolatedStorageSettings myUserSettings = IsolatedStorageSettings.ApplicationSettings;
And now once I verfied the user I write the relevant information to the storage file: (parts of method missing as irrelevant)
// Here I have just finished using JSON to extra info from a JSON response
if (success.EndsWith("rue"))
{
if (!myUserSettings.Contains("userLoggedIn"))
{
myUserSettings.Add("userLoggedIn", success);
}
else
{
myUserSettings["userLoggedIn"] = success;
}
if (!myUserSettings.Contains("username"))
{
myUserSettings.Add("username", username);
}
else
{
myUserSettings["username"] = username;
}
if (!myUserSettings.Contains("password"))
{
myUserSettings.Add("password", password);
}
else
{
myUserSettings["password"] = password;
}
if (!myUserSettings.Contains("fullAccess"))
{
myUserSettings.Add("fullAccess", fullAccess);
}
else
{
myUserSettings["fullAccess"] = fullAccess;
}
myUserSettings.Save();
and if something does not work, check that you did save the file as follows:
myUserSettings.Save();
Hope you can make sense of my example but please refer to the doco from Microsoft. This link shows a simple example I used to solve my requirements.

what is used in windows app on the place of Session?

i am new to windows programming, as we use Store user's details in Session when user successfully logged into a web application and check the session in master page every time, if it will null then redirect the user to login page. I want to do the same thing in Windows application, i have created a login form: the code is written below:
private void btnLogin_Click(object sender, EventArgs e)
{
clsLogin obj = new clsLogin();
DataTable dtLogin = obj.Login_Check(txtUserName.Text.Trim(), txtPassword.Text.Trim());
if (dtLogin.Rows.Count > 0)
{
if (dtLogin.Rows[0]["result"].ToString() == "3")
{
lblMessage.Text = "Password does not matched";
}
else
if (dtLogin.Rows[0]["result"].ToString() == "2")
{
lblMessage.Text = "User does not exists";
}
else
{
Staff.Home home = new Staff.Home();
this.Hide();
home.Show();
}
}
}
}
Now what i want to do is: store the user info some where and when user click on Log off then it will destroy that session and it will open the Login form.
i know it is a very silly question, as i am new to windows programming its tough for me, please help.
Apart from the obvious issues with the code:
Direct access to rows by index
Login being done in the event handler directly
You should have separate login service and data access service
I would:
Create a login service that maintains the current logged in user details and performs the authentication itself.
Create a data access service that the login service can call to access the datastore
Then in your event handler you just need to call:
if (loginService.Authenticate(username, password))
{
// Do your UI handling here
}
then the loginService will have a .CurrentUser property for example and you can go from there.
e.g.
public class LoginService
{
private User _currentUser;
public bool Authenticate(string username, string password)
{
if (_currentUser != null)
{
Logout();
}
else
{
var user = DataAccess.Get("users").SingleOrDefault(u => u.Username = username);
if (user == null)
{
throw new Exception("No user with that username found");
}
if (password == user.Password)
{
_currentUser = user;
return true;
}
else
{
return false;
}
}
}
public User CurrentUser
{
get { return _user; }
}
}
In a Web application it is supposed that there are multiple clients connected to the single server; you should use Session to distinguish between them and to pass data to each of them "there and back again". For a desktop application this problem does not exist at all - there is exactly one user and his data is all here: you do not need some special mechanism like Session for it.
This means that you may use a number of different approaches to pass data from your form. In your example it seems more logical to pass data to your "home" form directly, either through constructor
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home(userData);
this.Hide();
home.Show();
}
or through a property
else
{
var userData = .... (txtUserName.Text);
Staff.Home home = new Staff.Home();
home.UserData = userData;
this.Hide();
home.Show();
}
This is only an example, there are a lot alternatives - just think about this "single user, always on site" model.

Facebook SDK and threads (WebBrowser control)

This is probably more of a general c# and simple threading question than it is a Facebook SDK question, but I may be wrong. But I could really use some help. I am reusing the sample code that comes with the SDK which includes a FacebookLoginDialog class. I am currently using it like this. In my GetMessages, GetFriendRequests, and other Get* classes, I always try/catch calls like this:
try
{
var result = (IDictionary<string, object>)fb.Get("/me/inbox");
}
catch (FacebookOAuthException e)
{
FacebookSession.Login();
}
Here's my login method in my FacebookSession class
public static void Login()
{
var fbLoginDialog = new FacebookLoginDialog(APP_ID, EXTENDED_PERMISSIONS);
DialogResult dr = fbLoginDialog.ShowDialog();
DisplayAppropriateMessage(fbLoginDialog.FacebookOAuthResult);
}
And here is the constructor in my FacebookLoginDialog class (this is where I have the problem)
public FacebookLoginDialog(string appId, string[] extendedPermissions, bool logout)
{
try
{
var oauth = new FacebookOAuthClient { AppId = appId };
var loginParameters = new Dictionary<string, object>
{
{ "response_type", "token" },
{ "display", "popup" }
};
if (extendedPermissions != null && extendedPermissions.Length > 0)
{
var scope = new StringBuilder();
scope.Append(string.Join(",", extendedPermissions));
loginParameters["scope"] = scope.ToString();
}
var loginUrl = oauth.GetLoginUrl(loginParameters);
if (logout)
{
var logoutParameters = new Dictionary<string, object>
{
{ "next", loginUrl }
};
System.Uri uri =
new Uri("https://www.facebook.com/logout.php?next=" +
"https://www.facebook.com/connect/login_success.html&access_token=" +
FacebookSession._accessToken);
this.navigateUrl = uri;
}
else
{
this.navigateUrl = loginUrl;
}
InitializeComponent(); // crash here... sometimes
}
catch (Exception e)
{
//Log error message
}
}
Sorry for all the code, but now the problem. This code works fine the first time through. If I go to my facebook applications permissions page in Facebook and remove the app (that is, remove its permissions), while my desktop app here is NOT running, when I do start it up, it sees that it does not have permission and shows the login dialog. I can save the access_key and it will work just fine. But if I go to the facebook apps page and yank the permissions while my desktop app is running, then bad things happen. I get an error message about the activex control cannot be instantiated because the current thread is not in a single-threaded apartment. I have seen many posts here that say all you have to do is put [STAThread] above your main(), and my code has that. I have also tried creating a new thread to call the FacebookLoginDialog, but not only did that not work, but since my code is really not designed to run in multiple threads, that started causing more problems.
Is there a simple solution to all this, or do I need to redesign my code so that it properly runs in multiple threads? Or should I just live with the program crashing in those few instances when someone monkeys with the facebook permissions while my app is running?

How do I maintain user login details in a Winforms application?

Hi can I'm very new to windows forms. Here I want to maintain state (like session in web applications) in windows forms.
Actually i want to store user login details in session. But i think there is no concept of session in winforms. So what is the alternative method to handle this type of situation.
Regards,
Nagu
There is no concept of Session variables in windows forms. What you can do is:
Create a internal class that holds the User name and password and any other variables and enumerations needed across the application (Something like Common.cs). These can be accessed through public properties across the application.
Have a parameterized constructor for all the forms and send the user name and the password whenever you are showing the form.
public class MyForm : Form
{
private string userName;
private string password;
}
Since windows forms are statefull (opposed to stateless for web forms), you can just use a field in your Form class.
You need to think more in terms of scope than session; as long as an object remains in scope you will be able to pull values from its public properties/fields.
In your case it would make sense to store the user details in a static class:
public static class LoginInfo
{
public static string UserID;
}
Now you can access the UserID simply from anywhere in your code:
MessageBox.Show(LogInfo.UserID);
In winforms you can use variables that are exposed to other forms through methods or properties.
You can also use static variables.
In the following example, you would have a controller for each window or group of windows. The controllers would be passed to one another depending on how they need to collaborate (what knowledge they need to share, etc). The important thing is to keep your application state in the controllers and limit the windows to handling user input and events.
// pseudocode, because I do not know WinForms that much
class MainController
{
private Guid securityToken;
public Guid SecurityToken
{
get { return securityToken; }
set { securityToken = value; }
}
}
class LoginWindowController
{
MainController mainController;
LoginWindow loginWindow;
public LoginWindowController(MainController mainController)
{
this.loginWindow = new LoginWindow(this);
this.mainController = mainController;
}
public void Show()
{
loginWindow.IsVisible = true;
}
public void HandleLogin()
{
Guid token =
myobject.Authenticate(loginWindow.Username, loginWindow.Password);
if (token != Guid.Empty)
{
mainController.SecurityToken = token;
}
}
}
In reply to your comment to my first reply:
You are creating the new instance of the Login form. How is that supposed to have values. It is a Login form and hence I believe you will be closing it as the user enters user name and password and clicks OK or whatever.
Then, there is no way you can get the values from the Login form as it is closed. If you need to stick to this approach, this could be a way:
Do not close the Login form, just hide it.
Pass the current instance to the next form. Like this:
In Login form:
NextForm nxt = new NextForm(this);
The constructor of NextForm will look like:
public NextForm(LoginForm frm){
// Code here
}
Now in NextForm, you can access the properties through "frm".
from a program i was using with a login form to store global variables and to store the password as a secure string. Within the program I am able to "run as" a specific user when I call processes. You can use it for other things besides process.start.
//to run process as another user
//create these global variables on the first
//form or piece of code in your program
class usernameGlobalVariable
{
public static string var = "";
}
class passwordGlobalVariable
{
public static SecureString var;
}
// use these as event handlers for text fields
//for your login form
private void usernameTextBox_TextChanged(object sender, EventArgs e)
{
usernameGlobalVariable.var = usernameTextBox.Text;
}
private void passwordTextBox_TextChanged(object sender, EventArgs e)
{
SecureString passWord = new SecureString();
foreach (char c in passwordTextBox.Text.ToCharArray())
{
passWord.AppendChar(c);
}
passwordGlobalVariable.var = passWord;
}
//put this on form that launches program
//this assigns variables for process.start
//change fileName to path and name of program
// use \\ in paths
string fileName = "c:\\hdatools\\Ping2.exe";
string arguments = "";
string domain = "domain";
//start the process
//put this on the page along w the above variables that
//launches the app as another user
//the .var variables are global
{
Process.Start(
fileName,
arguments,
usernameGlobalVariable.var,
passwordGlobalVariable.var,
domain);
}
It's unclear to me whether you are talking about a web application or a stand along application based upon one of your responses. If you are talking about a web application, you can use the Session properties on the Page object.
It would set the variables like this:
Session["username"] = "Username";
Session["fullname"] = "User's full name";
You could then access like:
lblGreetings.Text = "Hi " + Session["fullname"];
Is that what you were after?

Categories