C # obtendo o caminho de% AppData%

387

C # 2008 SP1

Estou usando o código abaixo:

dt.ReadXml("%AppData%\\DateLinks.xml");

No entanto, estou recebendo uma exceção que aponta para o local de onde meu aplicativo está sendo executado:

Não foi possível encontrar uma parte do caminho 'D: \ Projetos \ SubVersionProjects \ CatDialer \ bin \ Debug \% AppData% \ DateLinks.xml'.

Eu pensei que o %AppData%deveria encontrar o caminho relativo. Quando vou, o Start|Run|%AppData%Windows Explorer me leva para esse diretório.

Não consigo inserir o caminho completo, pois o usuário é diferente em cada máquina cliente.

ant2009
fonte

Respostas:

802

Para obter o diretório AppData , é melhor usar o GetFolderPathmétodo:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

(deve adicionar using Systemse não estiver presente).

%AppData%é uma variável de ambiente e elas não são expandidas automaticamente em nenhum lugar do .NET, embora você possa usar explicitamente o Environment.ExpandEnvironmentVariablemétodo para fazer isso. Eu ainda sugeriria fortemente que você o usasse GetFolderPath, porque, como Johannes Rössel aponta no comentário, %AppData%pode não ser definido em determinadas circunstâncias.

Por fim, para criar o caminho conforme mostrado no seu exemplo:

var fileName = Path.Combine(Environment.GetFolderPath(
    Environment.SpecialFolder.ApplicationData), "DateLinks.xml");
Noldorin
fonte
45
+1 por oferecer uma solução real, sem depender do ambiente. Para adicionar à resposta: nem toda função que lida com nomes de arquivos expande variáveis ​​de ambiente. De fato, geralmente você precisa fazer isso explicitamente, caso contrário não funcionará e você terminará com pastas% something%. Além disso, o ambiente não precisa estar presente; em alguns casos, ao executar um programa em outra conta de usuário, o ambiente do usuário não será carregado e o% Appdata% ficará vazio. É por isso que você deseja usar as APIs documentadas para obter essas pastas (a menos que esteja usando arquivos em lote).
Joey
@ Johannes: Boas informações lá. Acabei de alterar minha resposta quando você a postou, mas deixarei mais claro que GetFolderPath é definitivamente preferível a ExpandEnvironmentVariable.
Noldorin
+1 para Environment.GetFolderPath (Environment.SpecialFolder.ApplicationData), eu estava por trás disso há alguns dias.
Sumit Ghosh
11
Por algum motivo, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)retorna uma string vazia para mim (IIS 7, VS 2011). Problema resolvido usando a solução Simon_Weaver - mapeando usando MapPath.
Mike Keskinov
52
FYI que dá o diretório Roaming para locais AppData Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData)
roundcrisis
49

O caminho é diferente se você estiver falando do ASP.NET.

Não consegui encontrar nenhum dos valores de 'SpecialFolder' que apontavam para / App_Data for ASP.NET.

Em vez disso, você precisa fazer o seguinte:

 HttpContext.Current.ApplicationInstance.Server.MapPath("~/App_Data")  

(Nota: você não precisa da propriedade 'Current' em um MVC Controller)

Se há outra maneira mais "abstrata" de chegar App_Data, adoraria ouvir como.

Simon_Weaver
fonte
Apenas uma observação, já que o núcleo do asp.net está sendo lançado agora. Essa abordagem depende especificamente do IIS.
George Mauer
7
HostingEnvironment.MapPath(@"~/App_Data")é melhor e funciona nos contextos MVC / WebAPI e WCF, onde não há HttpContext - mas não tenho certeza sobre o núcleo '
#
37

A melhor maneira de usar o diretório AppData, é usar o Environment.ExpandEnvironmentVariablemétodo

Razões:

  • ele substitui partes da sua string por diretórios válidos ou qualquer outra coisa
  • não diferencia maiúsculas de minúsculas
  • é fácil e descomplicado
  • é um padrão
  • bom para lidar com a entrada do usuário

Exemplos:

string path;
path = @"%AppData%\stuff";
path = @"%aPpdAtA%\HelloWorld";
path = @"%progRAMfiLES%\Adobe;%appdata%\FileZilla"; // collection of paths

path = Environment.ExpandEnvironmentVariables(path);
Console.WriteLine(path);

Lembre-se de que alguns usuários digitam %AppData%, alguns %appdata%e alguns %APpData% Você não deseja terminar com:

if (path.ToLower().StartsWith("%appdata%"))
    ; // path manipulation
if (path.ToLower().StartsWith("%programfiles%"))
    ; // path manipulation

Se a variável de ambiente não estiver definida, a culpa não é sua (além de quando IS ). Normalmente, não digo às pessoas para não reinventarem a roda, mas depois que segui o caminho pela primeira vez e percebi que era uma má ideia.

Azul amargo
fonte
Gostava de seus exemplos de pathvariável :)
RBT
O +1 Environment.ExpandEnvironmentVariableé melhor quando você simplesmente precisa expandir, independentemente de quais ambientes possam estar na cadeia de caminho.
blins
24

Você também pode usar

Environment.ExpandEnvironmentVariables("%AppData%\\DateLinks.xml");

para expandir a %AppData%variável.

parapeito
fonte
15

No .net2.0 você pode usar a variável Application.UserAppDataPath

Nathan
fonte
20
Este é apenas o WinForms.
7

Eu não acho que colocar% AppData% em uma string assim funcionará.

tentar

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).ToString()
danswain
fonte
4

Só queria compartilhar outra maneira de acessar a pasta 'App_Data' no meu aplicativo mvc, caso alguém precise disso.

 Path.Combine(HttpRuntime.AppDomainAppPath,"App_Data")
cpoDesign
fonte
Pode não ser a resposta certa, mas é o que eu estava procurando. +1
Derrick
Trabalhou para mim depois de substituir aspas simples por aspas duplas. Path.Combine (HttpRuntime.AppDomainAppPath, "App_Data")
ajaysinghdav10d
1

Isso está funcionando para mim em um aplicativo de console -

string appData = System.Environment.GetEnvironmentVariable("APPDATA");
Conta
fonte
1

Para o ASP.NET, a Load User Profileconfiguração precisa ser definida no pool de aplicativos, mas isso não é suficiente. Há uma configuração oculta denominada setProfileEnvironmentin \Windows\System32\inetsrv\Config\applicationHost.config, que por algum motivo é desativada por padrão, em vez de ativada conforme descrito na documentação . Você pode alterar o padrão ou configurá-lo no seu pool de aplicativos. Todos os métodos da Environmentclasse retornarão valores adequados.

MoonStom
fonte