如何获取ClickOnce应用程序的文件夹路径


160

我需要在控制台ClickOnce .application(可执行文件)所在的同一文件夹中写入文件。从中启动的文件夹。

我尝试使用Application.StartupPathPath.GetDirectoryName(Assembly.GetExecutingAssembly().Location) 但路径指向的子文件夹c:\Documents & Settings。我如何获得.application居住者所在的路径?

Answers:


253

要找到文件夹位置,您只需运行该应用程序,打开任务管理器(CTRL-SHIFT-ESC),选择该应用程序,然后右键单击|打开文件位置。


3
嘿,亲们小费!但不适用于旧的XP机器。:)
Jalal

5
对于“旧的for脚机器”,@ Jalal请访问www.SysInternals.com并下载Process Explorer。我怀疑Win7的TaskManager中的更改,然后从中复制了Win8。
Arioch'The

1
您如何在客户计算机上运行的应用程序中实现这一目标?
user3285954'9

2
如果无法运行该应用程序,因为它会删除我迫切需要的日志文件,该怎么办?
托马什Zato -恢复莫妮卡

2
@Tony_Henrich您应该将其标记为正确答案
sparkyShorts '17

120

路径指向c:\ Documents&Settings下的子文件夹

那就对了。 ClickOnce applications在安装它们的用户的配置文件下安装。您是否采用了从正在执行的程序集中检索信息的路径,然后去检查它?

在Windows Vista和Windows 7上,您将在此处找到ClickOnce缓存:

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

在Windows XP上,您可以在这里找到它:

C:\Documents and Settings\username\LocalSettings\Apps\2.0\obfuscatedfoldername\obfuscatedfoldername

1
我都明白 我想要从应用程序中单击的文件夹。我没有访问C:\ Documents和Settings的权限,因此如果我要使用该函数返回的文件夹路径并且我不想使用硬编码的路径值,那么我将无权访问日志文件。 。
Tony_Henrich 2010年

25

ApplicationDeployment.CurrentDeployment.ActivationUri可能会起作用

“零长度的字符串,如果部署清单中的TrustUrlParameters属性为false,或者用户提供了UNC来打开部署或在本地打开了部署。否则,返回值为用于启动应用程序的完整URL,包括任何参数。”


但是我认为您真正想要的是ApplicationDeployment.CurrentDeployment.DataDirectory,它为您提供了一个可以向其中写入数据的文件夹。无论如何,当您更新应用程序时,都将丢失原始.exe文件夹中的内容,但是您可以将数据目录迁移到该应用程序的新版本中。您的应用程序可以使用其拥有的任何日志文件写入此文件夹-我很确定它保证是可写的。


我什么也没做,但是在部署之后,旧DataDirectory中的文件会自动复制到新DataDirectory中。也没有.pre目录。(.NET Framework 3.5和4.5)
Der_Meister

15

Assembly.GetExecutingAssembly().Location用来获取ClickOnce.Net 4.5.1中已部署应用程序的路径。

但是,无论部署方法(xcopy,ClickOnce,InstallShield等)如何,您都不应写入应用程序已部署到的任何文件夹,因为这些文件夹通常仅对应用程序是只读的,尤其是在较新的Windows版本和服务器环境中。

应用程序必须始终写入为此目的保留的文件夹。您可以从Environment.SpecialFolder枚举开始获取所需的文件夹。MSDN页面解释了每个文件夹的用途:http : //msdn.microsoft.com/zh-cn/library/system.environment.specialfolder.aspx

即用于数据,日志和其他文件的用户可以使用ApplicationData(漫游),LocalApplicationData(本地)或CommonApplicationData。对于临时文件,请使用Path.GetTempPathPath.GetTempFileName

以上工作也适用于服务器和台式机。

编辑: Assembly.GetExecutingAssembly()在主要可执行文件中被调用。


对于我来说,这对于ClickOnce应用程序一直有效,在调试同一应用程序时也可以在VS开发环境中使用。
Developer63

3

ClickOnce应用程序确实位于C:\ Documents&Settings的子目录中。它们没有“干净”的安装目录,因为本地文件实际上是“临时”下载的,以允许应用程序在本地PC上运行,并且该应用程序的执行是由ClickOnce服务器控制的,具体取决于发布设置(检查更新,版本要求等)。


我无权访问服务器上的C:\ Documents&Settings文件夹,这意味着我无权访问该应用程序创建的文件。我从某个文件夹运行该应用程序。这是应用程序发布的文件夹。如何获取该文件夹的路径?
Tony_Henrich'3

哦,您需要部署URL。抱歉,我一点都没明白。您是要从ClickOnce应用程序内部还是从外部应用程序获取它?
RobinDotNet

1

这是我发现能够获取clickonce应用程序的已部署文件夹位置的结果,而对于类似的特定情况,在搜索中没有看到任何提及的地方:

  • clickonce应用程序已部署到公司LAN网络文件夹。
  • clickonce应用程序设置为可在线或离线使用。
  • 我的项目属性中的clickonce安装URL和Update URL未指定任何内容。也就是说,没有单独的安装或更新位置。
  • 在发布选项中,我为clickonce应用程序创建了一个桌面快捷方式。
  • 我要在启动时获取路径的文件夹是我希望应用程序的DEV,INT和PROD版本访问的文件夹,而无需对路径进行硬编码。

这是我的用例的视觉效果:

在此处输入图片说明

  • 蓝色框是每个环境应用程序的目录位置。
  • 红色框的文件夹是我要获取路径的目录(首先需要获取应用程序的已部署文件夹位置“ MyClickOnceGreatApp_1_0_0_37”,该位置与OP相同)。

在返回clickonce应用程序部署到的文件夹时,我没有找到该问题的任何建议或它们的注释(然后我将相对于该文件夹移动以找到感兴趣的文件夹)。没有其他互联网搜索或相关的SO问题也没有找到答案。

所有建议的属性要么由于对象(例如ActivationUri)为空而失败,要么指向本地PC的缓存已安装的应用程序文件夹。是的,我可以通过检查IsNetworkDeployed来优雅地处理空对象-这不是问题-但令人惊讶的是,即使我确实具有clickonce应用程序的网络部署文件夹位置,IsNetworkDeployed仍返回false。这是因为应用程序是从本地缓存的位运行的。

解决方案是看:

  • AppDomain.CurrentDomain.BaseDirectory 当我在Visual Studio中运行应用程序时,
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation 当它正常执行时。

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation在所有情况下,均会正确返回将我的clickonce应用程序部署到的网络目录。也就是说,通过以下方式启动它时:

  • 安装程序
  • MyClickOnceGreatApp.application
  • 首次安装和启动应用程序时创建的桌面快捷方式。

这是我在应用程序启动时使用的代码,用于获取WorkAccounts文件夹的路径。只需不进入父目录即可简单地获取已部署的应用程序文件夹:

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();
    }
}

0

假设问题是关于在用户PC上安装ClickOnce(true == System.Deployment.ApplicationDeploy.IsNetworkDeployed)应用程序之后访问应用程序文件夹中的文件的,它们是通过应用程序本身获取此文件夹的三种方法:

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.

这些可以从VS IDE和已部署/已安装的ClickedOnce应用程序运行,而无需“ true == System.Deployment.ApplicationDeploy.IsNetworkDeployed”检查。ClickOnce会拾取Visual Studio 2017项目中包含的任何文件,因此实际上应用程序可以使用应用程序内部的相对路径访问任何和所有已部署的文件。

这基于Windows 10和Visual Studio 2017

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.