Posso controlar a localização das configurações do usuário do .NET para evitar a perda de configurações na atualização do aplicativo?

Eu estou tentando personalizar o local do arquivo user.config . Atualmente é armazenado com um hash e número de versão

 %AppData%\[CompanyName]\[ExeName]_Url_[some_hash]\[Version]\ 

Eu quero ser agnóstico para a versão do aplicativo

 %AppData%\[CompanyName]\[ProductName]\ 

Isso pode ser feito e como? Quais são as implicações? O usuário perderá as configurações da versão anterior após a atualização?

Para responder a primeira pergunta, você tecnicamente pode colocar o arquivo onde quiser, no entanto, você terá que codificar você mesmo, já que o local padrão para o qual o arquivo vai é o primeiro de seus dois exemplos. ( link para como fazer você mesmo )

Quanto à segunda questão, depende de como você implanta o aplicativo. Se você implantar via .msi, haverá dois hashes nas propriedades do projeto de instalação (do qual o msi é construído), o ‘código de atualização’ e o ‘código do produto’. Eles determinam como o MSI pode ser instalado e se ele é atualizado, sobrescreve ou é instalado ao lado de qualquer outra versão do mesmo aplicativo.

Por exemplo, se você tem duas versões de seu software e elas têm diferentes códigos de ‘upgrade’, então, para o Windows, são peças de software completamente diferentes, independentemente de qual seja o nome. No entanto, se o código de ‘atualização’ for o mesmo, mas o código do ‘produto’ for diferente, quando você tentar instalar o segundo msi, ele perguntará se você deseja atualizar, quando então ele deverá copiar os valores do arquivo. configuração antiga para uma nova configuração. Se os dois valores forem iguais e o número da versão não for alterado, a nova configuração estará no mesmo local da configuração antiga e não precisará fazer nada. Documentação da MSDN

O ClickOnce é um pouco diferente, porque é baseado mais no número de versão e no caminho da URL do ClickOnce, no entanto, descobri que, enquanto você continuar a ‘Publicar’ no mesmo local, a nova versão do aplicativo continuará a usar o configuração existente. ( link para como o ClickOnce lida com atualizações )

Eu também sei que há uma maneira de mesclar manualmente as configurações durante a instalação do msi usando scripts de instalação personalizados, mas não me lembro das etapas exatas para fazê-lo … (veja este link para saber como fazer isso com uma web. config)

Eu queria adicionar este texto citado como referência para quando eu tiver esse problema no futuro. Supostamente, você pode instruir a infraestrutura do ApplicationSettings a copiar as configurações de uma versão anterior chamando Upgrade :

 Properties.Settings.Value.Upgrade(); 

Na postagem do blog de perguntas frequentes sobre as configurações do cliente :

P: Por que há um número de versão no caminho user.config? Se eu implantar uma nova versão do meu aplicativo, o usuário não perderá todas as configurações salvas pela versão anterior?

R: Existem alguns motivos pelos quais o caminho user.config é sensível à versão.

(1) Para suportar a implantação lado a lado de diferentes versões de um aplicativo (você pode fazer isso com o Clickonce, por exemplo). É possível que diferentes versões do aplicativo tenham configurações diferentes salvas.

(2) Quando você atualiza um aplicativo, a class de configurações pode ter sido alterada e pode não ser compatível com o que está salvo, o que pode causar problemas.

No entanto, facilitamos a atualização das configurações de uma versão anterior do aplicativo para a mais recente. Simplesmente chame ApplicationSettingsBase.Upgrade () e ele irá recuperar as configurações da versão anterior que correspondem à versão atual da class e armazená-las no arquivo user.config da versão atual. Você também tem a opção de replace esse comportamento na sua class de configurações ou na implementação do provedor.

P: Ok, mas como sei quando chamar o Upgrade?

A: boa pergunta. No Clickonce, quando você instala uma nova versão do seu aplicativo, o ApplicationSettingsBase o detecta e atualiza automaticamente as configurações para você quando as configurações do ponto são carregadas. Em casos sem Clickonce, não há atualização automática – você precisa ligar para a atualização por conta própria. Aqui está uma ideia para determinar quando chamar a atualização:

Tenha uma configuração booleana chamada CallUpgrade e atribua a ela um valor padrão de true. Quando seu aplicativo é iniciado, você pode fazer algo como:

 if (Properties.Settings.Value.CallUpgrade) { Properties.Settings.Value.Upgrade(); Properties.Settings.Value.CallUpgrade = false; } 

Isso garantirá que o Upgrade () seja chamado apenas na primeira vez que o aplicativo for executado após a implantação de uma nova versão.

Eu não acredito nem por um segundo que isso realmente funcionaria – não há como a Microsoft fornecer essa habilidade, mas o método é exatamente o mesmo.

O arquivo user.config é armazenado em

c:\Documents and Settings>\\[Local Settings\]Application Data\\__\

é o diretório de dados do usuário, não roaming (Configurações locais acima) ou em roaming.
é o nome do usuário.
é o valor CompanyNameAttribute, se disponível. Caso contrário, ignore este elemento.
é o AppDomain.CurrentDomain.FriendlyName. Normalmente, isso usa o nome do .exe.
é o URL, StrongName ou Caminho, com base na evidência disponível para hash.
é um hash SHA1 de evidências reunidas do CurrentDomain, na seguinte ordem de preferência:
1. StrongName
2. URL:
Se nenhum desses estiver disponível, use o caminho .exe.
é a configuração AssemblyVersionAttribute do AssemblyInfo.

A descrição completa está aqui http://msdn.microsoft.com/pt-br/library/ms379611.aspx

(Eu adicionaria isso como um comentário à resposta do @ Amr, mas eu não tenho representante suficiente para fazer isso ainda.)

As informações no artigo do MSDN são muito claras e parecem ainda se aplicar. No entanto, ele não menciona que o hash SHA1 está escrito na base 32 codificada, em vez da base mais típica 16.

Eu acredito que o algoritmo que está sendo usado é implementado em ToBase32StringSuitableForDirName , que pode ser encontrado aqui na fonte de referência da Microsoft .