从另一个ClickOnce应用程序启动ClickOnce应用程序

12
我的目标是实现一键式(或者两次点击)启动ClickOnce应用程序。该应用程序有一些必备的先决条件需要安装。微软提供的确保这些先决条件已经安装的正常方法是让用户决定他是否拥有这些先决条件,并下载和安装一个名为“setup.exe”的文件,该文件将它们安装并运行ClickOnce应用程序。这个过程需要下载EXE文件(一次点击),运行它(两次点击),然后在安装先决条件之后再点击一次才能运行ClickOnce应用程序。
我试图把这个过程减少到一次或两次点击: - 在我的网站上单击链接以获取ClickOnce的.application文件。 - 再次单击以运行它。
我又做了另一个ClickOnce应用程序,其中包含一个setup.exe 。它会检查是否安装了必备的先决条件,如果已安装,则自动运行其他ClickOnce应用程序。如果没有安装,则运行包含的setup.exe,然后运行其他ClickOnce应用程序。
我的问题是当我尝试从其中一个应用程序运行其他ClickOnce应用程序时,它只是打开我的Web浏览器并下载.application文件而不运行它。
我正在尝试使用以下代码在我的C#代码中启动ClickOnce应用程序:
Process.Start(ApplicationURL);

我只想让它自动启动 ApplicationURL 上的应用程序。有没有方法可以跳过我看到的浏览器参与?

(我的问题与 Stack Overflow 的问题非常相似:在没有用户操作的情况下从网页运行 ClickOnce 应用程序。)


你的默认浏览器是什么?你尝试过:Process.Start("iexplore.exe", ApplicationURL)吗? - M.Babcock
2
好的,我刚刚找到了我的问题的答案。 问题是我的默认浏览器是谷歌浏览器,它不太知道如何处理ClickOnce应用程序。 我改变了我的代码:ProcessStartInfo startInfo = new ProcessStartInfo("Iexplore"); startInfo.Arguments = ApplicationURL; Process agentStudio = Process.Start(startInfo);现在它使用Internet Explorer启动应用程序,并且应用程序现在确实作为“一键”应用程序工作。 - Jschiff
谢谢M. Babcock,我已经独立发现了,就在你回复之前! - Jschiff
如果您只是要设置 fileName 和 arguments,则无需实例化 ProcessStartInfo 对象。这就是 Process.Start(string, string) 重载的作用。 - M.Babcock
请提供您的工作答案作为问题的补充或答案。 - Florian
1
你的路径是怎样的?我可以通过使用 Process.Start(<.application 文件的路径>) 来从另一个 ClickOnce 应用程序中启动一个应用程序,并且这可以使用 UNC 路径(\\server\share\folder\program.application)实现。 - Dave Cousineau
5个回答

18

正如评论中指出的那样,您可以启动 iexplore.exe 进程来启动 ClickOnce 应用程序,而不依赖于默认浏览器。您还可以使用 dfshim.dll 以与 Windows Explorer 启动 ClickOnce 应用程序相同的方式来启动它。

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

有一些其他的文章讨论了使用该策略,但我没有找到任何官方文档关于dfshim.dll,ShOpenVerbApplication的内容。

  • 另一个Stack Overflow问题提到使用自定义的.exe安装.NET Framework,然后通过ShOpenVerbApplication启动ClickOnce应用程序。
  • Scott Hanselman在一篇关于Firefox和ClickOnce的文章中讨论了ShOpenVerbApplication作为具有application/x-ms-application MIME类型的文件的默认文件映射。

更新

正如另一个Stack Overflow问题所提到的,您也可以使用dfshim.dllLaunchApplication命令,在微软的网站上有记录。但是,该命令在某些旧版本的.NET Framework中不可用。


这些工作得很好,但是我该如何通过身份验证呢?SSRS网站需要一个,如果没有凭据,应用程序下载将失败。我正在尝试使用InPlaceHostingManager的组合(我已经知道它了,给@dgp点赞),以及一个隐藏的嵌入式Web浏览器控件,但它看起来很丑。 - Csaba Toth

1

安装应用程序的好方法,但无法“启动”应用程序。根据文档:“InPlaceHostingManager可以安装ClickOnce应用程序,但无法执行它。此类中的某些方法(例如Execute)是保留的,仅在下载运行在Web浏览器内的基于Windows Presentation Foundation的应用程序时使用。”dfshim方法允许安装和启动应用程序。 - mikdav

1

至少有两种方法可以启动ClickOnce应用程序。

一种简单的方法是使用Microsoft文档此处记录的Process.Start("PresentationHost.exe", "-launchApplication " + ApplicationURL);

一种更为复杂的方法是使用类似下面代码的ShellExecuteEx() Win32 API进行调用:

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

需要 Win32 API 导入和结构定义可在 这里 找到。该方法将查询注册表并运行 "rundll32.exe dfshim.dll,ShOpenVerbApplication"(或任何已配置在 HKEY_CLASSES_ROOT\Application.Manifest 下的内容)。

0
另一个选项是使用Launcher::LaunchUriAsync和LauncherOptions.ContentType = "application/x-ms-application"。这被称为“uri直接调用”。

0
以下是启动 ClickOnce 应用程序的方法: 方法一:通过 URL 启动
方法二:
string app = "http://domain.xyz/ClickOnce.application";
Process.Start("rundll32.exe", "dfshim.dll,ShOpenVerbApplication " + app);

方法二:

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

方法二: 直接从 .application 文件启动 ClickOnce.application

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接