如何获取ClickOnce应用程序的文件夹路径
我需要在控制台ClickOnce .application
(可执行文件)所在的同一文件夹中编写一个文件。它从中启动的文件夹。如何获取ClickOnce应用程序的文件夹路径
我尝试使用Application.StartupPath
& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
但路径c:\Documents & Settings
下指向一个子文件夹。我如何获得.application
所在的路径?
ClickOnce应用程序DO驻留在C:\ Documents &设置的子目录中。它们没有“干净的”安装目录,因为本地文件实质上是“临时”下载,以允许应用程序在本地PC上运行,并且应用程序的执行由部署它们的ClickOnce服务器控制,具体取决于发布设置(检查更新,版本要求等)。
路径在C指向一个子文件夹:\文件&设置
这是正确的。 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
我明白这一切。我想从我点击应用程序的位置获取文件夹。我没有权限访问C:\ Documents and Settings,因此如果我要使用该函数返回的文件夹路径,并且我不想使用硬编码的路径值,那么我将无法访问日志文件。 – 2010-03-09 20:10:00
ApplicationDeployment.CurrentDeployment.ActivationUri可能工作
“如果部署清单中的TrustUrlParameters属性为false,或者用户提供了UNC以打开部署或已打开部署,则为零长度字符串LLY。否则,返回值是用来启动应用程序的完整URL,包括任何参数。”
但我觉得你真正想要的是ApplicationDeployment.CurrentDeployment.DataDirectory,让你可以将数据写入到一个文件夹,当你更新应用程序无论如何都会丢失原始.exe文件夹中的内容,但是您可以将数据目录迁移到新版本的应用程序中。您的应用程序可以使用它的任何日志文件向此文件夹写入数据 - 而且很确定它的保证是可写的。
+1用于指出DataDirectory。感谢那 – 2012-11-07 21:01:20
我什么都没做,但是在部署之后,旧DataDirectory中的文件会自动复制到新的DataDirectory中。还没有.pre目录。 (.NET Framework 3.5和4.5) – 2014-03-25 07:02:58
要找到文件夹位置,您可以运行应用程序,打开任务管理器(CTRL-SHIFT-ESC),选择应用程序并右键单击|打开文件位置。
嘿,亲提示!但它不适用于老旧的XP机器。 :) – Jalal 2012-12-16 07:27:36
@Jalal for“老蹩脚的机器”去www.SysInternals.com并下载Process Explorer。我怀疑Win7的TaskManager中的变化,然后Win8只是从它复制。 – 2013-03-21 19:16:07
如何在客户计算机上运行的应用程序中实现这一目标? – user3285954 2015-09-10 16:46:00
我正在使用Assembly.GetExecutingAssembly().Location
获取在.Net 4.5.1中部署的应用程序的路径ClickOnce
。但是,不管部署方法如何(xcopy,ClickOnce,InstallShield,任何内容),您都不应写入应用程序部署到的任何文件夹,因为这些文件通常只能读取应用程序,尤其是在较新的Windows版本中服务器环境。
应用程序必须始终写入为此目的保留的文件夹。您可以从Environment.SpecialFolder Enumeration开始获取所需的文件夹。MSDN页面解释了每个文件夹的用途: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx
即,数据,日志和其他文件可以使用ApplicationData
(漫游),LocalApplicationData
(本地)或CommonApplicationData
。 临时文件使用Path.GetTempPath
或Path.GetTempFileName
。
以上在服务器和桌面上的工作也是如此。
编辑: Assembly.GetExecutingAssembly()
在主可执行文件中调用。
伟大的答案。谢谢 – stigzler 2015-11-09 13:42:17
这一直在为我工作的ClickOnce应用程序,以及也在VS开发环境中工作,同时调试同一个应用程序。 – Developer63 2016-06-02 19:08:47
这里是我发现,工作了,能够让我的ClickOnce应用程序的部署文件夹位置并没有被提及任何地方我在搜索看到,我的同类,具体情况:
- clickonce应用程序部署到公司LAN网络文件夹。
- clickonce应用程序设置为可在线或离线使用。
- 我的项目属性中的clickonce安装URL和更新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应用程序部署到的网络目录,在所有情况下。也就是说,当它通过推出:
- SETUP.EXE
- 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();
}
}
经过一番详尽的搜索,我终于找到了一种方法找到通过注册表混淆的文件夹名称。以下是一个简单的方法:
private static Tuple<string, string> GetClickonceDirectories()
{
var appToken = (string) Registry.GetValue(@"HKEY_CURRENT_USER\SOFTWARE\Classes\Software\Microsoft\Windows\CurrentVersion\Deployment\SideBySide\2.0", "ComponentStore_RandomString", null);
var dataToken = (string) Registry.GetValue(@"HKEY_CURRENT_USER\SOFTWARE\Classes\Software\Microsoft\Windows\CurrentVersion\Deployment\SideBySide\2.0\StateManager", "StateStore_RandomString", null);
if (string.IsNullOrWhiteSpace(appToken) || string.IsNullOrWhiteSpace(dataToken))
{
throw new Exception("Unable to find clickonce directories.");
}
var appDir =
[email protected]"{appToken.Substring(0, 8)}.{appToken.Substring(8, 3)}\{appToken.Substring(11, 8)}.{appToken.Substring(19, 3)}";
var dataDir =
[email protected]"Data\{dataToken.Substring(0, 8)}.{dataToken.Substring(8, 3)}\{dataToken.Substring(11, 8)}.{dataToken.Substring(19, 3)}";
var rootPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
rootPath = Path.Combine(rootPath, "Apps", "2.0");
return new Tuple<string, string>(Path.Combine(rootPath, appDir), Path.Combine(rootPath, dataDir));
}
我无法访问服务器上的C:\ Documents&Settings文件夹,这意味着我无权访问应用程序创建的文件。我从某个文件夹运行应用程序。这是该应用发布的文件夹。我如何获得该文件夹的路径? – 2010-03-01 21:20:32
哦,你想要部署网址。对不起,我一点都没有。您是否试图从ClickOnce应用程序或外部应用程序中获取它? – RobinDotNet 2010-03-10 09:52:12