Como obter o caminho da pasta para o aplicativo ClickOnce

160

Preciso escrever um arquivo na mesma pasta em que um ClickOnce do console .application(arquivo executável) reside. A pasta de onde é iniciada.

Eu tentei usar Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) mas o caminho está apontando para uma subpasta em c:\Documents & Settings. Como obtenho o caminho em que .applicationreside?

Tony_Henrich
fonte

Respostas:

253

Para encontrar o local da pasta, basta executar o aplicativo, abrir o gerenciador de tarefas (CTRL-SHIFT-ESC), selecionar o aplicativo e clicar com o botão direito do mouse em | Abrir local do arquivo.

Erik Vullings
fonte
3
ei, dica pro! mas não está disponível em máquinas XP ruins. :)
Jalal
5
@Jalal para "máquinas de baixa qualidade" acesse www.SysInternals.com e faça o download do Process Explorer. Eu suspeito que as alterações no TaskManager do Win7 e, em seguida, o Win8 foram copiadas dele.
Arioch '
1
Como você consegue isso em seu aplicativo em execução no computador do cliente?
user3285954
2
E se eu não conseguir executar o aplicativo porque ele excluiria um arquivo de log de que eu preciso desesperadamente?
Tomáš Zato - Restabelece Monica
2
@Tony_Henrich você deve marcar este como a resposta correta
sparkyShorts
120

o caminho está apontando para uma subpasta em c: \ Documents & Settings

Está certo. ClickOnce applicationssão instalados sob o perfil do usuário que os instalou. Você pegou o caminho que a recuperação das informações do assembly em execução lhe deu e foi dar uma olhada?

No Windows Vista e Windows 7, você encontrará o cache do ClickOnce aqui:

c:\users\username\AppData\Local\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

No Windows XP, você o encontrará aqui:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername
RobinDotNet
fonte
1
Eu entendo tudo isso. Quero a pasta de onde cliquei no aplicativo. Não tenho acesso ao C: \ Documents and Settings, portanto, não terei acesso ao arquivo de log se for usar o caminho da pasta retornado por essa função e não desejar usar valores de caminho codificados .
Tony_Henrich
25

ApplicationDeployment.CurrentDeployment.ActivationUri pode funcionar

"Uma cadeia de caracteres de tamanho zero se a propriedade TrustUrlParameters no manifesto de implantação for falsa ou se o usuário tiver fornecido um UNC para abrir a implantação ou a tiver aberto localmente. Caso contrário, o valor de retorno será o URL completo usado para iniciar o aplicativo, incluindo quaisquer parâmetros ".


Mas o que eu acho que você realmente deseja é ApplicationDeployment.CurrentDeployment.DataDirectory, que fornece uma pasta na qual você pode gravar dados. Quando você atualiza o aplicativo de qualquer maneira, perde o que estava na pasta .exe original, mas pode migrar o diretório de dados para uma nova versão do aplicativo. Seu aplicativo pode gravar nesta pasta com os arquivos de log que ele possui - e eu tenho certeza que é garantido que seja gravável.

Simon_Weaver
fonte
Não fiz nada, mas os arquivos do DataDirectory antigo são copiados automaticamente para o novo DataDirectory após a implantação. Também não existem diretórios .pre. (.NET Framework 3.5 e 4.5)
Der_Meister 25/03
15

Estou usando Assembly.GetExecutingAssembly().Locationpara obter o caminho para um ClickOnceaplicativo implantado no .Net 4.5.1.

No entanto, você não deve gravar em nenhuma pasta em que seu aplicativo seja implantado para sempre, independentemente do método de implantação (xcopy, ClickOnce, InstallShield, qualquer coisa), porque esses geralmente são apenas de leitura para aplicativos, especialmente em versões mais recentes do Windows e em ambientes de servidor.

Um aplicativo sempre deve gravar nas pastas reservadas para esses fins. Você pode obter as pastas necessárias a partir da Enumeração Environment.SpecialFolder. A página MSDN explica para que serve cada pasta: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

Ou seja, para dados, logs e outros arquivos que se pode usar ApplicationData(roaming), LocalApplicationData(local) ou CommonApplicationData. Para arquivos temporários, use Path.GetTempPathou Path.GetTempFileName.

O trabalho acima também funciona em servidores e desktops.

EDIT: Assembly.GetExecutingAssembly()é chamado no executável principal.

user3285954
fonte
Isso tem funcionado para mim para um aplicativo ClickOnce, além de também estar trabalhando no ambiente de desenvolvimento do VS durante a depuração do mesmo aplicativo.
Developer63
3

ClickOnce aplicativos FAZER reside em um subdiretório de C: \ Documentos e Configurações. Eles não têm diretórios de instalação "limpos" porque os arquivos locais são baixados "temporariamente" para permitir que o aplicativo seja executado no PC local e a execução do aplicativo é controlada no servidor ClickOnce em que eles são implantados, dependendo das configurações de publicação (Verificando atualizações, requisitos de versão etc.).

NebuSoft
fonte
Não tenho acesso à pasta C: \ Documents & Settings no servidor, o que significa que não tenho acesso ao arquivo que o aplicativo cria. Eu executo o aplicativo a partir de uma determinada pasta. É a pasta em que o aplicativo é publicado. Como obtenho o caminho dessa pasta?
Tony_Henrich
Você quer o URL de implantação. Desculpe, eu não entendi nada. Você está tentando obtê-lo de dentro do aplicativo ClickOnce ou de um aplicativo externo?
RobinDotNet
1

Aqui está o que eu achei que funcionava para conseguir o local da pasta implantada do meu aplicativo clickonce e que não havia sido mencionado em nenhum lugar que eu vi nas minhas pesquisas, no meu cenário específico semelhante:

  • O aplicativo clickonce é implantado em uma pasta de rede LAN da empresa.
  • O aplicativo clickonce está definido para estar disponível online ou offline.
  • Meu URL de instalação clickonce e URLs de atualização nas propriedades do meu projeto não possuem nada especificado. Ou seja, não há um local separado para instalação ou atualizações.
  • Nas minhas opções de publicação, estou tendo um atalho na área de trabalho criado para o aplicativo clickonce.
  • A pasta para a qual desejo obter o caminho na inicialização é aquela em que quero ser acessada pelas versões DEV, INT e PROD do aplicativo, sem codificar o caminho.

Aqui está um visual do meu caso de uso:

insira a descrição da imagem aqui

  • As pastas em caixas azuis são meus locais de diretório para cada aplicativo do ambiente.
  • A pasta em caixa vermelha é o diretório para o qual desejo obter o caminho (o que exige primeiro obter o local da pasta implantada do aplicativo "MyClickOnceGreatApp_1_0_0_37", que é igual ao OP).

Não encontrei nenhuma das sugestões nesta pergunta ou seus comentários para retornar a pasta na qual o aplicativo clickonce foi implantado (que eu passaria em relação a essa pasta para encontrar a pasta de seu interesse). Nenhuma outra pesquisa na Internet ou perguntas relacionadas ao SO apresentaram uma resposta também.

Todas as propriedades sugeridas estavam com falha devido ao objeto (por exemplo, ActivationUri) ser nulo ou estavam apontando para a pasta do aplicativo instalado em cache do PC local. Sim, eu poderia lidar com objetos nulos com facilidade, verificando IsNetworkDeployed - isso não é um problema -, mas surpreendentemente IsNetworkDeployed retorna false, mesmo que eu tenha, de fato, um local de pasta implantado em rede para o aplicativo clickonce. Isso ocorre porque o aplicativo está sendo executado nos bits em cache locais.

A solução é olhar para:

  • AppDomain.CurrentDomain.BaseDirectory quando o aplicativo está sendo executado no visual studio à medida que desenvolvo e
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation quando está executando normalmente.

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationretorna corretamente o diretório de rede em que meu aplicativo clickonce está implantado, em todos os casos. Ou seja, quando é lançado via:

  • setup.exe
  • MyClickOnceGreatApp.application
  • O atalho da área de trabalho criado após a primeira instalação e inicialização do aplicativo.

Aqui está o código que eu uso na inicialização do aplicativo para obter o caminho da pasta WorkAccounts. Obter a pasta do aplicativo implantado é simples, apenas não marcando para os diretórios pai:

string directoryOfInterest = "";
if (System.Diagnostics.Debugger.IsAttached)
{
    directoryOfInterest = Directory.GetParent(Directory.GetParent(Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).FullName).FullName).FullName;
}
else
{
    try
    {
        string path = System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
        path = path.Replace("file:", "");
        path = path.Replace("/", "\\");
        directoryOfInterest = Directory.GetParent(Directory.GetParent(path).FullName).FullName;
    }
    catch (Exception ex)
    {
        directoryOfInterest = "Error getting update directory needed for relative base for finding WorkAccounts directory.\n" + ex.Message + "\n\nUpdate location directory is: " + System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation.ToString();
    }
}
Kent Kruckeberg
fonte
0

Supondo que a pergunta seja sobre o acesso a arquivos na pasta do aplicativo após a instalação do aplicativo ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) no PC do usuário, há três maneiras de obter essa pasta pelo próprio aplicativo:

String path1 = System.AppDomain.CurrentDomain.BaseDirectory;
String path2 = System.IO.Directory.GetCurrentDirectory();    
String path3 = System.Reflection.Assembly.GetExecutingAssembly().CodeBase; //Remove the last path component, the executing assembly itself.

Eles funcionam no VS IDE e em um aplicativo ClickedOnce implantado / instalado, nenhuma verificação "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed" necessária. O ClickOnce seleciona todos os arquivos incluídos no projeto Visual Studio 2017 para que o aplicativo possa acessar todo e qualquer arquivo implantado usando caminhos relativos de dentro do aplicativo.

Isso é baseado no Windows 10 e Visual Studio 2017

BoiseBaked
fonte