RegistryKey.GetValue(..) returns null - c#

I'm trying to retrieve the value of a (REG_SZ) registry key and write it to a string. However this code seems to think the key is null or doesn't exist and won't allow me to GetValue() it. Here's the code I'm using to retrieve the value.
string s64BasePath = "SOFTWARE\\Wow6432Node\\Xactware\\";
private void versionSelectorBox_SelectedIndexChanged(object sender, EventArgs e)
{
showForms();
sVersionSelected = versionServerBox.Text;
if (b64Bit == true)
{
string sRKey = s64BasePath + sVersionSelected + "\\"; //Reads as SOFTWARE\\Wow6432Node\\Xactware\\Xactimate28\\
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(sRKey))
{
if (key != null)
{
//label1.Text = "Test."; //Reaches this point just fine
Object o = key.GetValue("Location");
if (o != null)
{
//label1.Text = "Test."; //Does not reach this point, o = null?
sLocationKey = Convert.ToString(o);
}
}
}
//label1.Text = sLocationKey;
}
Here is what the registry looks like. As you can see the Location key exists in the path provided. However the code isn't dropping into the inner most if statement, acting like the o object is null.
Thanks in Advance.

I will be honest, without having Xactimate installed, I do not have the same registry entry you do so I used Skype as my key.
I changed one thing, I changed it from \ to using the literal string flag.
FYI, I ran in this in LINQPad so ignore the 'dump' commands
var test = #"SOFTWARE\Wow6432Node\Skype\Phone";
var reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(test);
reg.Dump("OpenSubKey: ");
var result = reg.GetValue("SkypeFolder");
result.Dump("GetValue: ");
Here are the results from the two dumps

Related

Is there any way in which I can clean up my code by assigning a linq query to a single variable of type string?

I made a login system for a project that I have been working on and while it works, it doesn't seem to look like the most efficient way I could do it. This is a WPF/C# project linked to an SQLite database that uses LINQ for queries. Ideally, I would like the query to spit out a single variable of type string so that I can manipulate it and compare it with what the user enter.
List<Engineer> engineers;
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
string username = UsernameField.Text;
string password = PasswordField.Password.ToString();
string hashedPasswordString = "";
string saltString = "";
//establishes connection
using (SQLiteConnection conn = new SQLiteConnection(App.engineerDatabasePath))
{
engineers = conn.Table<Engineer>().ToList();
//Queries for a list containing the respective hashed passwords. This will only contain one password since the emails are unique
var hashedpasswordlist = from c in engineers
where c.Email == username
select c.Password;
//Take the password in the list and assign it to a string variable that can be compared
foreach (var item in hashedpasswordlist)
{
hashedPasswordString = item;
}
//Queries for a list containing the respective salts. This will only contain one salt since the emails are unique
var saltlist = from c in engineers
where c.Email == username
select c.Salt;
//Take the salt in the list and assign it to a variable to the password input, creating a hash value that is to be assigned
foreach (var item in saltlist)
{
saltString = item;
}
//Confirmation that the implementation works as it should
if (GenerateSHA256Hash(password, saltString) == hashedPasswordString)
{
MessageBoxResult deleteConfirmation = MessageBox.Show("IT WORKS!", "Grats", MessageBoxButton.YesNo, MessageBoxImage.Warning);
}
}
//Allows you to log in regardless of whether your login details are correct. This is the case for testing purposes.
MainWindow MainWindow = new MainWindow();
MainWindow.Show();
this.Close();
}
Here is the GenerateSHA256Hash method and the ByteArrayToHexString method
public string GenerateSHA256Hash(string input, string salt)
{
byte[] bytes = Encoding.UTF8.GetBytes(input + salt);
System.Security.Cryptography.SHA256Managed sha256hashtring = new System.Security.Cryptography.SHA256Managed();
byte[] hash = sha256hashtring.ComputeHash(bytes);
return ByteArrayToHexString(hash);
}
public static string ByteArrayToHexString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
{
hex.AppendFormat("{0:x2}", b);
}
return hex.ToString();
}
If you're wanting to retrieve the actual password and compare it to what the user entered, you shouldn't do that. Password should not be stored in a retrievable format in the database for security reasons, so hashing the entered password and comparing it to the hash in the database is much more secure (and not much less efficient) than comparing directly.
That said, you could retrieve both the salt and the hash in one step, and use SingleOrDefault() since you only expect one item:
//Queries for a list containing the respective hashed passwords. This will only contain one password since the emails are unique
var saltedPassword = (from c in conn.Table<Engineer>()
where c.Email == username
select new {c.Password, c.Salt}).SingleOrDefault();
//TODO: Add handling for when password is not found (saltedPassword is null)
hashedPasswordString = saltedPassword.Password;
saltString = saltedPassword.Salt;
You're querying Engineer table, so it's obvious that the return would be Engineer object, and since you're querying for the same object, you need to query the table, get the results as Engineer object, then navigate through its properties.
There is no need to query multiple times, just once is enough.
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
// Basic null handling
if(string.IsNullOrEmpty(UsernameField.Text)) { throw new ArgumentNullException(nameof(UsernameField.Text)); }
if(string.IsNullOrEmpty(PasswordField.Password?.ToString())) { throw new ArgumentNullException(nameof(UsernameField.Text)); }
//establishes connection
using (SQLiteConnection conn = new SQLiteConnection(App.engineerDatabasePath))
{
// get the Engineer object
var engineer = conn.Table<Engineer>().FirstOrDefault(c => c.Email.Equals(UsernameField.Text, StringComparison.OrdinalIgnoreCase));
// generate the password
var password = GenerateSHA256Hash(PasswordField.Password.ToString(), engineer.Salt);
//Confirmation that the implementation works as it should
if (engineer.Password.Equals(password))
{
MessageBoxResult deleteConfirmation = MessageBox.Show("IT WORKS!", "Grats", MessageBoxButton.YesNo, MessageBoxImage.Warning);
}
}
//Allows you to log in regardless of whether your login details are correct. This is the case for testing purposes.
MainWindow MainWindow = new MainWindow();
MainWindow.Show();
this.Close();
}
You can use your first line and build on it
engineers = conn.Table<Engineer>().ToList();
var engineer = conn.Table<Engineer>().First(x=>x.Email.Equals(username));
var password = conn.Table<Engineer>().First(x=>x.Email.Equals(username)).Password;
var saltString = engineer.Salt
var pw = engineer.Password
So I took #D Stanley 's method and combined it with #iSR5 's lack of variables to create the following:
using (SQLiteConnection conn = new SQLiteConnection(App.engineerDatabasePath))
{
var saltedPassword = (from c in conn.Table<Engineer>()
where c.Email == UsernameField.Text
select new { c.Password, c.Salt }).SingleOrDefault();
if (saltedPassword != null)
{
if (GenerateSHA256Hash(PasswordField.Password.ToString(), saltedPassword.Salt) == saltedPassword.Password)
{
MessageBox.Show("Correct credentials, click ok to continue", "Access Granted", MessageBoxButton.OK);
MainWindow MainWindow = new MainWindow();
MainWindow.Show();
this.Close();
}
}
else
{
MessageBox.Show("Incorrect credentials", "Error", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
It seems that when an email is not found, saltedPassword will end up being null so I also wrote an if statement in order to make sure that the program doesn't crash when that happens. I was thinking of venturing into lambda expressions and throwing null exceptions but I am still quite new to programming and lack knowledge in those areas.
Thanks guys :)

C#: What is the reason of not detecting if testcase failed

I am trying to detect if my testcase failed that it should do some process which I have mentioned it in my code below. I am successfully able to detect when my testcase passed.
I have added my code. My code here does is to navigate to google homepage if it passed then I should get a txt file with a "[MethodName] - Passed.txt" with a text in it Passed. Same for fail.
[Test]
public void Initialize()
{
PropertiesCollection.driver = new TWebDriver();
LoginPageObject objLogin = new LoginPageObject();
string pathfile = #"file location";
string sheetName = "Login";
var excelFile = new ExcelQueryFactory(pathfile);
var abc = from a in excelFile.Worksheet(sheetName).AsEnumerable()
where a["ID"] == "3"
select a;
foreach (var a in abc)
{
PropertiesCollection.driver.Navigate().GoToUrl(a["URL"]);
}
foreach (var a in abc)
{
objLogin.Login(a["uname"], a["paswd"]);
}
StackFrame stackFrame = new StackFrame();
MethodBase methodBase = stackFrame.GetMethod();
string Name = methodBase.Name;
GetFiles(Name);
}
public void GetFiles(string testcase)
{
if ((TestContext.CurrentContext.Result.Status == TestStatus.Failed) || (TestContext.CurrentContext.Result.State == TestState.Failure) || (TestContext.CurrentContext.Result.State == TestState.Ignored) || (TestContext.CurrentContext.Result.State == TestState.Error))
{
string destpath = (#"destination location");
File.WriteAllText(Path.Combine(destpath, testcase + " - Failed" + ".txt"), "Failed");
}
else
{
string destpath = (#"destination location");
File.WriteAllText(Path.Combine(destpath, testcase + " - Passed" + ".txt"), "Passed");
}
}
Here, only else condition is identified but not with if condition.
Question: Can anyone identify what part I am missing for fail test case.
Note:
Please forgive me if I have not explained properly. If you donot understand please ask question.
For each part is actually an error. If there is an error it should create a txt file as per my code in GetFiles(string testcase) which I am unable to do so.
I am using Nunit to identify whether my test case passed or fail. So if testcase passes or fails a text is created mentioning that to keep a record of my failed test case.
Appreciate your help.
If a test fails, the [Test] method is terminated, and the rest of the method never run. So, if your test were to fail mid-way through, GetFiles() would never be called.
You probably mean to run GetFiles() as a [TearDown] to achieve what you're trying to do.
As an aside, I'd recommend doing:
TestContext.CurrentContext.Result.Status != TestStatus.Success
rather than you current if - as you seem to have found already, there are many different varieties of failure!
It looks like you have a typo. Your if statement can never be true as written. You want an 'or' instead of an 'and'
if ((TestContext.CurrentContext.Result.Status == TestStatus.Failed) ||
(TestContext.CurrentContext.Result.State == TestState.Failure) ||
(TestContext.CurrentContext.Result.State == TestState.Ignored) || // <-- typo?
(TestContext.CurrentContext.Result.State == TestState.Error))
{

C# simple form index was outside the bounds of the array

I'm a student of programming and decided to make a simple program to practice.
It's a simple form, with name, date of birth, address etc, and it's being saved in a text file (I know there are easier ways, but I want to learn all of them and started with this one =) )
I have a button to search, by name, if the person is already saved and, if yes, it's supposed to fill the form with the data.
Here's an example of how it's saved:
38b7aa1f-0afb-4fe5-a8f6-40fe953eb1ca;Cindy;22/07/2005;111.111.111-11;22.222.222-2;33333-333;Testes;2112;05;Testando;Testadora;SP;cindy#gmail.com;(44)44444-4444;(55)55555-5555;True;True;Rose;26/05/1950;666.666.666-66;77.777.777-7
So, the name (Cindy) would be in and index[1] of an array.
The problem is this error: index was outside the bounds of the array
At this line: if (linha[1] == txtboxNome.Text)
I've searched on internet and kinda understood the problem, but still don't know how to fix it.
Can anybody help me, please?
How can I load my form properly?
Here's an print to help you "see" the program. Don't worry abou the layout, a few things get opacity 0 when running =)
http://i.imgur.com/jze16Pz.jpg
Thanks in advance =)
private void pesquisarNovoBtn_Click(object sender, RoutedEventArgs e)
{
var filePath = #"E:\Programação\WPF ConsultorioDentista\WPF ConsultorioDentista\bin\Debug\Pacientes.txt";
string[] resultado = null;
using (var abrirPacientes = System.IO.File.OpenText(filePath))
{
string lerPacientes = abrirPacientes.ReadLine();
while (lerPacientes != null)
{
var linha = lerPacientes.Split(';');
if (linha[1] == txtboxNome.Text)
{
resultado = linha;
break;
}
lerPacientes = abrirPacientes.ReadLine();
}
if (resultado == null)
{
MessageBox.Show("Paciente não encontrado.");
}
else
{
txtboxNome.Text = resultado[1];
txtboxData.Text = resultado[2];
txtboxCPF.Text = resultado[3];
txtboxRG.Text = resultado[4];
txtboxCEP.Text = resultado[5];
txtboxEndereco.Text = resultado[6];
txtboxNumero.Text = resultado[7];
txtboxCompl.Text = resultado[8];
txtboxBairro.Text = resultado[9];
txtboxCidade.Text = resultado[10];
txtboxUF.Text = resultado[11];
txtboxEmail.Text = resultado[12];
txtboxCel.Text = resultado[13];
txtboxTelRes.Text = resultado[14];
//checkBoxClinico.IsChecked = resultado[15];
//checkBoxOrto.IsChecked = resultado[16];
txtboxNomeResp.Text = resultado[17];
txtboxNascResp.Text = resultado[18];
txtboxCPFResp.Text = resultado[19];
txtboxRGResp.Text = resultado[20];
}
abrirPacientes.Close();
}
This is where you need to "Step Through" the application. Set a Breakpoint (F9) on the If STatement :
if (linha[1] == txtboxNome.Text)
{
resultado = linha;
break;
}
And mouse over to look at the values contained in the linha array.
Most likely you have a header in the first row of your file and it's not splitting.

using strings.xml in Mono for Android

I am using android SDK with Microsoft VS2010 C#. I want to use string values from my /resources/values/strings file in my C# code. Here is a piece of code that illustrates what I want to do. I am not getting the string value. I know that the resource id is an int, but what I need is the actual string value behind that id.
void vx2OkButton_Click(object sender, EventArgs e)
{
Log.Info(LOG_TAG, "Hello from OkButton|Enter()button"); // also used as Enter button
strVx20kButtonText = vx2OkButton.Text.ToString();
mDwnLdCodeEnteredByUser = vxxDwnldCodeEntered.Text.Trim();
string strDwnldCodeOut = mActCode.Bad.ToString();
if(strVx20kButtonText == Resource.String.Enter.ToString())
{
if (mDwnLdCodeEnteredByUser.Length < 1)
{
vxxSystemMsgBox.SetText(Resource.String.FieldRequried_);
m_txvEnterDwnLdCode.SetTextAppearance(this,Resource.Color.Red);
return;
}
// verify the dwnldcodeenter by the user matches the assigned to user when at the time the downloaded the app
mDwnLoadStatus = VerifyDwnLoadCode(mDwnLdCodeEnteredByUser);
if (mDwnLoadStatus == mDwnLdStatCode.BadDwnLdCode.ToString())
{
vxxSystemMsgBox.SetText(Resource.String.InvalidValueEntered);
m_txvEnterDwnLdCode.SetTextAppearance(this, Resource.Color.Red);
return;
}
mActionCD = mActCode.Ok.ToString();
vx2OkButton.SetText(Resource.String.OkButtonText);
vxxSystemMsgBox.SetText(Resource.String.ThanksPressOkButton);
m_txvEnterDwnLdCode.SetTextAppearance(this,Resource.Color.White);
return;
}
As you noticed, Resource.String.Enter is an integer generated for you that you can use to access the string resource. You can access it using the Android.Content.Res.Resources.GetString() method:
string enter = Resources.GetString(Resource.String.Enter);

How to update data in hypertable

I have written some C# code to store data into hypertable database. However I don't know how to update the data.
Below is what I have done:
Hypertable b = new Hypertable();
b.Write("1", "value1");//this line is for writing to database
b.Write("1", "value111");//this line is for updating the value whose key = "1"
and my Write function is:
public override bool Write(string key, string value)
{
try
{
using (IContext context = Context.Create(connectionString))
using (IClient client = context.CreateClient())
{
using (INamespace ns = client.OpenNamespace("Test", OpenDispositions.OpenAlways | OpenDispositions.CreateIntermediate))
{
using (ITable table = ns.OpenTable(tableName))
{
using (ITableMutator mutator = table.CreateMutator())
{
Key _key = new Key { Row = key, ColumnFamily = "vvalue" };
mutator.Set(_key, Encoding.UTF8.GetBytes(value));
}
}
}
}
return true;
}
catch (Exception e)
{
Console.WriteLine("Hypertable--Write--{0}", e.Message);
return false;
}
}
So my update is simply write again with the same key but different value. However after updating I do a read of that key and value, it is supposed to show the new key and value (key = "1" and value = "value111") but it doesn't, it just shows the old key and value (key = "1" and value = "value1")
I don't know why this happens. Any tips will be appreciated. Thanks.
You can try adding mutator.Flush() to your innermost using block, although it should be called automatically when mutator goes out of scope...

Categories