I have a windows application that writes user settings using the method described here:
http://msdn.microsoft.com/en-us/library/bb397755(v=vs.110).aspx
These settings are saved to a file in the users directory e.g:
c:\users\{you name}\Local\{Company}\{product}\user.config
I need to access these settings in a companion console application. Is this possible, at the moment the settings return null when I try to access them from the console application.
The code itself will look something like this:
To save the settings in App1:
namespace Application1{
public class DemoSave{
public void DoWork(){
Application1.Properties.Settings.Default.CustomSettings.Title ="someValue";
Application1.Properties.Settings.Default.Save();
}
}
}
To read the settings in another app:
namespace Application2{
public class Demo{
public void DoWork(){
var title = Application1.Properties.Settings.Default.CustomSettings.Title;
}
}
}
In Application2 the Application1.Properties.Settings.Default.CustomSettings property is null.
Last time I did something similar, I had two projects in a solution (a windows service and a wpf application), and I had to reference the WPF app in the Win Service project to access it's settings (I assume you're talking about Namespace.Properties.Settings). It seems to have worked fine for me. In this case i had to set the access modifier on the settings to public though. I'm not sure if this is the best way, but it worked for me for something very small and insignificant.
Are you even sure your pointing at the right place when you modifies/read the settings files.
Because that might be why it doesn't work.
Related
My app is written in WPF C# and I export it as Universal app using MSIX Application Project straight from Visual Studio.
I just can't get the settings to persist between updates. I'm using the following code in the MainWindow_Loaded event:
Settings.Default.Upgrade();
Settings.Default.Save();
Settings.Default.Reload();
I tried keeping assembly information versions the same and just increment the version in the appx.manifest but it doesn't work.
I've noticed that each time the app updates it creates a new uniquely named parent settings folder (with a new hash every time) and the subfolder name is the version from the assembly. The folder structure is like this:
App.exe_Url_dfvfmfjs1qo33zsag1ay5w1s0rwg0u53/0.2.10.0/user.config
App.exe_Url_tazrvujdga5ujjarnahpkoscv5zbkgl0/0.2.10.0/user.config
I believe it might have to do with the fact that it keeps generating new hashes instead of just placing the new version as a subfolder and that's why Upgrade doesn't do anything.
The only information I've found so far is to use Settings.Default.Upgrade()
How am I supposed to transfer the old version settings to the new version when my universal desktop bridge app updates?
As far as I researched these settings do not transfer to UWP updates using Desktop Bridge. So I started using UWP's native ApplicationData.Settings
As a workaround I created 2 methods to update the newly created WPF settings using LocalSettings which is the UWP equivalent and vice versa. UWP's LocalSettings transfer on update. I call Update() when I save my WPF settings and I call Load() when the application starts. It works.
Here's the code, only caveat I've found so far is you should use the basic types as these methods will fail transferring something like a List<string> or a StringCollection, for that I'm using serialization, although you can always adapt them to do that too:
static class UWPSettings
{
public static void Update()
{
if (Startup.IsUniversalPlatform)
{
foreach (SettingsPropertyValue value in Properties.Settings.Default.PropertyValues)
{
ApplicationData.Current.LocalSettings.Values[value.Name] = value.PropertyValue;
}
}
}
public static void Load()
{
if (Startup.IsUniversalPlatform)
{
foreach (var setting in ApplicationData.Current.LocalSettings.Values)
{
foreach (SettingsPropertyValue s in Properties.Settings.Default.PropertyValues)
{
if (s.Name == setting.Key)
{
s.PropertyValue = setting.Value;
}
}
}
Properties.Settings.Default.Save();
}
}
}
Like what I said in the title, how can we access the property in App in a different project? I want to access it from normal class like a service. Not in viewmodel. Hope we can do something like Application as App.
Access properties in App.xaml.cs from different project UWP
You may try to use one App.xaml.cs for the two projects. For example, if the second project wants to access App.xaml.cs in the first project without reference the first project, you may consider remove the App.xaml.cs which is belonged to the second project, and Add-ExitingItem to add the App.xaml.cs from the first project. In that case, the two projects will share the same App.xam.cs and then you can directly access the properties as Marian Dolinský mentioned.
Otherwise, the two projects may not be able to communicate with each other directly. If the above method is not suit for you, please detail why you need this feature and we may need to consider other ways without accessing the App.xaml.cs.
Method 1
You could cast Application.Current to App:
App app = (App)Application.Current;
app.YourProperty = something;
Method 2
Create some static property holding the reference of App. In my projects I do it by creating a new property called Current as follows:
// in App.xaml.cs
public static new App Current { get; private set; }
public App()
{
Current = this;
// Another code
}
My current solution has 3 project with 2 app.config (one for common settings and another for service settings). As of now I'm simply creating static classes to act as a mediator to access values. I do this so I don't have to write ConfigurationManager.AppSettings["SomeKey"] everywhere. This works fine until you want to access an app.config file from a different project.
Here is what I'm currently doing (all properties omitted for brevity).
public class ServiceConfiguration
{
public static readonly string SyncEvery = ConfigurationManager.AppSettings["SyncEveryMinutes"];
}
How can I access an app.config file located in another project? I thought perhaps setting VS to copy the file to the output directory would do the trick however my configuration object is still null.
I can't imaging many good reasons to read another app's configuration in the first place, it just opens a can of worms that isn't worth dealing with.
Expose a class that exposes the project's configured values as properties, and access them from a consuming class.
public class FirstProjectClass
{
public static int SyncEveryMinutes
{
get { return (int)ConfigurationManager.AppSetting["SyncEveryMinutes"] };
}
}
public class SecondProjectClass
{
public void ShowConfigedValue()
{
Console.Writeline("Syncing every {0} minutes", FirstProjectClass.SyncEveryMinutes);
}
}
if you've got complex configuration requirements you can also look into custom configuration sections
ConfigurationManager.OpenExeConfiguration can be helpfull:
http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.openexeconfiguration.aspx
Also: what Jason said - it is usually a bad idea.
I have multiple .NET assemblies that all need to share common user settings, such as preferences, user names, etc. One is a WPF application, another is a console application, and the third is an Office Add-in. All of these settings are user-scope.
Only the WPF application needs to be able to change settings. The rest just read them.
Ideally, I'd like to use the .NET configuration framework. I'm not sure how to do this though. If I add Settings to the WPF application, how can the other applications find the user.config file?
Is it just easier to create a class library and use IsolatedFileStorage and serialize my settings?
Any advice would be greatly appreciated.
You can implement your custom settings class, inheriting ApplicationSettingsBase. As a good start, you can add the default User Settings file to a sample project (Right click on the project -> Properties -> Settings -> This project does not contain a default settings file. Click here to create one.). Add a user-scoped setting and investigate the structure of the designer-generated Settings.Designer.cs file:
namespace ConsoleApplication1.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("John Doe")]
public string Name {
get {
return ((string)(this["Name"]));
}
set {
this["Name"] = value;
}
}
}
}
In your custom implementation, you will not be limited to the designer-generated access modifiers, so you can implement the Settings class as internal with internal setters, visible only to the needed assemblies, or whatever fits your needs.
Of course, you can always implement your custom serialize/deserialize mechanism, but you will lose the funcionality provided by ApplicationSettingsBase's Updgrade, Reload, and Reset methods. If you don't need any of these, this could be the cleaner approach.
I would recommend you to create service to provide and update user info and or preferences. It will be better architecture, cleaner solution and it will be easier to maintain and extend.
This is very frustrating... I can set the Configuration File for a Windows Forms Application just fine. Consider this:
public static void Main(){
AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", #"SharedAppConfig.config");
//do other things
}
However, in a WPF application, this doesn't seem to work! If I set this value, the value of the AppDomain.CurrentDomain.SetupInformation.ConfigurationFile property is correct, but any calls to that configuration file while debugging yield no results. There are WCF configuration settings in an App.config that I need to share between application, so this is my proposed solution. Is it possible to dynamically set the location of my config file in WPF?
Help! Thanks!
You should be able to do something along the lines of:
using System.Configuration;
public class TryThis
{
Configuration config = ConfigurationManager.OpenExeConfiguration("C:\PathTo\app.exe");
public static void Main()
{
// Get something from the config to test.
string test = config.AppSettings.Settings["TestSetting"].Value;
// Set a value in the config file.
config.AppSettings.Settings["TestSetting"].Value = test;
// Save the changes to disk.
config.Save(ConfigurationSaveMode.Modified);
}
}
NOTE: This will attempt to open a file named app.exe.config at C:\PathTo. This also REQUIRES that a file exists at the same path with the name "app.exe". The "app.exe" file can just be an empty file though. For your case I'd almost make a shared "Config.dll" library that would handle the config file.
~md5sum~
Is this on the service side or the client side? If on the service side, it is often the case that the service is running in its own AppDomain, so that if you set AppDomain.CurrentDomain.SetData(...) it won't apply to the service configuration.
I'm not entirely sure how to get around this, but you should be able to control the service's configuration by implementing your own ServiceHost.