Como você mantém as configurações user.config em diferentes versões de montagem em .net?

StackOverflow https://stackoverflow.com/questions/534261

  •  22-08-2019
  •  | 
  •  

Pergunta

Basicamente, o problema é que cada vez que a versão alterações de montagem (ou seja, o usuário instala uma nova versão do aplicativo) todas as suas configurações são redefinir as os padrões (ou mais precisamente um novo arquivo user.config é criado em uma pasta com um número de versão diferente, como o nome)

Como posso manter as mesmas configurações quando as versões de melhoramento, uma vez que o uso de arquivos ini ou o registro parece estar desanimado?

Quando usamos Clickonce parecia ser capaz de lidar com isso, então parece que ele deve ser capaz de ser feito, mas eu não sei como.

Foi útil?

Solução

ApplicationSettingsBase tem um método chamado Atualização que migra todas as configurações da versão anterior.

A fim de executar o merge sempre que publicar uma nova versão do seu aplicativo, você pode definir um sinalizador booleano no seu arquivo de configurações que o padrão é verdadeiro. Nomeá-lo UpgradeRequired ou algo similar.

Então, no início do aplicativo que você verificar para ver se o sinalizador está definido e se for, chame a método de actualização , defina o sinalizador como false e salvar sua configuração.

if (Settings.Default.UpgradeRequired)
{
    Settings.Default.Upgrade();
    Settings.Default.UpgradeRequired = false;
    Settings.Default.Save();
}

Leia mais sobre o método de atualização em MSDN . A GetPreviousVersion também pode valer a pena um olhar se você precisa fazer alguma fusão personalizado.

Outras dicas

Eu sei que já faz algum tempo ... Em um aplicativo winforms, basta ligar My.Settings.Upgrade() antes de carregá-los. Isto irá obter as definições mais recentes, se a versão atual ou uma versão anterior.

Aqui está a minha investigação no caso de alguém está tendo um momento difícil com a migração de configurações que foram alteradas / removidas. problema básico é que GetPreviousVersion() não funciona se você tiver renomeado ou removido a definição na nova versão do seu aplicativo. Então, você precisa manter a configuração em sua classe Settings, mas adicionar atributos poucos / artefatos para isso para que você não inadvertidamente usá-lo no código em outros lugares, tornando-se obsoleto. A definição obsoleta amostra seria parecido com isso em VB.NET (pode ser facilmente traduzido para C #):

<UserScopedSetting(),
DebuggerNonUserCode(),
DefaultSettingValue(""),
Obsolete("Do not use this property for any purpose. Use YOUR_NEW_SETTING_NAME instead."),
NoSettingsVersionUpgrade()>
Public Property OldSettingName() As String
  Get
    Throw New NotSupportedException("This property is obsolete")
  End Get
  Set
    Throw New NotSupportedException("This property is obsolete")
  End Set
End Property

Certifique-se de adicionar essa propriedade para o mesmo namespace / classe que tem as configurações do aplicativo. Em VB.NET, esta classe é nomeado MySettings e está disponível em namespace My. Você pode usar a funcionalidade de classe parcial para impedir que as definições obsoletas de misturar-se com as configurações atuais.

Todo o crédito para jsharrison para postar um excelente artigo sobre esta questão. Você pode ler mais detalhes sobre isso lá.

Aqui está uma variação sobre as soluções apresentadas aqui que encapsula a lógica de atualização em uma classe abstrata que as classes configurações podem derivar.

Algumas soluções propostas usar um atributo DefaultSettingsValue para especificar um valor que indica quando as configurações anteriores não foram carregados. Minha preferência é simplesmente usar um tipo cujo valor padrão indica isso. Como um bônus, um DateTime? É informações de depuração útil.

public abstract class UserSettingsBase : ApplicationSettingsBase
{
    public UserSettingsBase() : base()
    {
        // Accessing a property attempts to load the settings for this assembly version
        // If LastSaved has no value (default) an upgrade might be needed
        if (LastSaved == null)
        {
            Upgrade();
        }
    }

    [UserScopedSetting]
    public DateTime? LastSaved
    {
        get { return (DateTime?)this[nameof(LastSaved)]; }
        private set { this[nameof(LastSaved)] = value; }
    }

    public override void Save()
    {
        LastSaved = DateTime.Now;
        base.Save();
    }
}

Derive de UserSettingsBase:

public class MySettings : UserSettingsBase
{
    [UserScopedSetting]
    public string SomeSetting
    {
        get { return (string)this[nameof(SomeSetting)]; }
        set { this[nameof(SomeSetting)] = value; }
    }

    public MySettings() : base() { }
}

E usá-lo:

// Existing settings are loaded and upgraded if needed
MySettings settings = new MySettings();
...
settings.SomeSetting = "SomeValue";
...
settings.Save();

Se as alterações ao USER.settings são feitas por meio de programação, como sobre a manutenção de uma cópia (apenas) as modificações para USER.settings em um arquivo separado, por exemplo, user.customized.settings?

Você provavelmente ainda quer manter e carregar as configurações modificadas em USER.settings também. Mas desta forma quando você instala uma nova versão do seu aplicativo com a versão mais recente do USER.settings você pode perguntar ao usuário se eles querem continuar a usar suas configurações modificadas, copiando-os de volta para o novo USER.settings. Você poderia importá-los por atacado, ou obter mais extravagante e pedir que o usuário confirme quais configurações eles querem continuar a usar.

EDIT: Eu li muito rapidamente sobre a parte "mais precisão" sobre as versões de montagem causando uma nova USER.settings para ser instalado em um novo diretório específico da versão. Assim, a idéia acima, provavelmente não ajudá-lo, mas pode fornecer algumas pistas de reflexão.

Isto é como eu lidei com isso:

public virtual void LoadSettings(ServiceFileFormBaseSettings settings = null, bool resetSettingsToDefaults = false)
{
    if (settings == null)
            return;

    if (resetSettingsToDefaults)
        settings.Reset();
    else
    {
        settings.Reload();

        if (settings.IsDefault)
            settings.Upgrade();
    }

    this.Size = settings.FormSize;

}

e na classe de configurações, defini a propriedade IsDefault:

// SaveSettings always sets this to be FALSE.
// This will have the default value TRUE when first deployed, or immediately after an upgrade.
// When the settings exist, this is false.
//
[UserScopedSettingAttribute()]
[DefaultSettingValueAttribute("true")]
public virtual bool IsDefault
{
    get { return (bool)this["IsDefault"]; }
    set { this["IsDefault"] = value; }
}

Nos SaveSettings, eu definir IsDefault como false:

public virtual void SaveSettings(ServiceFileFormBaseSettings settings = null)
{
    if (settings == null) // ignore calls from this base form, if any
        return;

    settings.IsDefault = false;
    settings.FormSize = this.Size;
    settings.Save();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top