12
votes

My goal is to actually achieve launching my ClickOnce application in one click (or two I guess). The application has some prerequisites which need to be installed. The normal way of ensuring they are installed that Microsoft provides involves having the user decide whether he has the prerequisites or not and downloading and installing a "setup.exe" which installs them and runs the ClickOnce application. This involves downloading the EXE file (one click), running it (two clicks), then after prerequisites are installed, clicking again to run the ClickOnce application.

I'm trying to reduce this process to one or two clicks: - Click a link on my website to the ClickOnce .application file. - Click again to run it.

I have made ANOTHER ClickOnce application, which includes a setup.exe. It checks if the prerequisites are installed, and if they are it runs the other ClickOnce application automatically. If not, it runs the included setup.exe and then runs the other ClickOnce application.

My problem is that when I try to run the other ClickOnce application from this one, it simply opens my web browser and downloads the .application file without running it.

I'm trying to use the following to start the ClickOnce application from inside my C# code:

Process.Start(ApplicationURL);

I just want this to automatically launch the application at ApplicationURL. Is there a way to skip the browser involvement that I'm seeing?

(My question is very similar to Stack Overflow question Run a ClickOnce application from a webpage without user action).

5
What is your default browser? Have you tried: Process.Start("iexplore.exe", ApplicationURL)?M.Babcock
Ok I just found the answer to my own question. The problem was that my default browser is google chrome, which doesn't quite know how to handle clickOnce applications. I changed my code to: ProcessStartInfo startInfo = new ProcessStartInfo("Iexplore"); startInfo.Arguments = ApplicationURL; Process agentStudio = Process.Start(startInfo); Now it launches the application using internet explorer, and the application now really works as a "one click" application.Jschiff
Thanks M. Babcock, discovered it independently as you replied!Jschiff
There is no need to instantiate a ProcessStartInfo object if all you're going to do is set the fileName and arguments. This is what the Process.Start(string, string) overload is for.M.Babcock
What is your path like? I am able to start one ClickOnce application from another simply by using Process.Start(<path to .application file>);. and that is with a UNC path (\\server\share\folder\program.application)Dave Cousineau

5 Answers

17
votes

As pointed out in the comments, you can start the iexplore.exe process to launch a ClickOnce application without any dependency on the default browser. You can also launch the ClickOnce application the same way Windows Explorer launches it, using dfshim.dll.

Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + ApplicationURL);

There are a few other articles online that discuss using this strategy, but I did not find any official documenation of dfshim.dll,ShOpenVerbApplication.

  • Another Stack Overflow question mentions using a custom .exe to install the .NET Framework and then launch a ClickOnce application via ShOpenVerbApplication.
  • Scott Hanselman discusses ShOpenVerbApplication as the default file mapping for files with the application/x-ms-application MIME type in a post about Firefox and ClickOnce.

Update

As the other Stack Overflow question mentions, you can also use dfshim.dll's LaunchApplication command, which is documented on Microsoft's site. However, that command is not available in some older versions of the .NET Framework.

1
votes

Have a look at the Microsoft walkthrough for installing manually via InPlaceHostingManager. You have the ability to customize programmatically.

1
votes

There are at least 2 other methods for launching ClickOnce applications.

One simple method is Process.Start("PresentationHost.exe", "-launchApplication " + ApplicationURL); as documented by Microsoft here.

A more sophisticated method is calling ShellExecuteEx() Win32 API with code like this:

SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpFile = ApplicationURL;
info.nShow = SW_SHOWNORMAL;
info.fMask = SEE_MASK_CLASSNAME;
info.lpClass = "Application.Manifest";
ShellExecuteEx(ref info);

Required Win32 API import and structure definitions can be found here. This method will query registry and run "rundll32.exe dfshim.dll,ShOpenVerbApplication" (or anything else that is configured under HKEY_CLASSES_ROOT\Application.Manifest).

0
votes

Following are the ways to launch clickonce.application

Approach 1: Launch from URL

Method 1:

string app = "http://domain.xyz/ClickOnce.application";
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + app);

Method 2:

string app = "http://domain.xyz/ClickOnce.application";
Process.Start("IExplore.exe", app);

Approach 2: Directly launch ClickOnce.application from .application file

string app = "file://C:/ClickOnce.application";
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + app);
0
votes

And another option is using Launcher::LaunchUriAsync with LauncherOptions.ContentType = "application/x-ms-application". This is known a "uri direct invoke"