问题描述
我已成功开发并部署了一个 ClickOnce 应用程序,该应用程序注册了一个关联的文件扩展名,例如 *.abc
.当我单击一个名为 x.abc
的文件或从命令提示符键入 x.abc
时,ClickOnce 应用程序将启动,我可以通过专用的API.我还可以使用以下代码以编程方式启动应用程序:
I have successfully developed and deployed a ClickOnce application which registers an associated file extension, for instance *.abc
. When I click on a file named x.abc
or if I type x.abc
from the command prompt, the ClickOnce application starts, and I can retrieve the file through the dedicated API. I can also launch the application programmatically with the following code:
System.Diagnostics.Process.Start ("x.abc");
在我的 Windows Vista 64 bit 盒子上一切正常.
Everything works fine on my Windows Vista 64 bit box.
但是,如果我尝试在 Windows 7(也是 64 bit)上做同样的事情,我会遇到一个非常奇怪的问题.这是我观察到的:
However, if I try to do exactly the same thing on a Windows 7 (also 64 bit ), I have a very strange problem. Here is what I observe:
- 从资源管理器中双击
x.abc
手动启动它. - 从命令提示符手动启动
x.abc
有效. Process.Start("x.abc")
不启动应用程序;但是,返回的进程对象显示没有错误,并且 ClickOnce 应用程序以某种方式立即退出.但即使是 ClickOnce 应用程序一开始的Trace
也永远无法到达.- 更奇怪的是,
Process.Start("x.bat")
文件x.bat
包含单行x.abc
也不启动 ClickOnce 应用程序!相同的x.bat
从 Explorer 作品开始(当然).
- Manual start of
x.abc
by double-clicking it from the Explorer works. - Manual start of
x.abc
from the command prompt works. Process.Start("x.abc")
does not start the application; however, the process object returned shows that there was not error and that the ClickOnce application somehow exited immediately. But even aTrace
at the very beginning of the ClickOnce application is never reached.- Stranger yet,
Process.Start("x.bat")
with a filex.bat
containing the single linex.abc
does not start the ClickOnce application either! Samex.bat
started from the Explorer works (of course).
尝试分析 ProcMon
发生的情况并不是很有帮助,因为在我看来,启动应用程序的 ClickOnce 过程很难遵循.我观察到 rundll32
开始工作,但没有任何失败的迹象.
Trying to analyse what happens with ProcMon
was not very helpful, as the ClickOnce process of launching an application is very difficult to follow, from my point of view. I observe rundll32
getting to work, but no evidence of any failure.
执行 Process.Start
的程序是一个完全信任的控制台应用程序,没有什么花哨的.
The program which is doing the Process.Start
is a full trust console application with really nothing fancy.
我看不出 ClickOnce 应用程序在 Windows 7 上的处理方式发生了什么变化,以及为什么 Process.Start
与从资源管理器启动文件的方式不同.值得一提的是,使用带有 ProcessStartInfo
的 Start
方法的更高级版本并将 UseShellExecute
设置为 true
并没有也可以帮忙.
I can't see what changed with respect to how ClickOnce applications are handled on Windows 7 and why Process.Start
would not do exactly the same as launching the file from Explorer. It's worth to mention that using more advanced versions of the Start
method with ProcessStartInfo
and setting UseShellExecute
to true
did not help either.
使用 Process.Start
启动 cmd
然后尝试启动 x.abc
显示完全相同的问题.如果我将环境设置与手动启动的 cmd
进行比较,我会发现 ProgramFiles
的定义方式存在差异(第一个指向 C:Program Files (x86)
而第二个指向 C:Program Files
).从我的 .NET 应用程序启动的应用程序是在 32 位仿真层 (SysWoW64) 上启动的.
Starting cmd
with Process.Start
and then trying to launch x.abc
shows exactly the same problem. If I compare the environment settings with a cmd
started manually, I see differences in how ProgramFiles
is defined (the first one points to C:Program Files (x86)
whereas the second points to C:Program Files
). The applications started from my .NET application are started on the 32-bit emulation layer (SysWoW64).
我能够通过启动 32 位版本的命令提示符(即 %windir%SysWoW64cmd.exe
),然后在提示符处键入 x.abc
.我还发现了一个丑陋的解决方法,即通过启动 %windir%Sysnativecmd.exe/C x.abc
而不是 从 32 位环境启动 64 位命令提示符代码>x.abc
.
I was able to reproduce the launch failure of x.abc
by starting a 32-bit version of the command prompt (that is, %windir%SysWoW64cmd.exe
) and then typing x.abc
at the prompt. I have also found an ugly workaround, which is to start a 64-bit command prompt from the 32-bit environment by launching %windir%Sysnativecmd.exe /C x.abc
instead of x.abc
.
但我宁愿使用一种干净的方式来做这件事(或者让 Microsoft 代表告诉我这确实是 Windows 7 和/或 ClickOncce 的一个问题,并且很快就会修复).
But I'd rather use a clean way of doing it (or have a Microsoft representative tell me that this is indeed an issue with Windows 7 and/or ClickOncce and that it will be fixed soon).
推荐答案
我想出了一个基于 .BAT 的解决方案,它很容易实现.假设您要启动与 *.abc
文件关联的 ClickOnce 应用程序,那么您只需在相同的文件夹,然后改为执行批处理文件.这是批处理脚本:
I've come up with a .BAT based solution, which is easy to implement. Say that you want to launch the ClickOnce application associated with *.abc
files, then you simply put a file with the same name, but with the *.bat
extension in the same folder, and then execute the batch file instead. Here is the batch script:
if exist "%windir%sysnativecmd.exe" goto :mode64bit
rem For a file named "C:fooxyz.bat", this will generate the corresponding
rem "C:fooxyz.abc" file, built as the concatenation of the drive (%~d0),
rem the folder (%~p0) and the file name (%~n0), plus ".abc":
"%~d0%~p0%~n0.abc"
goto :end
:mode64bit
rem When running in a 32-bit emulation environment on a real 64-bit system,
rem start the 64-bit version of CMD.EXE, and make if start the ".abc" file
rem for us:
C:Windowssysnativecmd.exe /c "%~d0%~p0%~n0.xgen"
:end
这可以直接在 *.abc
文件的调用者中实现,但有时批处理文件有助于过渡...
This could be implemented directly in the caller of the *.abc
files, but sometimes a batch file helps in the transition...
这篇关于ClickOnce 应用程序不通过 Process.Start(“x.abc") 启动,其中 *.abc 与 ClickOnce 应用程序关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!