ClickOnce .net7 WPF app - Why is ActivationUri null?

123 Views Asked by At

Hey I'm trying to launch an offline .net7 clickonce wpf app from another app with arguments. Following several other threads and blogposts led me to the following solution. Let's call the launcher 'App 1' and the launched 'App 2'. App 2 uses the following code on startup:

try
{
    NameValueCollection nameValueTable = new();

    if (ApplicationDeployment.IsNetworkDeployed)
    {
        string? queryString = ApplicationDeployment.ActivationUri?.Query;
        if (ApplicationDeployment.ActivationUri == null)
        {
            MessageBox.Show("ActivationUri is null!");
            return null;
        }
        if (string.IsNullOrWhiteSpace(queryString))
        {
            MessageBox.Show("Query string empty!");
            return null;
        }

        nameValueTable = HttpUtility.ParseQueryString(queryString);
    }

    return (nameValueTable);
}
catch (Exception e)
{
    MessageBox.Show($"Error:{Environment.NewLine}{e.Message}");
    return null;
}

Aaand unfortunately what App 1 does is irrelevant as ActivationUri is NULL no matter if App 2 is launched from a shortcut or using Process.Start. When publishing App 2 the setting: "Allow URL parameters to be passed to application" is set to true. Any idea why ActivationUri is null?

Or alternatively: Do you know of a different way I can pass/read arguments than ApplicationDeployment.ActivationUri.Query?

Relevant documentation: https://learn.microsoft.com/en-us/visualstudio/deployment/access-clickonce-deployment-properties-dotnet?view=vs-2022

Edit: Maybe what App 1 does is not that irrelevant. I've seen some people claim that ActivationUri is not set if the application is launched locally, but others say this method should work if launched locally... I need to be able to have launch parameters work even if the device does not currently have access to the network drive the application updates/installs from... This is how I launch the app:

string shortcutPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.Programs)}\\Company\\{myAppName}.appref-ms";

var p = new Process();
p.StartInfo = new ProcessStartInfo(shortcutPath, "arg test")
{
    UseShellExecute = true,
};

Edit 2: Alright so my solution is a mix of several solutions and it turns out my implementation will not work offline. This blog explains how to get offline click once arguments by calling "AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData", but unfortunately 'ActivationArguments' does not exist in AppDomain.CurrentDomain.SetupInformation... Which I can not find any mention of anywhere :/ Any thoughts?

Edit 3: It turns out I wasn't testing my application correctly - I never passed the arguments, but it also turns out that parsing ANY argument(s) crashes the app before even reaching OnStartup... Even in a completely empty wpf project. What?!

1

There are 1 best solutions below

5
egeer On

This is a tricky one.

Microsoft says not to do what I have done here, but it is working. I was able to get the args to work by referencing the installed .exe. (for me it was pretty burried in local app data). Then I was able to use the args from the StartupEventArgs.

public partial class App1 : Application
{
    string app2Path = Environment.ExpandEnvironmentVariables(@"%localappdata%\Apps\2.0\EH2OVAR3.62J\53Y7M9Y1.QOB\app2..tion_0000000000000000_0001.0000_6a7609a423d3786f\App2.exe");
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var psi = new ProcessStartInfo(app2Path, "arg test");
        Process.Start(psi);
    }
}
public partial class App2 : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        var msg = string.Join("\n", e.Args);
        MessageBox.Show(msg);
    }
}

From Microsoft's docs: https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start?view=net-7.0

You can start a ClickOnce application by setting the fileName parameter to the location (for example, a Web address) from which you originally installed the application. Do not start a ClickOnce application by specifying its installed location on your hard drive.

However, like you, when I tried that I immediately got an error.

Regarding the ApplicationDeployment.ActivationUri.Query, I don't think that will work for your case, since you said this is an offline app. I assume that means you are deploying to your local and installing from there. In that case, I am not sure if there will not be an activation uri, since it looks like that is intended for web-deployed ClickOnce apps.