Access application setting by name - c#

In application settings I have a group of settings called "Name01", "Name02" and so on.
I have a list of strings "Name01", "Name16", "NameWhatever"..
How to check if there is a setting called "NameXX" in Settings.Default ?

You could test it like this:
var x = Properties.Settings.Default.Properties["NameXX"];
if(x != null) {
//....
}

Related

What parameter i have to assign inside my variable so i can start it from my Main?

im new to C# and Tia Openness and have an problem. I dont know what parameter goes inside my ImportSingleTextList();.Its an example from Siemens but there is never mentioned how to call it inisde the main. That is my code.
private static void ImportSingleTextList(HmiTarget hmitarget)
{
TextListComposition textListsComposition = hmitarget.TextLists;
IList<TextList> importedTextLists = textListsComposition.Import(new FileInfo(#"D:\SamplesImport\myTextList.xml"), ImportOptions.Override);
}
I guess you have to look into your HmiTarget exactly. Is it a class, then you should instantiate a first instance of it; what constructor does this class have - with or without parameters? Click on HmiTarget and see what input it expects.
I guess you class has some kind of enumerable hmitarget.TextLists that you have to fill or get too.
Presumably you have a Project instance. You have to drill down from Project->Device->DeviceItem(->DeviceItem) until you find a DeviceItem that can provide a SoftwareContainer service. It may be that all such DeviceItems reside at the first level below Device; I haven't checked. Anyway, here's a method I wrote that searches the first and second DeviceItem levels:
public static HmiTarget GetHmiTarget(Device hmiDevice)
{
//search first level of DeviceItems
foreach (DeviceItem di in hmiDevice.DeviceItems)
{
SoftwareContainer container =
di.GetService<SoftwareContainer>();
if (container != null)
{
HmiTarget hmi = container.Software as HmiTarget;
if (hmi != null)
return hmi;
}
//search second level of DeviceItems
foreach (DeviceItem devItem in di.DeviceItems)
{
SoftwareContainer subContainer = devItem.GetService<SoftwareContainer>();
if(subContainer != null)
{
HmiTarget hmi = subContainer.Software as HmiTarget;
if (hmi != null)
return hmi;
}
}
}
return null; //nothing was found at the first or second levels
}
to get the Device, you can use PROJECT.Devices.Find(NAME) where PROJECT is your TIA portal project instance, and NAME is the string name of your HMI device.

.NET Core: why is the result of ConfigurationBuilder["Key"] null when.ConfigurationBuilder.GertChildren has elements?

I have created a windows service using .NET Core 2.1 and added a set of environment variables:
Application_key1 = Key1
Application_key2 = Key2
Application_key3 = Key3
Application_key4 = Key4
Application_key5 = Key5
I am accessing it through:
var configuration = new ConfigurationBuilder().AddEnvironmentVariables("Application_").Build();
return new ApplicationSettings
{
Key = configuration["key1"],
//Get the rest of the keys
};
Works great when I debug using my IDE. The environment variables get pulled out of my user settings just fine. When I run, the service, it doesn't pull the data reporting back a null reference exception. I then added the environment variables to the registry in HKLM/System/CurrentControlSet/services/{Service} as a REG_MULTI_SZ:
I verified that the environment variables are correctly being pulled from the registry:
if (configuration == null)
{
eventLog.WriteEntry("Configuration is null", EventLogEntryType.Warning);
}
else
{
foreach (var child in configuration.GetChildren())
{
eventLog.WriteEntry($"Key: {child.Key} Value: {child.Value}", EventLogEntryType.Warning);
}
}
It displays correctly in the event viewer. However, when I try to access the data:
var a = configuration["key1"]
the result is null. I don't really have a clue where to go next
You have to remove the spaces between the equals signs for the environment variables to the registry:
Key1 = Value1
etc.
becomes
Key1=Value1
etc.

changing webservice calls to test or prod via radio button

I have created a vsto application that calls a webservice. everything seems to work just fine, but i would like to extend the functionality to call the test service version of my production service.
code snippet that works that calls my test service.
//how do i change here to be dynamic?
npfunctions.finfunctions service = new npfunctions.finfunctions();
var Results = service.ValidateFoapal(index.ToArray(), fund.ToArray(), org.ToArray(), prog.ToArray(), acct.ToArray(), row.ToArray());
/* if their are no error then return a "Y" for success.*/
if (Results.Count() < 0) { return LocallErrorInd; }
/*well we have encountered errors lets adjust the spreadsheet to notify the user.*/
else{
//REMOVE ANY VISUAL ERRORS
Microsoft.Office.Interop.Excel.Range delRng = Globals.ThisAddIn.Application.Range["R:S"];
delRng.Delete(XlDeleteShiftDirection.xlShiftToLeft);
for (int i = 0; i < Results.Count(); i++)
{//set the error indicator
LocallErrorInd = "Y";
//account error:
if (Results[i].FVALJOR_FUND_WARNING == "Y")
{
Microsoft.Office.Interop.Excel.Range WrkRng = Globals.ThisAddIn.Application.Range[Results[i].FVALJOR_ROW];
WrkRng.Offset[0, 17].Value2 = "Invalid Account";
}
i have seen this post How can I dynamically switch web service addresses in .NET without a recompile?
but it requires me to change my config file i would really like to change the service variable to point to another location based on a variable and basically flip from prod to test on my command. as i see it right now it appears that i would have to duplicate the code but i know there has got to be a better way. i like it to be something like.
if (TestBtn.Checked == true)
{
npfunctions.finfunctions service = new npfunctions.finfunctions();
Results = service.ValidateFoapal(index.ToArray(), fund.ToArray(), org.ToArray(), prog.ToArray(), acct.ToArray(), row.ToArray());
}
if (PrdBtn.Checked == true)
{
prdFunctions.finfunctions service = new prdFunctions.finfunctions();
Results = service.ValidateFoapal(index.ToArray(), fund.ToArray(), org.ToArray(), prog.ToArray(), acct.ToArray(), row.ToArray());
}
/* if their are no error then return a "Y" for success.*/
if (Results.Count() < 0) { return LocallErrorInd; }
Does your service object not have a URL property?
2nd option, you can use a config file transformation so you do not need to manually change the settings(after the intial setup of course).
npfunctions.finfunctions service = new npfunctions.finfunctions();
if (TestBtn.Checked == true)
{
service.url="<testurl>";
}
else
{
service.url="<produrl>";
}
Results = service.ValidateFoapal(index.ToArray(), fund.ToArray(), org.ToArray(), prog.ToArray(), acct.ToArray(), row.ToArray());
In our test client we have a drop-down to select between dev or tst. We also have buttons to select proxy or net.tcp. (We have many different people using our service using different methods).
In the app.config the names of the endpoints correlate with different selectable options.
Eg. name="BasicHttpBinding_IInterface_PROXY_DEV"
You can then dynamically build up which endpoint you would like to use and go with that.

Custom workflow activity errors 'Value cannot be null'

I'm creating a custom workflow activity in VS2010 targeting .NET 3.5. The DLL is actually being used in a Microsoft System Center Service Manager custom workflow, but I don't think that is my issue.
I have a public string property, that the user types in the string of what the activity should use. However, when the WF runs, it errors out 'value cannot be null'. I want to target if it is my code or something else.
When we drag my custom activity onto the designer, I'm able to type in the text of the string on the designer for that property.
public static DependencyProperty ChangeRequestStageProperty = DependencyProperty.Register("ChangeRequestStage", typeof(String), typeof(UpdateChangeRequestStage));
[DescriptionAttribute("The value to set the ChangeRequestStage Property in the ChangeRequest Extension class.")]
[CategoryAttribute("Change Request Extension")]
[BrowsableAttribute(true)]
[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
public String Stage
{
get { return ((String)(base.GetValue(UpdateChangeRequestStage.ChangeRequestStageProperty))); }
set { base.SetValue(UpdateChangeRequestStage.ChangeRequestStageProperty, value); }
}
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
EnterpriseManagementGroup emg = CreateEMG();
//System.WorkItem.ChangeRequest Extension - ClassExtension_928bec0a_cac4_4a0a_bd89_7146c9052fbe
ManagementPackClass mpcChangeRequest = emg.EntityTypes.GetClass(new Guid("8c6c6057-56ad-3862-47ec-dc0dde80a071"));
//System.WorkItemContainsActivity Relationship Class
ManagementPackRelationship workItemContainsActivityRelationship = emg.EntityTypes.GetRelationshipClass(new Guid("2DA498BE-0485-B2B2-D520-6EBD1698E61B"));
EnterpriseManagementObject changeRequest = null;
//Loop thru each emo (Change Request in this case), and assign it. There will never be more than 1 emo returned
foreach (EnterpriseManagementObject obj in emg.EntityObjects.GetRelatedObjects<EnterpriseManagementObject>(executionContext.ContextGuid, workItemContainsActivityRelationship, TraversalDepth.OneLevel, ObjectQueryOptions.Default))
{ changeRequest = obj; }
EnterpriseManagementObjectProjection emop = new EnterpriseManagementObjectProjection(changeRequest);
if (emop != null)
{ emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage; }
emop.Commit();
return base.Execute(executionContext);
}
Since it is getting a 'value cannot be null' error, I'm guessing it's on this line:
emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage;
I'm going to test and see if hardcoding a value works or not. Any ideas?
enter code here
try this
if (emop != null && emop.Object[mpcChangeRequest, "ChangeRequestStage"] != null)
emop.Object[mpcChangeRequest, "ChangeRequestStage"].Value = Stage
I didn't want to leave this question wide open, so I'm updating it as to how I resolved this (a long time ago).
Rather than working with an EnterpriseManagementObjectProjection (emop), I worked with a standard EnterpriseManagementObject (emo). From there, I was able to follow a similar format from above:
ManagementPackClass mpcChangeRequest = emg.EntityTypes.GetClass(new Guid("8c246fc5-4e5e-0605-dc23-91f7a362615b"));
changeRequest[mpcChangeRequest, "ChangeRequestStage"].Value = this.Stage;
changeRequest.Commit();

Can I modify [appname].exe.config without having to manually read/write the XMl?

I have created some settings in a C# application using .NET 3.5 and Visual Studio 2008 Express. I have a number of application-scoped settings which I would like to be able to modify from within the application - I can access them through Properties.Settings.Default but they are read only as expected. I do not want to have to make these become user-scoped settings as they should be application-wide. Is this possible without loading the XML and reading/writing from/to it myself?
I have seen examples using System.Configuration.ConfigurationManager.OpenExeConfiguration, but the config xml looks to be in a different format to that which I am using (is this from an older version?)
Thanks
Edit
I worked out that I can modify the values doing this, but it seems like a ridiculous hack.
Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
SettingElementCollection settingElements = ((ClientSettingsSection)config.GetSectionGroup("applicationSettings").Sections[0]).Settings;
SettingElement element = settingElements.Get("SettingName");
element.Value.ValueXml.InnerText = "new value";
config.Save(ConfigurationSaveMode.Modified, true);
OpenExeConfiguration (or any of the other ConfigurationManager methods) is the preferred entry point for most modifications to configuration files. Once you have a Configuration instance you should get the section you wish to modify and after the modifications call any of the ConfigurationManager.Save methods. However, it is impossible to retrieve the applicationSettings section this way.
There is no API for changing settings from the applicationSettings section in your app.config file. Only user-scoped settings can be changed this way.
So actually changing these settings can only be done by directly manipulating the app.config XML file.
Some confusion may occur because the indexed property from Properties.Settings.Default is actually writable. The following is perfectly legal:
Properties.Settings.Default["MySetting"] = "New setting value";
Properties.Settings.Default.Save();
However, the setting will not be saved.
You could also use the Windows Registry to store app-specific state. There are per-user and per-machine keys in the registry - either or both are available to you . For example, some people use the registry to store the location and size of the app window upon exit. Then when the app is restarted, you can position and size the window according to its last known size. This is a small example of the sort of state you can store in the registry.
To do it you would use different APIs for storage and retrieval. Specifically the SetValue and GetValue calls on the Microsoft.Win32.RegistryKey class. There may be libraries that are helpful in persisting complex state to the registry. If you have simple cases ( a few strings and numbers) then it is easy to just do it yourself.
private static string _AppRegyPath = "Software\\Vendor Name\\Application Name";
public Microsoft.Win32.RegistryKey AppCuKey
{
get
{
if (_appCuKey == null)
{
_appCuKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(_AppRegyPath, true);
if (_appCuKey == null)
_appCuKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(_AppRegyPath);
}
return _appCuKey;
}
set { _appCuKey = null; }
}
private void RetrieveAndApplyState()
{
string s = (string)AppCuKey.GetValue("textbox1Value");
if (s != null) this.textbox1.Text = s;
s = (string)AppCuKey.GetValue("Geometry");
if (!String.IsNullOrEmpty(s))
{
int[] p = Array.ConvertAll<string, int>(s.Split(','),
new Converter<string, int>((t) => { return Int32.Parse(t); }));
if (p != null && p.Length == 4)
{
this.Bounds = ConstrainToScreen(new System.Drawing.Rectangle(p[0], p[1], p[2], p[3]));
}
}
}
private void SaveStateToRegistry()
{
AppCuKey.SetValue("textbox1Value", this.textbox1.Text);
int w = this.Bounds.Width;
int h = this.Bounds.Height;
int left = this.Location.X;
int top = this.Location.Y;
AppCuKey.SetValue("Geometry", String.Format("{0},{1},{2},{3}", left, top, w, h);
}
private System.Drawing.Rectangle ConstrainToScreen(System.Drawing.Rectangle bounds)
{
Screen screen = Screen.FromRectangle(bounds);
System.Drawing.Rectangle workingArea = screen.WorkingArea;
int width = Math.Min(bounds.Width, workingArea.Width);
int height = Math.Min(bounds.Height, workingArea.Height);
// mmm....minimax
int left = Math.Min(workingArea.Right - width, Math.Max(bounds.Left, workingArea.Left));
int top = Math.Min(workingArea.Bottom - height, Math.Max(bounds.Top, workingArea.Top));
return new System.Drawing.Rectangle(left, top, width, height);
}
That code uses Microsoft.Win32.Registry.CurrentUser, and so it sets and retrieves user-specific app settings. If you are setting or retrieving machine-wide state, you want Microsoft.Win32.Registry.LocalMachine.

Categories

Resources