[.net] How to get folder path for ClickOnce application

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

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 .application resides in?

This question is related to .net windows clickonce

The answer is


ClickOnce applications DO reside 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).


ApplicationDeployment.CurrentDeployment.ActivationUri might work

"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."


BUT what I think you really want is ApplicationDeployment.CurrentDeployment.DataDirectory which 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.


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:

  • 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.

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).

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.

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.

The solution is to look at:

  • AppDomain.CurrentDomain.BaseDirectory when the application is being run within visual studio as I develop and
  • System.Deployment.Application.ApplicationDeployment.CurrentDeployment.UpdateLocation when it is executing normally.

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

  • setup.exe
  • MyClickOnceGreatApp.application
  • The desktop shortcut created upon first install and launch of the 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:

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

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.


I'm using Assembly.GetExecutingAssembly().Location to get the path to a ClickOnce deployed application in .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.

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

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

The above work on servers and desktops too.

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


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

That's right. ClickOnce applications are 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?

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

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

On Windows XP, you will find it here:

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

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:

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.

This is based on Windows 10 and Visual Studio 2017


Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to windows

"Permission Denied" trying to run Python on Windows 10 A fatal error occurred while creating a TLS client credential. The internal error state is 10013 How to install OpenJDK 11 on Windows? I can't install pyaudio on Windows? How to solve "error: Microsoft Visual C++ 14.0 is required."? git clone: Authentication failed for <URL> How to avoid the "Windows Defender SmartScreen prevented an unrecognized app from starting warning" XCOPY: Overwrite all without prompt in BATCH Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory how to open Jupyter notebook in chrome on windows Tensorflow import error: No module named 'tensorflow'

Examples related to clickonce

Best way to deploy Visual Studio application that can run without installing IIS - can't access page by ip address instead of localhost How to find the Target *.exe file of *.appref-ms How to get folder path for ClickOnce application Error message "Unable to install or run the application. The application requires stdole Version 7.0.3300.0 in the GAC"