Search code examples
wpfclickoncefile-association

WPF; click once; Double Click file to launch; VS 2008


My application is only for me and co-workers, so I don't care if it's Click-Once or copy-the-exe. I want to be able to click a file with given extension in windows explorer and have my program launch and open that file. I can't get it to capture the file name.

Ostensible solution:

Link

The code I'm trying is below and at this point all I'm trying to do is put the name of the clicked file in a text box. I suspect my relevant ignorance is about how to reference the click-once application from windows explorer. When I build I end up with a file called setup.exe, a file called Wis.application, and when I click on "setup" to install it, I end up with a shortcut of type "Click-once application reference" in "C:\Users\ptom\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Wis". I've tried associating files with that shortcut created by install, and associating files with setup.exe. When I click on the file, the application launches but indicates that AppDomain.CurrentDomain.SetupInformation.ActivationArguments is null. (By "indicates" I mean the text box gets filled in with the text from where I test to see if it's null). If I run the app from debug, or just by running it from the start menu, it does what I'd expect, following the code path that indicates that ActivationArguments is not null, but that its ActivationData (string[]) is of length 0.

Here is the code from app.xaml.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;

namespace Wis
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {

            // Check if this was launched by double-clicking a doc. If so, use that as the

            // startup file name.
            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments == null)
            {
                this.Properties["DoubleClickedFileToLoad"] = "There were no activation arguments AGAIN";
            }
            else
            {
                if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData != null
                                   && AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Length > 0)
                {
                    this.Properties["DoubleClickedFileToLoad"] =
                    AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0];
                }
                else
                {
                    this.Properties["DoubleClickedFileToLoad"] = "Type in a file name";
                }
            }


        }
    }
}
            

Thanks


Solution

  • First of all you should add file assoc for ClickOnce-publish (Select Project->Properties->Publish-Options->File Associations)
    Then add Reference to "System.Deployment"
    Then you could extract path in App.cs in such a manner, depending on type of startup (ClickOnce or Local)

        protected override void OnStartup(System.Windows.StartupEventArgs e)
        {
            var path = GetPath (e);
        }        
    
        private static string GetPath(StartupEventArgs e)
        {
            if (!ApplicationDeployment.IsNetworkDeployed)
                return e.Args.Length != 0 ? e.Args[0] : null;
            if (AppDomain.CurrentDomain.SetupInformation.ActivationArguments == null)
                return null;
            var args = AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData;
            return args == null || args.Length == 0 ? null : new Uri(args[0]).LocalPath;
        }