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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2359026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 14:00:57  来源:igfitidea点击:

How to get folder path for ClickOnce application

.netwindowsclickonce

提问by Tony_Henrich

I need to write a file in the same folder where a console ClickOnce .application(executable file) resides. The folder where it launches from.

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

I tried using Application.StartupPath& Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)but the path is pointing to a subfolder under c:\Documents & Settings. How do I get the path where the .applicationresides in?

我尝试使用Application.StartupPath&Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)但路径指向c:\Documents & Settings. 我如何获得.application所在的路径?

回答by Erik Vullings

To find the folder location, you can just run the app, open the task manager (CTRL-SHIFT-ESC), select the app and right-click|Open file location.

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

回答by RobinDotNet

path is pointing to a subfolder under c:\Documents & Settings

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

That's right. ClickOnce applicationsare installed under the profile of the user who installed them. Did you take the path that retrieving the info from the executing assembly gave you, and go check it out?

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

On windows Vista and Windows 7, you will find the ClickOnce cache here:

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

c:\users\username\AppData\Local\Apps.0\obfuscatedfoldername\obfuscatedfoldername

On Windows XP, you will find it here:

在 Windows XP 上,您可以在此处找到它:

C:\Documents and Settings\username\LocalSettings\Apps.0\obfuscatedfoldername\obfuscatedfoldername

回答by Simon_Weaver

ApplicationDeployment.CurrentDeployment.ActivationUrimight work

ApplicationDeployment.CurrentDeployment.ActivationUri可能有效

"A zero-length string if the TrustUrlParameters property in the deployment manifest is false, or if the user has supplied a UNC to open the deployment or has opened it locally. Otherwise, the return value is the full URL used to launch the application, including any parameters."

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



BUT what I think you really want is ApplicationDeployment.CurrentDeployment.DataDirectorywhich gives you a folder you can write data to. When you update the application anyways you'll lose what was in the original .exe folder, but you can migrate the data directory over to a new version of the app. Your app can write to this folder with whatever log files it has - and I'm pretty sure its guaranteed to be writable.

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

回答by user3285954

I'm using Assembly.GetExecutingAssembly().Locationto get the path to a ClickOncedeployed application in .Net 4.5.1.

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

However, you shouldn't write to any folder where your application is deployed to ever, regardless of deployment method (xcopy, ClickOnce, InstallShield, anything) because those are usually read only for applications, especially in newer Windows versions and server environments.

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

An app must always write to the folders reserved for such purposes. You can get the folders you need starting from Environment.SpecialFolder Enumeration. The MSDN page explains what each folder is for: http://msdn.microsoft.com/en-us/library/system.environment.specialfolder.aspx

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

I.e. for data, logs and other files one can use ApplicationData(roaming), LocalApplicationData(local) or CommonApplicationData. For temporary files use Path.GetTempPathor Path.GetTempFileName.

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

The above work on servers and desktops too.

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

EDIT: Assembly.GetExecutingAssembly()is called in main executable.

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

回答by NebuSoft

ClickOnce applications DOreside in a subdirectory of C:\Documents & Settings. They don't have "clean" installation directories because the local files are essentially "temporarily" downloaded to allow the application to run on the local PC and execution of the application is controlled from the ClickOnce server that they are deployed on depending on publishing settings (Checking for updates, version requirements, etc).

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

回答by Kent Kruckeberg

Here's what I found that worked for being able to get the deployed folder location of my clickonce application and that hasn't been mentioned anywhere I saw in my searches, for my similar, specific scenario:

这是我发现可以获取我的 clickonce 应用程序的部署文件夹位置的方法,并且在我的搜索中看到的任何地方都没有提到,对于我类似的特定场景:

  • The clickonce application is deployed to a company LAN network folder.
  • The clickonce application is set to be available online or offline.
  • My clickonce installation URL and Update URLs in my project properties have nothing specified. That is, there is no separate location for installation or updates.
  • In my publishing options, I am having a desktop shortcut created for the clickonce application.
  • The folder I want to get the path for at startup is one that I want to be accessed by the DEV, INT, and PROD versions of the application, without hardcoding the path.
  • clickonce 应用程序部署到公司 LAN 网络文件夹。
  • clickonce 应用程序设置为在线或离线可用。
  • 我的项目属性中的 clickonce 安装 URL 和更新 URL 未指定任何内容。也就是说,没有单独的安装或更新位置。
  • 在我的发布选项中,我为 clickonce 应用程序创建了一个桌面快捷方式。
  • 我想要在启动时获取路径的文件夹是我想要由应用程序的 DEV、INT 和 PROD 版本访问的文件夹,而无需对路径进行硬编码。

Here is a visual of my use case:

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

enter image description here

在此处输入图片说明

  • The blue boxed folders are my directory locations for each environment's application.
  • The red boxed folder is the directory I want to get the path for (which requires first getting the app's deployed folder location "MyClickOnceGreatApp_1_0_0_37" which is the same as the OP).
  • 蓝色方框文件夹是我在每个环境中的应用程序的目录位置。
  • 红框文件夹是我想要获取路径的目录(这需要首先获取应用程序的部署文件夹位置“MyClickOnceGreatApp_1_0_0_37”,与OP相同)。

I did not find any of the suggestions in this question or their comments to work in returning the folder that the clickonce application was deployed to (that I would then move relative to this folder to find the folder of interest). No other internet searching or related SO questions turned up an answer either.

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

All of the suggested properties either were failing due to the object (e.g. ActivationUri) being null, or were pointing to the local PC's cached installed app folder. Yes, I could gracefully handle null objects by a check for IsNetworkDeployed - that's not a problem - but surprisingly IsNetworkDeployed returns false even though I do in fact have a network deployed folder location for the clickonce application. This is because the application is running from the local, cached bits.

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

The solution is to look at:

解决办法是看:

  • AppDomain.CurrentDomain.BaseDirectorywhen the application is being run within visual studio as I develop and
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationwhen it is executing normally.
  • AppDomain.CurrentDomain.BaseDirectory当我开发和应用程序在 Visual Studio 中运行时
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation正常执行的时候。

System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocationcorrectly returns the network directory that my clickonce application is deployed to, in all cases. That is, when it is launched via:

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

  • setup.exe
  • MyClickOnceGreatApp.application
  • The desktop shortcut created upon first install and launch of the application.
  • 安装程序
  • MyClickOnceGreatApp.application
  • 首次安装和启动应用程序时创建的桌面快捷方式。

Here's the code I use at application startup to get the path of the WorkAccounts folder. Getting the deployed application folder is simple by just not marching up to parent directories:

这是我在应用程序启动时用来获取 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();
    }
}

回答by BoiseBaked

Assuming the question is about accessing files in the application folder after the ClickOnce (true == System.Deployment.ApplicationDeploy.IsNetworkDeployed) application is installed on the user's PC, their are three ways to get this folder by the application itself:

假设问题是关于在用户 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.

These work from VS IDE and from a deployed/installed ClickedOnce app, no "true == System.Deployment.ApplicationDeploy.IsNetworkDeployed" check required. ClickOnce picks up any files included in the Visual Studio 2017 project so really the application can access any and all deployed files using relative paths from within the application.

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

This is based on Windows 10 and Visual Studio 2017

这是基于 Windows 10 和 Visual Studio 2017