Detecting that You’re Running in a ClickOnce Application


In my last post,  I mentioned that application scoped isolated storage only works if you’re running in a ClickOnce application.  That begs the question — how do I tell if I’m currently running in the context of a ClickOnce application?


You can see if a ClickOnce application is running in the current AppDomain by checking the AppDomain.CurrentDomain.ActivationContext property.  If that value is non-null, then the domain is running a ClickOnce application.  The ActivationContext will also get you the name of that application.


What you choose to do with that information is up to you.  In general, modifying your behavior depending on the context of the application leads to difficult to test and debug programs.  However, there may be situations (such as choosing an isolated storage scope), where having this information is necessary and useful.

Comments (15)

  1. Neno Loje says:

    How about using System.Deployment.Application.ApplicationDeployment.CurrentDeployment.IsNetworkDeployed

    MSDN Library states: "Gets a value indicating whether the current application is a ClickOnce application."

  2. shawnfa says:

    Hi Neno,

    Actually, the reason behind this post was someone attempting to use the ApplicationDeployment.CurrentDeployment property 🙂

    If you access CurrentDeployment when not running as a ClickOnce application, the property will throw an InvalidDeploymentException.

    -Shawn

  3. Neno Loje says:

    Interesting fact. 🙂

    But what sence does "IsNetworkDeployed" make then…?

    -Neno

  4. shawnfa says:

    It could detect if your ClickOnce application was installed off of a network location or installed off of a CD-ROM for instance.

    -Shawn

  5. Find

    Out What’s New with Code Access Security in the .NET Framework 2.0

    and its

    side notes (MSDN…

  6. Richard says:

    The IsNetworkDeployed property is static, which means you don’t need to access the CurrentDeployment property first.

    The documentation is correct – it returns true if the application is a ClickOnce application, and false otherwise. It has nothing to do with UNC vs CD deployment.

    However, looking at the IL for the property, it works by accessing the CurrentDeployment property and catching the InvalidDeploymentException. This would be quite an expensive call in a non-deployed application. Checking for a null ActivationContext is a much more efficient test.

    Perhaps the ApplicationDeployment class should be rewritten to avoid the exception? Something like this should do it:

    [PermissionSet(SecurityAction.Assert, Name=”FullTrust”)]
    private static ApplicationDeployment TryGetCurrentDeployment(out bool requireDemand)
    {
    requireDemand = false;

    if (null == _currentDeployment)
    {
    lock (lockObject)
    {
    if (null == _currentDeployment)
    {
    string appIdentity = null;
    ActivationContext context = AppDomain.CurrentDomain.ActivationContext;
    if (null != context) appIdentity = context.Identity.FullName;

    if (!string.IsNullOrEmpty(appIdentity))
    {
    _currentDeployment = new ApplicationDeployment(appIdentity);
    requireDemand = true;
    }
    }
    }
    }

    return _currentDeployment;
    }

    public static ApplicationDeployment CurrentDeployment
    {
    get
    {
    bool requireDemand;
    ApplicationDeployment result = TryGetCurrentDeployment(out requireDemand);

    if (null == result)
    throw new InvalidDeploymentException(Resources.GetString(“Ex_AppIdNotSet”));

    if (requireDemand)
    result.DemandPermission();

    return result;
    }
    }

    public static bool IsNetworkDeployed
    {
    get
    {
    bool requireDemand;
    ApplicationDeployment result = TryGetCurrentDeployment(out requireDemand);

    if (null == result)
    return false;

    if (requireDemand)
    result.DemandPermission();

    return true;
    }
    }

  7. Neno Loje says:

    Hmm… the following works perfectly:

    if (!ApplicationDeployment.IsNetworkDeployed)

    {

     // … and show warning if its not and abort startup…

     MessageBox.Show(Properties.Resources.NotNetworkDeployed, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

     return;

    }

  8. IsNetworkDeployed returns false when running in debug, true if run via the application launcher (program group). As you would expect.

    ActivationContext returns true even in debug mode…once you publish the application the first time. Even if you do not configure a URL to launch.

    I can’t use ActivationContext to verify the current deployment, because it fails if not network deployed:

    ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;

  9. shawnfa says:

    ActivationContext will be non-null in any situation that the AppDomain is configured to run a ClickOnce application.  (Or, in the future, any manifested style application).

    -Shawn

  10. How do you detect if you are running as a ClickOnce application?

    ActivationContext

    Well, use can use…

  11. I will attempt to not be rude but…

    If I build an executable and want to reference GetUserStoreForApplication it should not matter how I install the executable provided that the correct .Net framework is installed.

    The executable should contain the information that identifies the application.  

    It appears that the current .Net framework requires that an application be installed using the ClickOnce process before it will work.  Thus you have eliminated running applications from thumb (USB) drives if you publish them.

    Does that mean that Microsoft recommends that any application that might be run from a thumb drive not be defined as a ClickOnce application?

  12. shawnfa says:

    "Application" here is a bit of an overloaded term.  It’s being used to mean exactly "ClickOnce Application", and the isolated storage that it uses is in fact located in the ClickOnce application store.

    You can get IsolatedStorage for your individual assembly though if you use the GetUserStoreForAssembly calls – and those don’t require ClickOnce.   That’s most likely what you’ll be looking for.

    -Shawn

  13. rickb says:

    I thought that the whole point of the ClickOnce technology was that the developer should not have to care, during development, how the app will be deployed. That is besides some general guidelines like the app should not expect any particular install directory.

    I find myself struggling to use Isolated Storage from an app that may or may not be ClickOnce deployed, sometimes on the same machine.

    Specifically how do I code the needed workaround in the app so that in all deployment cases the same Isolated Store will be used to keep user preferences?

  14. shawnfa says:

    IsolatedStorage is scoped per-application, so in ClickOnce each individual ClickOnce app ends up with seperate isolated storage.  That means that if you repackage your app with different manifests, I don’t think you can use IsoStore to store preferences between them unfortunately.

    -Shawn