I've noticed that when changes are made to the assemblyinfo.cs the hash that is used to generate the user settings path is changed.
The screen grab shows the two directories that were created when I changed the copyright date from 2014 to 2015.
I don't imagine I will change other items in the assemblyinfo, but I'm pretty sure I will change the copyright if I do another release next year.
What's the best way to handle this?
Thanks in advance.
The ApplicationSettings class has an Upgrade method which will move the existing setting values to the new settings file.
What I have done previously is to have a boolean flag as a setting (named something like UpgradeRequired) which indicates if an upgrade to the settings is required. This is set to true as default.
When the application starts, check this flag and call the Upgrade() method if required (and then set the UpgradeRequired setting to false).
if (Settings.Default.UpgradeRequired)
{
Settings.Default.Upgrade();
Settings.Default.UpgradeRequired = false;
Settings.Default.Save();
}
Related
.NET Framework 4.5.2
OS: Windows Server 2012 RS Standard
IIS: 6.2
Application Pool: .NET CLR Version v.4.0.30319
Managed Pipeline Mode: Integrated
Spread.NET Version: 11.45.20183.0
NOTES:
The problem below ONLY occurs when hosted in IIS from our web-server. It does NOT occur when hosted through IIS Express (v.10.0.18362.1) on my local machine. I'm able to debug this problem while attaching to the running IIS process ID from Visual Studio on the web-server.
ISSUE:
We have some logic that checks for changes in the Datasource which has been bound to the FpSpread control. If changes are detected we then pull out the cell values where a delta exists. There are no problems with the code detecting changes; however, there is a problem with the result returned.
Example Code:
public static DataTable getUpdatedGrid(FpSpread FpExcel, DataTable beforeDt)
{
FpExcel.SaveChanges();
if (FpExcel.Columns.Count == beforeDt.Columns.Count)
{
// No added headers. HasChanges does not track added headers.
if (((DataSet)FpExcel.DataSource).HasChanges())
{
DataTable changes = ((DataSet)FpExcel.DataSource).GetChanges().Tables[0];
etc...
The code above works as expected, it detects the change and makes it to the "DataTable changes" statement. The only problem is the value doesn't reflect the change the user made if that change involved changing the case. For example if the user tries to change a cell from "Click" to "click" the "HasChanges" condition will evaluate to "true"; however, the value remains "Click."
Below is a screenshot where the user attempted to change a cell value from "False" to "false". As you can see the case was preserved and not altered.
Again this only happens when the user tries to change the case of the cell value. Changing the value to something completely new works as expected.
As mentioned prior this only happens when hosted in IIS. Also the dataset bound to the control has "CaseSensitive" set to "true", as noted in the screenshot below:
We found the cause and a solution. After looking at additional instances of published code it turns out that this issue is somewhat intermittent, but it seemed to be fairly consistent when cell values equal True or False.
In our solution we are doing a lot of cell formatting prior to binding. Part of this logic involved setting the CellType for all columns to TextCellType, example below.
TextCellType txt = new TextCellType();
txt.AllowWrap = false;
txt.Multiline = true;
FpExcel.Columns[0, FpExcel.Columns.Count - 1].CellType = txt;
This code works but it gave us the false assumption that this "type" wouldn't be overridden by any other logic.
Apparently this assumption turned out to be somewhat incorrect as it seems like cells with a certain value intermittently have their changes suppressed, as mentioned above with True/False. This lead us to the DataAutoCellTypes method, which by default is True. By setting DataAutoCellTypes to False, using the statement below, our issue disappeared.
FpExcel.Sheets[0].DataAutoCellTypes = false;
I have gone through various question regarding Properties.Settings.Default.<My Settings Name> in stackoverflow and google, but none of them resolved my issue.
I want check whether my application is running for the first time or not, If first time then load particular form, else skip it.
I have a piece of code in My MDIParent Form load
bool isFirstRun = Properties.Settings.Default.IsFirstRun;
MessageBox.Show(Properties.Settings.Default.IsFirstRun.ToString());
if (isFirstRun){
OrganizationDetailsFrm childForm = new OrganizationDetailsFrm();
childForm.MdiParent = this;
childForm.Show();
Properties.Settings.Default.IsFirstRun = false;
Properties.Settings.Default.Save();
}
I checked and found that, every time isFirstRun value is false. When I checked in debug mode, I tried to add Properties.Settings.Default.<My Settings Name> in Add Watch, It show The name 'IsFirstRun' does not exist in the current context.
I have faced the same problem in my project.
Possible Reasons:
You may have multiple 'setting' files in your project.
Name space problem can also be the problem (I was unable to figured it out what is exactly is)
Possible Solutions:
Backup your project first.
Delete your existing settings file.
Make a new settings file in the project.
Drag that new settings file into the Properties Folder (Remember don't do this from Visual Studio, do it from project directory). Now it should work.
Thanks,
Muhammad Fuzail Zubari
I am trying to use Settings.settings to define/persist some vars. For brevity, I've set up a test file to demonstrate the behavior I'm seeing:
First, I define a setting in Settings.settings:
I then have the following code to test changing variableName:
public Form1()
{
InitializeComponent();
string newString = Properties.Settings.Default.variableName;
Properties.Settings.Default.variableName = "This is a new string";
Properties.Settings.Default.Save();
}
Running the above in the debugger for the first time, I grab the current value (the value I set in the Settings.settings window initially) of variableName from Properties.Settings. As expected, newString is set to "This is a string". Good.....
After executing the next two lines, the debugger shows variableName changed to "This is a new string". Good....
I then run the app through the debugger again. I hit the string newString line and, prior to execution, newString is undefined (of course). Good....
As soon as I execute...
string newString = Properties.Settings.Default.variableName;
... and on subsequent executions of the code, the actual value of variableName is defined as "This is a new string" (Good...as expected).
I then go back to the Settings.settings window. variableName has not changed - it's still "This is a string". I've even closed VSE 2012 and re-opened the project. Settings.settings never changes.
Where is the new value being stored? I've checked all of the .config files ([appname].exe.config, [appname].vshost.exe.config, app.config, and the Settings.settings file) and the new value, "This is a new string" isn't anywhere to be found.
In summary, I'm getting the result I desire from the code, but I can't seem to view the result at design time other than to check the value of the var in the debugger. This seems not only peculiar to me, but impossible.
What am I missing/where am I not looking? I would fully expect the value of variableName to change in the Settings.settings window, but it never does. I've looked everywhere on StackOverflow/Google and can't seem to find the answer.
Thanks in advance....
The original value that you configured via Settings.settings is stored in a .config file alongside your executable's assembly. This will never change unless you modify the Settings file directly via Visual Studio; it's essentially a read-only file.
The user's customized setting is stored in a separate config file within the user's profile. The location of this file depends on your assembly's metadata. For example, on Windows 7/Vista the location might look like:
C:\Users\<user name>\AppData\Local\<company name>\<assembly name>\
AssemblyName\<version>\user.config
If you haven't customized the company name in your assembly's metadata then it may default to Microsoft. Also note that AppData is a hidden folder that may not be visible in Windows Explorer depending on your view settings.
I am not sure if I understand your question. That variable content stay persistent. Thats it. Why you would set a persistent variable to change it later?
I am trying to iterate through application properties in C# using reflection (.NET 3.5 using VS 2010). The code "works" in that it successfully gets properties. However, it always gets the property values that were defined at design time and does not see the current values in myapp.exe.config. Properties that I access directly by name do reflect what is in the .config file. Here is the reflection-based code which only sees design-time properties:
List<StringDictionary> dictList = new List<StringDictionary>();
StringCollection bogus = new StringCollection();
foreach (PropertyInfo info in Properties.Settings.Default.GetType().GetProperties())
{
if (!("logLevel".Equals(info.Name) || "eventURL".Equals(info.Name)))
{
if (bogus.GetType().IsAssignableFrom(info.PropertyType))
{
StringCollection rawConfig = (StringCollection)info.GetValue(Properties.Settings.Default, null);
// do something
}
}
}
This code does pick up the current values in myapp.exe.config.
String logLevelStr = Properties.Settings.Default.logLevel
What am I doing wrong in my reflection code that causes me to pull only the properties defined at design time and not what is currently in myapp.exe.config?
To get the current value you need to use something like this which looks at Default.PropertyValues instead of Default.Properties
foreach (SettingsPropertyValue property in Properties.Settings.Default.PropertyValues)
{
Debug.WriteLine(string.Format("Property {0}'s value is {1}",property.Name,property.PropertyValue));
}
// note: the above may not work in some multi-form app, even if the applicaton prefix is prepended in front of Properties esp for visual studio 2010 compiled app with .net frame work 4
I think that there is a fundamental misunderstanding here. Settings can be one of two types- Application settings and User settings.
Application settings are intended to be written only at design time. As Henk points out it is possible to edit them after deployment if you are admin, but that isn't really the intent. Also, it should be noted that while Application settings are stored in the .config file, they are only read once and then cached in memory. That's why you don't see the new values when you edit the file.
User settings can be overwritten at run time by application code and saved, but they are saved at a user scope, so a different user running the same application can have different values. The intention there was things like user preferences. There is a drop down in the settings designer grid to switch between Application and User scope for each Setting.
Either way, you shouldn't be accessing them via reflection.
There must be some kind of misunderstanding here.
If you want to read the configurations from myapp.exe.config you should use ConfigurationManager. This class allows you to access AppSettings and ConnectionString directly through static properties or read custom sections by the GetSection method.
Beside, application configurations are meant to be design-time only. You shouldn't alter myapp.exe.config at runtime. Never. This file must be the same for each execution of your application.
Beside, what is Properties.Settings.Default.logLevel ???
Consider:
foreach (SettingsProperty sp in Settings.Default.Properties)
{
Console.WriteLine(sp.Name + "=" + Settings.Default.Properties.Default[sp.Name].ToString());
}
I've been working on a pet project on the weekends to learn more about C# and have encountered an odd problem when working with localization. To be more specific, the problem I have is with System.Threading.Thread.CurrentThread.CurrentUICulture.
I've set up my app so that the user can quickly change the language of the app by clicking a menu item. The menu item in turn, saves the two-letter code for the language (e.g. "en", "fr", etc.) in a user setting called 'Language' and then restarts the application.
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
Application.Restart();
When the application is started up, the first line of code in the Form's constructor (even before InitializeComponent()) fetches the Language string from the settings and sets the CurrentUICulture like so:
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
InitializeComponent();
}
The thing is, this doesn't work consistently. Sometimes, all works well and the application loads the correct language based on the string saved in the settings file. Other times, it doesn't, and the language remains the same after the application is restarted.
At first I thought that I didn't save the language before restarting the application but that is definitely not the case. When the correct language fails to load, if I were to close the application and run it again, the correct language would come up correctly. So this implies that the Language string has been saved but the CurrentUICulture assignment in my form constructor is having no effect sometimes.
Any help? Is there something I'm missing of how threading works in C#? This could be machine-specific, so if it makes any difference I'm using Pentium Dual-Core CPU.
UPDATE
Vlad asked me to check what the CurrentThread's CurrentUICulture is. So I added a MessageBox on my constructor to tell me what the CurrentUICulture two-letter code is as well as the value of my Language user string.
MessageBox.Show(string.Format("Current Language: {0}\nCurrent UI Culture: {1}", Properties.Settings.Default.Language, Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName));
When the wrong language is loaded, both the Language string and CurrentUICulture have the wrong language. So I guess the CurrentUICulture has been cleared and my problem is actually with the Language Setting.
So I guess the problem is that my application sometimes loads the previously saved language string rather than the last saved language string. If the app is restarted, it will then load the actual saved language string.
I got the same problem. I figured out that Application.Restart() do not really make an absolutely restart, see MSDN.
So Application.Restart() do not call the initializing things within the forms constructor
like InitializeComponent(), more the "Applications are restarted in the context in which they were initially run."
So your code is correct
Properties.Settings.Default.Language = "en";
Properties.Settings.Default.Save();
public Form1()
{
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Properties.Settings.Default.Language);
//...
InitializeComponent();
}
but it doesn't work this way with Application.Restart(). If You close the app and open it again your (new) settings are taken.
So we have to find a way to initialize the form again to make the new language settings happen.
Could you check what is your thread's CurrentUICulture?
I remember having a problem like yours; it was solved by reloading the resource dictionary containing the strings to be localized:
Thread.CurrentThread.CurrentUICulture = <new culture>;
ResourceDictionary newDict = new ResourceDictionary();
newDict.Source = localizedStrings.Source;
localizedStrings = newDict;
(and this approach worked dynamically as well; here is some more information).
You could manually change the language of the current form similar to this:
CultureInfo cInfo = new CultureInfo("en-US");
ResourceManager rm = new ResourceManager(GetType());
// For each control on the form, perform the translation manually (probably better in a loop)
control1.Text = rm.GetString(control1.Name + ".Text", cInfo);
// Now set the culture for all other dialogs
Thread.CurrentThread.CurrentUICulture = cInfo;
Hope that helps!
You could simply "reset" your application by closing the open forms and re-creating them. Then you could directly set the culture when the user changes the setting.
Also, try giving some debug output so you see what values are being set and if the culture is actually what you expect.
EDIT: My guess: Since the data has to be written to a file, and then loaded from that file, you may be restarting too quickly for the write to have been completed.
By using CurrentThread.CurrentUICulture, and then changing the form, you don't need to restart the application. Ref my old post here