I am making a program in C# for accessing and storing passwords, as a school project.
I have a text file, passwords.txt, with account names and the associated passwords as such:
gmailUsername:gmailPassword
facebookUsername:facebookPassword
So colon (:) between username and password and new line for new site/account whatever.
In the Windows Form i have a listBox that should get its items (only accounts) from reading the passwords.txt file.
Once a item from the listBox has been selected, a textbox in the same Form should show only that associated password from that same text file.
How can I code this? I am stuck on trying to figure out how to read the file and putting all profile entries into an array, then adding these as list items in the listBox. And putting all passwords into another array.
This code would do the job.
You need to create a form with a ListBox named "listBox1" and a TextBox named "textBox1".
public partial class Form1 : Form
{
List<Account> Accounts = new List<Account>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Accounts.Clear();
foreach (string line in File.ReadAllLines("passwords.txt"))
{
int pos = line.IndexOf(':');
if (pos > 0)
{
Accounts.Add(new Account() { Service = line[0..pos], Password = line[(pos + 1)..] });
}
}
listBox1.DataSource = Accounts;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
textBox1.Text = ((sender as ListBox)?.SelectedItem as Account)?.Password;
}
}
class Account
{
public string Service { get; set; }
public string Password { get; set; }
public override string ToString()
{
return Service;
}
}
Here is what i ended up with. Changed the method slightly. Used List instead of an array.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PSN_PasswordManager
{
public partial class FormVaultUnlocked : Form
{
List<string> myAccounts = new List<string>();
List<string> myPasswords = new List<string>();
string[] passLines;
public FormVaultUnlocked()
{
InitializeComponent();
getProfiles();
}
private void lstProfiles_SelectedIndexChanged(object sender, EventArgs e)
{ // When new list item is chosen
// Gets selected item (string)
string curItem = lstProfiles.SelectedItem.ToString();
//MessageBox.Show(curItem); //testing
string tempPassword = null;
for (int i = 0; i < myAccounts.Count; i++)
{
if (myAccounts[i] == curItem)
{
tempPassword = myPasswords[i];
}
}
txtPassword.Text = tempPassword;
string showPassword = "yeet";
//txtPassword.Text = showPassword;
}
void getProfiles()
{
// Lese tekstfil
string[] passLines = File.ReadLines("passwords.txt").ToArray();
// Legge til items fra array til listBox
foreach (string profile in passLines)
{
// splitting acc. and pass. into strings in new array.
// account[0] is account name. account[1] is password.
string[] accPass = profile.Split(':');
// adds account as list items. And accounts and passwords to global lists.
lstProfiles.Items.Add(accPass[0].ToString());
myAccounts.Add(accPass[0]);
myPasswords.Add(accPass[1]);
}
}
}
}
Related
I am new to WPF and I am trying to figure out how to create an "Update" button that will show all the contents of a row on a table, allowing the user to change any category and save the new data.
What the main window would look like :
Then when the update button is clicked, a window looking like this would pop up. :
How would you make the second window? Down below is what I have to show the main window without an "update" button.
**MainWindowxaml.cs**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using System.IO;
namespace Sort_a_list
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public class Student
{
public string name
{
get;
set;
}
public int age
{
get;
set;
}
public string gender
{
get;
set;
}
public string major
{
get;
set;
}
public string classification
{
get;
set;
}
}
public MainWindow()
{
InitializeComponent();
List<Student> user = new List<Student>();
try
{
using (StreamReader sr = new StreamReader(#"C:\Users\justi\Documents\2021 Self Study\WPF C#\Samples.txt"))
{
string line;
char[] sep = { ',' };
int length;
ArrayList rows = new ArrayList();
while ((line = sr.ReadLine()) != null)
{
string[] words = line.Split(sep);
length = words.Length;
rows.Add(words);
}
string[] columns;
for(int i = 1; i < rows.Count; i++)
{
columns = (string[])rows[i];
user.Add(new Student() { name = columns[0], age = Int16.Parse(columns[1]), gender = columns[2], major = columns[3], classification = columns[4] });
}
}
}
catch(Exception e)
{
Console.WriteLine("The file could not be read:");
Console.WriteLine(e.Message);
}
sort.ItemsSource = user;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
}
}
}
Please help! Thank you very much!
You won't be able to access your Window1's DataGrid from Window2 directly.
You also not have access to your source collection (List) from Window2 to modify it from there.
In that facts, you got 2 ways:
use external database;
create public fixed collection of Students.
First of all and in any way I strongly recommend you to add some ID field to your Student object to be able unify each student.
If use external database, you can simply call something like "UPDATE students s SET s.name = #name, s.age = #age... WHERE s.ID = #id" from your Window2 when Save button clicked. #name, #age ... is new modified values
If use public fixed collection, you can access it from any part of your program.
When Window2 Save button clicked, you can search for student in it by student's ID and simply edit him. After Window2 closing you need just refresh DataGrid view by resetting ItemsSource.
It may look like this:
Student class:
public class Student
{
// Need to be unique for each student
public int ID { get; private set; }
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
public string Major { get; set; }
public string Classification { get; set; }
public Student(int id)
{
ID = id;
Name = "SomeName";
Age = -1;
Gender = "Unknown";
Major = "Unknown";
Classification = "None";
}
// May also be overloaded with id, id+name, id+name+age, id+name+age+gender etc
public Student(int id, string name, int age, string gender, string major, string classification)
{
ID = id;
Name = name;
Age = age;
Gender = gender;
Major = major;
Classification = classification;
}
// If you need some kind of string representation of Student
public override string ToString()
{
return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
}
}
Fixed and public collection class to store Students:
public static class DB
{
// Your actual Database, where Students would be stored
private static readonly List<Student> students = new List<Student>();
// You can get it by DB.Students from anywhere
public static List<Student> Students { get { return students; } }
// As I see you use a file as source for item collection.
// You can add some Save() method to rewrite you existing
// file with items from "database":
// public static void Save()
// {
// StringBuilder sb = new StringBuilder();
//
// foreach (Student student in students)
// {
// sb.AppendLine(student.ToString());
// }
//
// File.WriteAllText("PathToYourFile", sb.ToString());
// }
//
// You should also override ToString method in Student class
// with something like (in format you wish):
// public override string ToString()
// {
// return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
// }
}
}
Update button click handler at Window1:
private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
// There should be selected only 1 item or use dataGrid.SelectedItems[0]
if (dataGrid.SelectedItem is Student student)
{
// Pass selected Student to Window2
// where user will edit it
Window2 w2 = new Window2(student);
// Subscribe to Closed window to refresh DataGrid view after Student editing
w2.Closed += (s, a) =>
{
// Refresh the view of DataGrid by resetting its ItemsSource property
dataGrid.ItemsSource = null;
dataGrid.ItemsSource = DB.Students;
};
// Show update window
w2.ShowDialog();
}
}
And some kind of Window2:
public partial class Window2 : Window
{
// Here would be a copy of Student object from Window1
// with which we would manipulate in Window2
// while editing in its fields
private readonly Student editableStudent = null;
public Window2(Student student)
{
InitializeComponent();
// Copy student object to store it in our Window2
// and be able to modify it not only from Constructor
editableStudent = student;
// Fill Window2 fields with existing Student values
tbName.Text = student.Name;
tbAge.Text = student.Age.ToString();
tbGender.Text = student.Gender;
tbMajor.Text = student.Major;
tbClassification.Text = student.Classification;
// Easy "on-the-fly" subscribe to each field TextChanged handlers to check,
// whether some data was changed/edited or not
// and save it to editableStudent
tbName.TextChanged += (s, a) =>
{
// Comparing value in field with existing Student's value
if (tbName.Text != student.Name) // May also check for not empty / or for min input length
{
// Saving new value to a copied object of our Student
editableStudent.Name = tbName.Text;
}
};
// Don't forget to check for integer value
// and convert in back to int:
// Convert.ToInt32(tbAge.Text)/int.Parse(tbAge.Text)/int.TryParse(tbAge.Text, out int age)
tbAge.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbGender.TextChanged += (sender, args) => { /* Do same as with Name. */ };
tbMajor.TextChanged += (sender, args) => { /* Do same as with Name */ };
tbClassification.TextChanged += (sender, args) => { /* Do same as with Name */ };
}
private void ButtonSave_Click(object sender, RoutedEventArgs e)
{
// Find index of Student element in our "Database" (List)
int index = DB.Students.FindIndex(x => x.ID == editableStudent.ID);
if (index != -1)
{
// Update record in a collection if it was found
DB.Students[index].Name = editableStudent.Name;
DB.Students[index].Age = editableStudent.Age;
DB.Students[index].Gender = editableStudent.Gender;
DB.Students[index].Major = editableStudent.Major;
DB.Students[index].Classification = editableStudent.Classification;
// Instead of use 'editableStudent' field with copied in
// constructor student's object, you can create it here
// and fill with values from TextBoxes in Window2.
// Or not create new Student object and fill new values
// directly in "database" by index.
// But you anyway need to store at least student's ID from
// student's object, passed from Window1, to be able to
// find him in "database"
// Student modifiedStudent = new Student(...);
// modifiedStudent.Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// modifiedStudent.Age = age;
// ...
// DB.Students[index].Name = modifiedStudent.Name;
// DB.Students[index].Age = modifiedStudent.Age;
// ...
// or
// DB.Students[index].Name = tbName.Text;
// if (int.TryParse(tbAge.Text, out int age))
// DB.Students[index].Age = age;
// ...
}
else
{
// Or message user if not found
MessageBox.Show("Student not found in Database (in a List of Students).");
}
// Close window after updating record in "Database"
// DataGrid view we will refresh from Window1 after
// Window2 close
Close();
}
private void ButtonCancel_Click(object sender, RoutedEventArgs e)
{
// Do nothing with Student, just close
Close();
}
}
I made a form that contains a datagridview, button, and a chart. The datagridview shows a Sales record of the business. The graph shows the top selling items from the datagridview. It is based from the quantity column (number of items sold) of the datagridview. What I want to happen is that when a user clicks the Generate button, a messagebox/ new form will appear.
It will contain a label (Top 3 Items) and under that label, there will be a ranking of the best selling items.
The question is how will I be able to create a ranking list in a messagebox/new form if the data is from a chart/datagridview?
Here's my current code for the form:
public partial class CFReport : Form
{
public CFReport()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
label5.Text = DateTime.Now.ToLongTimeString();
timer1.Start();
}
private void CFReport_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'casaFrancaDataSet.Sales' table. You can move, or remove it, as needed.
this.salesTableAdapter.Fill(this.casaFrancaDataSet.Sales);
timer1.Start();
label5.Text = DateTime.Now.ToLongTimeString();
label6.Text = DateTime.Now.ToLongDateString();
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Top 3 items:" + Environment.NewLine + "1. " + Environment.NewLine + "2. " + Environment.NewLine + "3. ");
}
}
Try this if I got the question right. You can use LINQ for ordering your chart/datagridview.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApp9
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<Product> products = new List<Product>(); // your chart/datagridview
products.Add(new Product { Name = "Banana", Price = 1 });
products.Add(new Product { Name = "Orange", Price = 10 });
products.Add(new Product { Name = "Apple", Price = 5 }); // your products
products = products.OrderByDescending(p => p.Price).ToList(); // ordering products by price
StringBuilder sb = new StringBuilder();
int i = 1;
foreach (var product in products)
{
sb.Append($"{i}. {product.Name} - {product.Price}\n");
i++;
}
MessageBox.Show(sb.ToString());
}
}
class Product
{
public string Name { get; set; }
public int Price { get; set; }
}
}
Use data binding to separate your data (model) from how the data is displayed (view).
Your DataGridView has a DataSource. Use that to show the data.
class DisplayedProduct
{
public int Id {get; set;}
public string Name {get; set;}
public int Quantity {get; set;}
public decimal Price {get; set;}
}
Use visual studio designer to create the columns and tell which column should show which property, or do this programmatically.
public MyForm : Form
{
public MyForm()
{
this.InitializeComponent();
this.columnId.DataPropertyName = nameof(DisplayedProdut.Id);
this.columnName.DataPropertyName = nameof(DislayedProduct.Name);
...
}
I'll make a lot of small methods, so they will be easy to understand, easy to reuse, easy to unit test, debug and change:
Fetch the Products:
private IEnumerable<DisplayedProduct> FetchProductsToDisplay()
{
... // TODO: implement
}
Create a property to show the Products and fetch the displayed (and possibly edited) products:
private BindingList<DisplayedProduct> DisplayedProducts
{
get => (BindingList<DisplayedProduct>)this.dataGridView1.DataSource;
set => this.dataGridView1.DataSource = value;
}
And show the products on form loading:
private void InitProductDisplay()
{
this.DisplayedProducts = new BindingList<DisplayedProduct>
this.FetchProductsToDisplay.ToList());
}
private void OnFormLoading(object sender, ...)
{
this.InitProductDisplay();
}
This is enough to show the products, and fetch them when needed. All changes made by the operator (add / remove rows, edit cells) are automatically reflected in the binding list.
private IEnumerable<DisplayedProduct> GetTopProducts()
{
return this.DisplayedProduts.OrderByDescending(product => product.Quantity);
}
private string CreateTextTopProducts(int count)
{
IEnumerable<DisplayedProduct> top3Products = GetTopProducts()
.Select((product, index) => new
{
Index = index + 1,
// select the properties that you want to show in the messagebox:
Name = product.Name,
...
})
.Take(count);
// use a string builder to efficiently add formatted lines:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Top 3 items:");
foreach (var product in top3Products)
{
stringBuilder.AppendFormat("{0}. {1}", product.Index, product.Name);
stringBuilder.AppendLine();
}
return stringBuilder.ToString();
}
Finally the methods to show the top3 products:
private void ShowTop3Products()
{
string displayText = this.CreateTextTop3Products(3);
MessageBox.Show(this, displayText, ...);
}
private void button2_Click(object sender, EventArgs e)
{
this.ShowTop3Products();
}
I have this code:
cpMythic0.Text = Properties.Settings.Default.M0;
and let's say I have 31 cpMythic (string) variables all being named "cpMythic0, cpMythic1, cpMythic2 ... cpMythic30 and the same goes with some Properties Settings string variables called "M0,M1,M2...M30"
Instead of writing this:
cpMythic0.Text = Properties.Settings.Default.M0;
cpMythic1.Text = Properties.Settings.Default.M1;
I would like to use a for() function, with an i variable but I don't really know the syntax.
I would appreciate any help.
I'm not sure why you'd want to do this, but this is achievable using reflection.
Here is an example:
using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Fill_Click(object sender, EventArgs e)
{
string propertyMatcher = "cpMythic";
var defaultSettings = new Properties.Settings.Default(); //Get instance of default settings
var settingProperties = defaultSettings.GetType().GetFields(); //Get default setting properties.
foreach (TextBox control in this.Controls.OfType<TextBox>().Where(c => c.Name.StartsWith("cpMythic"))) //Loop through controls, and filter
{
string settingPropertyName = "M" + control.Name.Substring(propertyMatcher.Length);
var settingProperty = settingProperties.FirstOrDefault(p => p.Name == settingPropertyName);
var value = settingProperty.GetValue(defaultSettings); //Get the value of the corresponding setting using reflection
control.Text = value.ToString(); //Set value
}
}
private static class Properties
{
public static class Settings
{
public class Default
{
public string M0 = "Default Value 0";
public string M1 = "Default Value 1";
public string M2 = "Default Value 2";
}
}
}
}
}
For my windows forms application I tried to retrieve the selected string from a listBox and i wanted it to compare to a set string so that, in the event of the comparison returning true, i can set the next listBox to have specific, selection-related values.
namespace PhysCalc
{
public class Selectors
{
public static string[] topicContents = new string[] { "MECHANICS", "THEORY_OF_RELATIVITY" };
public static string[] VarItemsMechanics = new string[] { "Test", "Wavelength" };
public static void SetVarBox()
{
PhysCalc.Topic.DataSource = topicContents;
if PhysCalc.Topic.Items[PhysCalc.Topic.SelectedIndex].ToString() == "MECHANICS")
{
PhysCalc.Var.DataSource = VarItemsMechanics;
}
}
}
}
But somehow when i select "MECHANICS" in the listBox(in the code above named 'Topic'), the 2nd listBox(above named 'Var') just stays empty
any help would be very appreciated
I think you need to set the DisplayMember and ValueMember properties on the Var list control when using the DataSource.
If the DataSource is an object then DisplayMember is the object member it will use as the text display (which in your case is currently blank), and ValueMember is used to determine the SelectedValue property of the list control which is useful to bind against.
For example if your VarItemsMechanics is populated with the following class:
public class Mechanic
{
public int ID { get; set; }
public string Name { get; set; }
}
Then you probably want to set the DisplayMember to "Name" and you might want to set the ValueMember to "ID" (subjective).
Try changing
if (PhysCalc.Topic.GetItemText(PhysCalc.Topic.SelectedItem) == "MECHANICS")
to this:
if (PhysCalc.Topic.Items[PhysCalc.Topic.SelectedIndex].ToString() == "MECHANICS")
1- Bind your First List named "Topic" in the form_load Event
2- in the SelectedIndexChanged Event of your First List do your checks about the selected Item
and Fill the Second List
Here is the Complete Code and it works fine for me
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public static string[] topicContents = new string[] { "MECHANICS", "THEORY_OF_RELATIVITY" };
public static string[] VarItemsMechanics = new string[] { "Test", "Wavelength" };
private void Form1_Load(object sender, EventArgs e)
{
listBox1.DataSource = topicContents;
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
string curItem = listBox1.SelectedItem.ToString();
switch (curItem)
{
case "MECHANICS":
listBox2.DataSource = VarItemsMechanics;
break;
}
}
}
}
I'm learning as I go with c# and I have been stuck with some code for a few weeks now and I'm hoping an experienced programmer can help.
Here is the scenario: When one connects to the remote computers' registry you only get HKEY_LOCAL_MACHINE & HKEY_USERS. Now HKEY_USERS has a range of sub keys that related to the users profiles registry stored on the machine but is only displays it by numbers instead of Jo's registry or John's registry, hope you see where I'm going with this. So, using the code below provides one with the users profile name which is in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList and the sub key it's stored in (distinguish by numbers) is the same sub key in HKEY_USERS...bingo.
Please note: This line of code if (!(sk.GetValue("Guid") == null)) ie."Guid" is only present in a domain environment within the Profile list sub key and has a value called "Guid". Because there are various Sub keys listed, I only want the ones which is a users profile. On my home machine I add the sub key in to make the code work.
using System;
using System.Windows.Forms;
using Microsoft.Win32;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//http://www.dreamincode.net/code/snippet1995.htm
//The registry key:
string SoftwareKey = #"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList";
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(SoftwareKey))
{
foreach (string skName in rk.GetSubKeyNames())
{
using (RegistryKey sk = rk.OpenSubKey(skName))
{
try
{
if (!(sk.GetValue("Guid") == null))
{
string UserProfile;
string UserProfileComboBox;
string Software = null;
UserProfile = Software += sk.GetValue("ProfileImagePath");
UserProfileComboBox = UserProfile.Substring(9); //this reduces C:\Users\Home to Home. (0, 8) would have provide C:\Users
comboBox1.Items.Add(UserProfileComboBox);
//This messagebox displays the sub key I need when the userprofile is selected from the checkbox
MessageBox.Show(UserProfile + " " + skName);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
}
}
}
In the above code I used: UserProfile.Substring(9) to reduce C:\Users\Home to just Home which is disable in the image below:
I've also added the following line of code to display the results to a message box for your understanding: MessageBox.Show(UserProfile + " " + skName);
What I would like to be able to do is...when I select the User profile from the combo box that the code knows which HKEY_USER subkey it relates too eg. S-1-5-21-340336367-1635450098-906894100-1008 (hkeyuserprofile) so I can do the registry key changes later:
CHANGE:
using (RegistryKey test = registry.Users.OpenSubKey(#"Software\Policies\Microsoft\..."))
To:
string hkeyuserprofile;
using (RegistryKey test = registry.Users.OpenSubKey(hkeyuserprofile + #"\Software\Policies\Microsoft\...")
Any help would be greatly appreciate! ;)
You can accomplish this in a couple of different ways. I'll show you two, but the first is preferred over the second. (I realized after writing this the second way is not applicable, so I have refrained from adding it)
Databinding
The nice thing about most of the collection controls is that they have a fairly decent data-binding mechanism built into them. You can leverage this to bind the control to a collection of more strongly typed Objects for future retrieval.
First thing is first, you need an object that represents the information you want:
public class RegKeyInfo
{
public String SubKeyPath { get; set; }
public String Name { get; set; }
}
So now you have a type that will store both the derived name you want, and the SubKeyPath for later use.
Now we need to tell the combobox how it should handle this kind of object. We can set that up in the Form Constructor. Normally you could do this via the designer, but it's easier to show you here.
public Form1()
{
InitializeComponent();
comboBox1.ValueMember = "SubKeyPath";
comboBox1.DisplayMember = "Name";
}
Now you have told the ComboBox that when you give it an Object, it should look for a property called "Name" and use that for the display, and use the property "SubKeyPath" for the Value.
Instead of adding items manually to the ComboBox, we are going to create a collection of our RegKeyInfo type, and "Bind" it to the ComboBox.
private void Form1_Load(object sender, EventArgs e)
{
//http://www.dreamincode.net/code/snippet1995.htm
//Declare the string to hold the list:
var keys = new List<RegKey>();
//Snip...
UserProfileComboBox = UserProfile.Substring(9);
keys.Add(new RegKey {
Name = UserProfileComboBox,
KeyPath = skName
});
//Snip...
comboBox1.DataSource = keys;
}
The big difference here is making use of the DataSource property, which tells the ComboBox to use data-binding based on the information you have given it.
When someone selects a value from the ComboBox, you can access the SelectedValue property and retrive the SubKeyPath that it is bound to. Try adding in this event handler to the SelectedValueChanged event to see what I'm talking about:
void comboBox1_SelectedValueChanged(object sender, EventArgs e)
{
MessageBox.Show(comboBox1.SelectedValue as String);
}
//Updated code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
namespace RegistryUSER
{
public partial class Form1 : Form
{
public class RegKeyInfo
{
public String SubKeyPath { get; set; }
public String Name { get; set; }
}
public Form1()
{
InitializeComponent();
comboBox1.ValueMember = "SubKeyPath";
comboBox1.DisplayMember = "Name";
}
private void Form1_Load(object sender, EventArgs e)
{
var keys = new List<RegKeyInfo>();
using (RegistryKey ProfileKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"))
{
foreach (string skName in ProfileKey.GetSubKeyNames())
{
using (RegistryKey sk = ProfileKey.OpenSubKey(skName))
{
try
{
if (!(sk.GetValue("Guid") == null))
{
string UserProfile;
string UserProfileKey;
string ProfileValue = null;
string ProfileKeyName = null;
UserProfile = ProfileValue += sk.GetValue("ProfileImagePath");
UserProfileKey = ProfileKeyName += skName;
RegKeyInfo UserInformation = new RegKeyInfo();
UserInformation.Name = UserProfile;
UserInformation.SubKeyPath = UserProfileKey;
UserProfile = UserProfile.Substring(9); //this reduces C:\Users\Home to Home. (0, 8) would have provide C:\Users
keys.Add(new RegKeyInfo
{
Name = UserProfile,
SubKeyPath = UserProfileKey
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
comboBox1.DataSource = keys;
}
}
private void button1_Click(object sender, EventArgs e)
{
try
{
string result = comboBox1.SelectedValue as string;
using (RegistryKey Key = Registry.Users.OpenSubKey(result + #"\Software\Microsoft\Office\14.0\Outlook\OST"))
if (Key != null)
{
int Value = System.Convert.ToInt32(Key.GetValue("NoOST"));
if (Value == 3)
{
MessageBox.Show("yes");
}
else
{
MessageBox.Show("no");
}
}
else
{
MessageBox.Show("not present");
}
}
catch (Exception)
{
throw;
}
}
}
}