简体   繁体   English

.Net应用程序“ B”可以读取应用程序“ A”的用户设置吗?

[英].Net can app “B” read the user settings for app “A”?

The title sort of says it all. 标题说明了一切。 I have on app that defines some user settings, which end up being stored by .NET in a user specific file, for that app. 我在应用程序上定义了一些用户设置,这些设置最终由.NET存储在该应用程序的用户特定文件中。

I have a closely related support app that needs to read some of these same settings, but I don't know if this is possible programatically? 我有一个密切相关的支持应用程序,需要读取其中一些相同的设置,但是我不知道这是否可以通过编程实现? All the examples I've seen of reading properties read out the properties associated with the running application.. 我看过的所有读取属性的示例都读取了与正在运行的应用程序关联的属性。

Michael 迈克尔

When I have run in to this in the past what I do is I save in to CommonApplicationSettings a xml file with my settings. 过去,我要做的就是将包含设置的xml文件保存到CommonApplicationSettings中。 I then have the model and the reader/writer for the settings in a common C.dll that A and B both share. 然后,我拥有A和B都共享的通用C.dll中的设置模型和读取器/写入器。

Here is a example class of a reader/writer I made. 这是我制作的一个读写器的示例类。 It holds the settings in a property, any time the file is changed on the hard drive a new copy of the settings is loaded and the PropertyChanged event is raised. 每次在硬盘上更改文件时,它将设置保存在属性中,并且会加载新的设置副本并引发PropertyChanged事件。

Both programs create a copy of Configuration then listen to the PropertyChanged event. 这两个程序都创建Configuration的副本,然后侦听PropertyChanged事件。 If it gets a signal that a change happened the programs re-read the settings out of Configuration.Settings and use them as their active values. 如果收到更改发生的信号,程序将从Configuration.Settings重新读取设置,并将其用作活动值。

public sealed class Configuration : INotifyPropertyChanged, IDisposable
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(Configuration));


    private readonly FileSystemWatcher _fileSystemWatcher;
    public string SettingsPath { get; private set; }
    private ConfigurationSettings _settings;

    public Configuration()
    {
        const string settingsFileName = "Settings.xml";
        const string programName = "App A";

        SettingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), programName, settingsFileName);

        if (!File.Exists(SettingsPath))
        {
            CreateDefaultFile();
        }

        //Read in the settings.
        ReadSettingsFromFile();


        _fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(SettingsPath), settingsFileName);
        _fileSystemWatcher.BeginInit();
        _fileSystemWatcher.Changed += FileSystemWatcherOnChanged;
        _fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
        _fileSystemWatcher.EndInit();
        _fileSystemWatcher.EnableRaisingEvents = true;
    }

    public ConfigurationSettings Settings
    {
        get { return _settings; }
        private set
        {
            if (Equals(value, _settings))
            {
                return;
            }
            _settings = value;
            OnPropertyChanged("Settings");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void ReadSettingsFromFile()
    {
        Logger.Debug("Reading settings from the file.");

        var serializer = new XmlSerializer(typeof(ConfigurationSettings));
        using (FileStream settingsStream = File.Open(SettingsPath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            Settings = (ConfigurationSettings)serializer.Deserialize(settingsStream);
        }

    }

    private async void FileSystemWatcherOnChanged(object sender, FileSystemEventArgs fileSystemEventArgs)
    {
        _fileSystemWatcher.EnableRaisingEvents = false;

        Logger.Debug(new {fileSystemEventArgs.ChangeType, fileSystemEventArgs.FullPath, fileSystemEventArgs.Name});

        //Add a pause to allow for the file to be finished writing.
        await TaskEx.Delay(TimeSpan.FromSeconds(1));

        ReadSettingsFromFile();

        _fileSystemWatcher.EnableRaisingEvents = true;
    }

    /// <summary>
    ///     Creates the default settings file
    /// </summary>
    private void CreateDefaultFile()
    {

        var directoryInfo = Directory.CreateDirectory(Path.GetDirectoryName(SettingsPath));
        //add rights for other users to modify the directory.
        var security = directoryInfo.GetAccessControl();
        security.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null), FileSystemRights.Modify, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
        directoryInfo.SetAccessControl(security);

        Settings = new ConfigurationSettings();
        Save();
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public void Save()
    {
        bool oldState = false;

        if (_fileSystemWatcher != null)
        {
            oldState = _fileSystemWatcher.EnableRaisingEvents;
        }

        try
        {
            //Disable events while the value is written.
            if (_fileSystemWatcher != null)
            {
                _fileSystemWatcher.EnableRaisingEvents = false;
            }

            var serializer = new XmlSerializer(typeof(ConfigurationSettings));

            using (var filestream = new FileStream(SettingsPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                serializer.Serialize(filestream, Settings);
            }
        }
        finally
        {
            if (_fileSystemWatcher != null)
            {
                _fileSystemWatcher.EnableRaisingEvents = oldState;
            }
        }
    }

    #region IDisposable Pattern

    private bool _disposed;

    /// <summary>
    ///     Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    /// <summary>
    ///     Finalizes this instance (called prior to garbage collection by the CLR)
    /// </summary>
    ~Configuration()
    {
        Dispose(false);
    }

    private void Dispose(bool fromUserCode)
    {
        if (!_disposed)
        {
            if (fromUserCode)
            {
                if (_fileSystemWatcher != null)
                {
                    _fileSystemWatcher.Dispose();
                }
            }
        }
        _disposed = true;
    }

    #endregion
}

Here is what my ConfigurationSettings class looks like. 这是我的ConfigurationSettings类的外观。

/// <summary>
/// Used as a container to represent the settings of the program
/// </summary>
[Serializable]
[XmlType(AnonymousType = false)]
public sealed class ConfigurationSettings : IEquatable<ConfigurationSettings>
{
    private TimeSpan _uploadInterval;
    private TimeSpan _pauseBetweenModules;
    private static readonly TimeSpan UploadIntervalDefault = new TimeSpan(0, 0, 30, 0);
    private static readonly TimeSpan PauseBetweenModulesDefault = new TimeSpan(0,0,0,5);
    private const int InitialBatchSizeDefault = 100;

    public ConfigurationSettings()
    {
        InitialBatchSize = InitialBatchSizeDefault;
        UploadInterval = UploadIntervalDefault;
        PauseBetweenModules = PauseBetweenModulesDefault;
        DatabaseInstances = new ObservableCollection<DatabaseInstance>();
        UploadPulseData = true;
    }

    /// <summary>
    /// Will upload the pulse finical data
    /// </summary>
    public bool UploadPulseData { get; set; }

    /// <summary>
    /// The batch size the auto windowing function will use for its initial value for the upload module.
    /// </summary>
    public int InitialBatchSize { get; set; }

    /// <summary>
    /// The ammount of time a pause should be inserted between modules to allow the program to do any work that
    /// has processing to do.
    /// </summary>
    [XmlIgnore] //Xml can not serialize a TimeSpan, so we use the hidden property PauseBetweenModulesInMilliseconds during serialization.
    public TimeSpan PauseBetweenModules
    {
        get { return _pauseBetweenModules; }
        set { _pauseBetweenModules = value; }
    }

    // Hidden property for serialization
    [XmlElement("PauseBetweenModulesInMilliseconds")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public long PauseBetweenModulesInMilliseconds
    {
        get { return _pauseBetweenModules.Ticks / TimeSpan.TicksPerMillisecond; }
        set { _pauseBetweenModules = new TimeSpan(value * TimeSpan.TicksPerMillisecond); }
    }

    /// <summary>
    /// The length of time between upload batches.
    /// </summary>
    [XmlIgnore] 
    public TimeSpan UploadInterval
    {
        get { return _uploadInterval; }
        set { _uploadInterval = value; }
    }

    // Hidden property for serialization
    [XmlElement("UploadIntervalInMinutes")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public long UploadIntervalInMinutes
    {
        get { return _uploadInterval.Ticks / TimeSpan.TicksPerMinute; }
        set { _uploadInterval = new TimeSpan(value * TimeSpan.TicksPerMinute);}
    }

    /// <summary>
    /// The databases to run uploads against.
    /// </summary>
    public List<DatabaseInstance> DatabaseInstances { get; set; }

    //We override Equals to make OnPropertyChanged less spammy, if the same file is loaded with the same settings it keeps the event from being raised.
    public bool Equals(ConfigurationSettings other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return _uploadInterval.Equals(other._uploadInterval) && 
               _pauseBetweenModules.Equals(other._pauseBetweenModules) &&
               InitialBatchSize == other.InitialBatchSize && 
               UploadPulseData == other.UploadPulseData &&
               DatabaseInstances.SequenceEqual(other.DatabaseInstances);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        return obj is ConfigurationSettings && Equals((ConfigurationSettings)obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = _uploadInterval.GetHashCode();
            hashCode = (hashCode*397) ^ _pauseBetweenModules.GetHashCode();
            hashCode = (hashCode*397) ^ InitialBatchSize;
            hashCode = (hashCode*397) ^ UploadPulseData.GetHashCode();
            if (DatabaseInstances != null)
            {
                foreach (var databaseInstance in DatabaseInstances)
                {
                    hashCode = (hashCode * 397) ^ (databaseInstance != null ? databaseInstance.GetHashCode() : 0);
                }
            }
            return hashCode;
        }
    }
}

There is a very straight-forward way to read another app's settings with the ConfigurationManager.OpenExeConfiguration method. 使用ConfigurationManager.OpenExeConfiguration方法可以非常直接地读取另一个应用程序的设置。

Example: 例:

var config = System.Configuration.ConfigurationManager.OpenExeConfiguration(exePath);
var x = config.AppSettings.Settings["setting"].Value;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在不使用用户设置的情况下在运行时读取/写入 app.config 设置? - How can I read/write app.config settings at runtime without using user settings? 从另一个可访问的 C# 应用程序读取用户(不是应用程序)设置 - Read user (not app) settings from another accessible C# app 使用VB.NET在Metro应用程序中保存用户设置 - Saving user settings in Metro app using VB.NET 设置最终保留在user.config中,即使它们未修改为从app.config中读取 - Settings end up in user.config even though they are unmodified as read from app.config 编辑app.config文件并读取设置 - Edit app.config file and read settings 用户范围应用程序设置始终重置为默认值 - User scope app settings always reset to defaults 如何将我的应用程序设置保存到文本文件并在加载时重新读取? - How can i save settings of my app to a text file and read them back on load? 我可以使用 Environment.GetEnvironmentVariable 方法从 Azure 应用程序设置中读取环境变量吗? - Can i read environment variable from Azure App Settings by using Environment.GetEnvironmentVariable method? 当应用程序 A 的身份验证失败时,.NET OpenIdConnect 重新向应用程序 B 进行身份验证 - .NET OpenIdConnect reauthenticate to App B when authentication failed for App A 当用户是管理员时,为什么 .NET 应用程序不能覆盖文件? - Why can .NET app not overwrite file when user is Administrator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM