I have an Editable ComboBox. The user enters text and presses a Save button. Their text is turned into a string.
I need it at Run Time to Create a new User Setting to the app.config with the name of their string. (I think this part works now).
Then another ComboBox's Selected Item is saved to the Setting. (Object reference not set error).
This is to create a custom preset that will save each control state, checkboxes, textboxes, etc. in the program.
// Control State to be Saved to Setting
Object comboBox2Item = ComboBox2.SelectedItem;
// User Custom Text
string customText = ComboBox1.Text;
// Create New User Setting
var propertyCustom = new SettingsProperty(customText);
propertyCustom.Name = customText;
propertyCustom.PropertyType = typeof(string);
Settings.Default.Properties.Add(propertyCustom);
// Add a Control State (string) to the Setting
Settings.Default[customText] = (string)comboBox2Item;
At this part I get an error.
Settings.Default[customText] = (string)comboBox2Item;
Exception:Thrown: "Object reference not set to an instance of an object."
I have tried setting ComboBox1.Text to an Object instead of string, with same error. The text and string is also not null.
Object customText = ComboBox1.Text;
Here's a visual of what I'm trying to do
Original Answer:
I haven't tried adding a new setting to the file but i have had to update it. Here is some code that I use to save and retrieve the saved changes to the file. I know it doesn't directly answer the question but should point you in the right direction as to what classes to look at and use.
I'll try to update to directly answer this question once I get some breathing time.
public static void UpdateConfig(string setting, string value, bool isUserSetting = false)
{
var assemblyPath = AppDomain.CurrentDomain.BaseDirectory;
var assemblyName = "AssemblyName";
//need to modify the configuration file, launch the server with those settings.
var config =
ConfigurationManager.OpenExeConfiguration(string.Format("{0}\\{1}.exe", assemblyPath, "AssemblyName"));
//config.AppSettings.Settings["Setting"].Value = "false";
var getSection = config.GetSection("applicationSettings");
Console.WriteLine(getSection);
var settingsGroup = isUserSetting
? config.SectionGroups["userSettings"]
: config.SectionGroups["applicationSettings"];
var settings =
settingsGroup.Sections[string.Format("{0}.Properties.Settings", assemblyName)] as ClientSettingsSection;
var settingsElement = settings.Settings.Get(setting);
settings.Settings.Remove(settingsElement);
settingsElement.Value.ValueXml.InnerText = value;
settings.Settings.Add(settingsElement);
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
Edited Answer:
I did a quick google search and found an accepted answer on the MSDN forum.MSDN question. You have to call save on the properties class in order for the add to take affect. Think of a database transaction, until you call commit, it doesn't take effect.
So what appears to be missing in your code is: Properties.Settings.Default.Save(); which should be the very next line after your Settings.Default.Properties.Add(propertyCustom);
Related
I am using the vanilla library of keepass simply by adding the .exe file to my project.
From my code I am accessing PwDatabase like so:
var dbpath = #"\\MyPath\To\PersonalVault\PersonalVault.kdbx";
var masterpw = "myPassword";
var ioConnInfo = new IOConnectionInfo { Path = dbpath };
var compKey = new CompositeKey();
compKey.AddUserKey(new KcpPassword(masterpw));
var db = new KeePassLib.PwDatabase();
db.Open(ioConnInfo, compKey, null);
From there I want to access and read the custom string field that I have previously manually added from the Advanced tab of entry on the UI:
var entry = db.RootGroup.FindEntry(new KeePassLib.PwUuid(KeePassLib.Utility.MemUtil.HexStringToByteArray("97A51FE92F700D4FB665DC6AA7C9D67D")), true);
var customString = entry.Strings.Where(lookingFor => lookingFor.Key.Equals("customString")).FirstOrDefault().Value;
However I end up with a null value here.
Any suggestion on how I can read this or is it simply not exposed through the vanilla KeePass.exe?
The "Entry" tab on KeePass.exe UI shows data stored in PwEntry (KeePass source code is downloadable here) with reserved key names. Reserved key names are shown in code sample below.
The "Advanced" tab on KeePass.exe UI stores strings with custom key names. So, when reading them in code, entry.Strings.ReadSafe("myCustomString") works (assuming that a custom string with that key name is present in the password entry). Below is the code that I tried and it works.
var pwUuid = new KeePassLib.PwUuid(KeePassLib.Utility.MemUtil.HexStringToByteArray("F3A8DC6E93571944B485AA947C68FB5E"));
var entry = db.RootGroup.FindEntry(pwUuid, true);
// Reserved key names ("Entry" tab on KeyPass.exe)
Console.WriteLine($"Title : {entry.Strings.ReadSafe("Title")}");
Console.WriteLine($"UserName: {entry.Strings.ReadSafe("UserName")}");
Console.WriteLine($"Password: {entry.Strings.ReadSafe("Password")}");
Console.WriteLine($"URL : {entry.Strings.ReadSafe("URL")}");
Console.WriteLine($"Notes : {entry.Strings.ReadSafe("Notes")}");
// Custom key names ("Advanced" tab on KeePass.exe)
Console.WriteLine($"myCustomString: {entry.Strings.ReadSafe("myCustomString")}");
This also made me wonder about clashes between reserved and custom key names. As expected KeePass.exe UI does show an error if I try to create a custom key with a reserved key name.
I am trying to add settings to Settings file dynamically. I use code below:
public PathSourceDir(int id)
{
InitializeComponent();
_id = id;
SettingsProperty property = new SettingsProperty(Properties.Settings.Default.Properties["baseSetting"]);
property.Name = "dynamicSettingName" + _id.ToString();
property.DefaultValue = _id.ToString();
Properties.Settings.Default.Properties.Add(property);
Properties.Settings.Default.Save();
//Read stored value
var dynamicSetting = Properties.Settings.Default["dynamicSettingName" + _id.ToString()];
}
Code runs, however if I comment code lines where new property is created and Settings are saved, and run again, I get an exception:
System.Configuration.SettingsPropertyNotFoundException: 'The settings
property 'dynamicSettingName6' was not found.
Meaning that setting previously was not saved in the file. However code was executed before also with id=6. Could you please advise what is wrong?
I´d like to update a label that was applied to a branch programmatically. While searching for a method that would do the trick, I found the VersionControlServer.CreateLabel()-Method. https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.versioncontrolserver.createlabel(v=vs.120).aspx
I tried it like this, but it doesn´t seem to work:
TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(new Uri(tfsuri));
var vcs = tfs.GetService<VersionControlServer>();
string labelscope = "$/MyProjects/" + machinenumber;
var specifiedBranch = vcs.QueryLabels(label, labelscope, null, true);
string branch = specifiedBranch[0].Items[0].ServerItem;
ItemSpec newItemSpec = new ItemSpec(branch, RecursionType.Full);
string newItem = specifiedBranch[0].Items[0].ServerItem;
newItemSpec.Item = newItem;
VersionSpec versSpec = new LabelVersionSpec(label);
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, false);
LabelItemSpec[] newLabelItemSpecList = new LabelItemSpec[1] { newLabelItemSpec };
string labelOwner = vcs.AuthenticatedUser;
string labelName = label.Insert(6, "ed");
VersionControlLabel labelToUpdate = new VersionControlLabel(vcs, labelName, labelOwner, branch, null);
vcs.CreateLabel(labelToUpdate, newLabelItemSpecList, LabelChildOption.Replace);
What I exactly want to do is to update the old label name from "Deploy" to "Deployed". I know how to do this with TF.exe, but it should work without TF.exe.
Does anyone has an code example how to use the CreateLabel()-Methode for updateting a existing label?
-- UPDATE --
I changed
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, true);
to
LabelItemSpec newLabelItemSpec = new LabelItemSpec(newItemSpec, versSpec, false);
Now a new Label is created for the same branch. I cann delete the old label with VersionControlServer.DeleteLabel. Then I get the result that I was looking for, But I still would like to know how to update correctly.
Renaming Labels is not supported by TFS. You can only create a new Label based on the old Label you want to remove. Details please see this link: Rename Label in Team Foundation Server
You could also verify this in VersionControlLabel Class.
Name Gets the name of this label.
It's only be able to get the name not set the name.
Update
For the LabelChildOption options in VersionControlServer::CreateLabel Method , there are three options:
Replace: Any item that you specify in your request that’s already in the label will be replaced by what you have specified.
Anything that’s not in the label already will be added to the
label, and existing items that aren’t modified by your request will
remain as they were.
Merge: Leave unmodified items that are in your request but that already exist in the label. Any item in your request that’s not
already in the label will be added to the label, and existing items
in the label that aren’t specified in your label will remain
unchanged.
Fail: Labels have the notion of a scope. The Fail option says that the call to create or update the label should fail if there is
at least one label by the same name that exists at a scope that would
be below the scope of the new label.
The update label only means update the itemSpecs parameter which means the item specs included in the label. So it's used to update the ItemSpec for the label – Which Files, Folder we want to Label.
I'm a novice programmer using Visual C# 2010. I am trying to dynamically (during run time) create a new SettingsProperty and add it to the Settings.Default.Properties collection in my application (new settings). These properties are essentially user defined views (stored in a string) that I want to save for later reloading. I have tried using the code below but it doesn't seem to be working. When I close the application, the newly created and saved properties are gone.
private void button6_Click(object sender, EventArgs e)
{
string connectionText = maskedTextBox3.Text;
string vusipsText = maskedTextBox2.Text;
string chartText = maskedTextBox1.Text;
string[] settingsArray = { connectionText, chartText, vusipsText };
string saveSettings = String.Join(":", settingsArray);
//configure new property
SettingsProperty property = new SettingsProperty("kri");
property.DefaultValue = saveSettings;
property.IsReadOnly = false;
property.PropertyType = typeof(string);
property.Provider = Settings.Default.Providers["LocalFileSettingsProvider"];
property.Attributes.Add(typeof(System.Configuration.UserScopedSettingAttribute), new System.Configuration.UserScopedSettingAttribute());
Settings.Default.Properties.Add(property);
//Properties.Settings.Default.Reload();
Settings.Default.Save();
ActiveForm.Close();
}
How can I get around this issue?
Thanks
Your code looks fine, but the Settings doesn't know about your property next time you load the data. If you define your property again (at load time) the value should be available. This is a working sample out of a loop that I use to save enums:
If My.Settings.Properties(settingName) Is Nothing Then
Dim p = New Configuration.SettingsProperty(settingName)
p.Provider = My.Settings.Providers("LocalFileSettingsProvider")
p.Attributes.Add(GetType(Configuration.UserScopedSettingAttribute), _
New Configuration.UserScopedSettingAttribute())
p.PropertyType = GetType(SampleEnum)
My.Settings.Properties.Add(p)
If My.Settings(settingName) Is Nothing Then
My.Settings(settingName) = SampleEnum.DefaultValue
End If
End If
Always run the code at startup to create the property and for the first time to create the value, too.
I have a path to an setting "Properties.Settings.Default.Password1" and "Properties.Settings.Default.Password2".
Now I want to use one of these paths. I use the following code:
If (certain condition)
{
kindOfVariable passwordPath = Properties.Settings.Default.Password1
}
else
{
kindOfVariable passwordPath = Properties.Settings.Default.Password2
}
Well, I know that the password is a string, thats no problem but I want the path.
But what kind of variable do I have to use? Or is there another way to do this?
Normally you would save a new value like this:
Properties.Settings.Default.passwordPath = "New Password";
Properties.Settings.Default.Save();
What I wanna do with the path is to give a new value on that path, so for example
passwordPath = "New Password";
Properties.Settings.Default.Save();
If you're using C# 3.0 or later, var is a good choice.
That causes the compiler to automatically infer the type of a local variable from the expression on the right side of its initialization statement.
if (certain condition)
{
var Passwordpath = Properties.Settings.Default.Password1
}
else
{
var Passwordpath = Properties.Settings.Default.Password2
}
Otherwise, hover over the right side of the initialization statement (Password1, for example) in the development environment. You should see a tooltip that gives away its type. Use that one.
(Off-topic suggestion: Name your local variables using camelCasing, as recommended by Microsoft's C# and .NET code style guidelines. The Passwordpath variable should really be passwordPath.)
Edit to answer updated question:
The simplest way is just to reverse the logic. Rather than trying to store the address of the property and set it to a new value later, just store the new value in a temporary variable, and use it to set the property directly. Maybe it would be easier to explain with some code...
// Get the new password
string password = "New Password";
// Set the appropriate property
if (certain condition)
{
Properties.Settings.Default.Password1 = password;
}
else
{
Properties.Settings.Default.Password2 = password;
}
// Save the new password
Properties.Settings.Default.Save();
You could always use var - that makes the compiler decide the actual type for you (at compile time, so IntelliSense etc. can still take advantage of static typing).
var Passwordpath = Properties.Settings.Default.Password1
I'm not really sure what are you trying to do though.