我有一个Java 9应用程序,正在尝试为Windows应用商店打包。奇怪的是,当我直接运行exe-launcher时,它可以按预期工作,但是当我通过APPX包运行启动器时,出现以下奇怪的错误:
Exception in thread "Swing-Shell" java.lang.InternalError: Could not
initialize COM: HRESULT=0x80010106
at java.desktop/sun.awt.shell.Win32ShellFolderManager2.initializeCom(Native Method)
at java.desktop/sun.awt.shell.Win32ShellFolderManager2$ComInvoker$1.run(Unknown Source at java.base/java.lang.Thread.run(Unknown Source)
HRESULT=0x80010106
意味着RPC_E_CHANGED_MODE
我猜这意味着COM已经以某种方式在MTA模式下初始化了。但是,为什么这只是Windows Bridge沙箱中的一个问题?Windows Bridge是否pre-initialize
出于某种原因以某种方式COM?
我不确定这是Java 9问题,还是Desktop Bridge问题,或两者都是。是否有人对如何确定问题或解决方法的原因有任何想法?
我做了一个最小的示例项目来重现该问题
该应用程序在直接执行时可以运行,但在通过APPX启动器执行时则不能运行。为什么?
依赖COM初始化(D3DPipeline,Sound和Windows Shellfolder访问)的JDK部分都遵循相同的模式:
CoInitialize
叫做CoUnitialize
被称为这与MSDN为COM提供的文档一致,并且分析是正确的,该错误表明该COM子系统已经初始化为MTA线程化。
因此,我修改了Java启动器(jvm.dll),并将调试语句插入到os_windows.cpp中的某些本机方法中。我专注于线程方法。我发现的是:
create_main_thread
,create_os_thread
,pd_start_thread
所有COM运行尚未初始化thread_native_entry
)已在COM初始化的情况下运行我仔细研究了一下,_beginthreadex
的确找到了堆栈溢出方面的领先者。这使我看到了threadex.c的源代码,该代码是Visual Studio 2013 Express安装的一部分。
在这里,您_beginthreadex
不会直接启动提供的线程功能,而是先运行库初始化程序(_threadstartex
)。该初始化程序的一部分内容为:
_ptd->_initapartment = __crtIsPackagedApp();
if (_ptd->_initapartment)
{
_ptd->_initapartment = _initMTAoncurrentthread();
}
_callthreadstartex();
_crtIsPackagedApp
通过内核函数检测应用程序是否以“ PackagedApp”(即AppX包)运行,如果是,则RoInitialize
调用该函数,据我了解,该函数就像CoInitialize的老大哥一样。
长话短说:如果您的应用程序是使用Visual Studio 2013构建的,并作为打包的应用程序运行,则您的环境将不完整。
已确认,Oracle JDK的工作版本是使用VS2010 SP1构建的,而损坏的版本是使用VS2013SP4构建的。
有了以上信息,谷歌终于找到了支持该分析的参考:
https://blogs.msdn.microsoft.com/vcblog/2016/07/07/using-visual-c-runtime-in-centennial-project/
引用那篇文章:
请注意,在Windows 8时间框架内创建的现有VC ++ 12.0库具有运行时检查功能,以确定应用程序是否在应用程序容器下运行。当将桌面应用程序作为打包的应用程序运行时,这些检查可能会限制桌面应用程序的功能或使其表现为UWA(通用Windows应用程序)(限制文件系统访问或创建线程初始化MTA等)。我们已在这些框架软件包中包含的VC ++库中修复了此问题,从而消除了桌面应用程序中现代应用程序的限制。
因此,我看到了用于修复应用程序的选项,这些选项应作为AppX软件包分发:
msvcr120.dll
更新包中的固定版本替换与Java 9(并且我也假定为Java 10)捆绑在一起的我将使用第二个版本,并对此进行了测试。从全新的Windows 10系统开始,我安装了JDK 9.0.4,克隆了提供的测试用例,使用本地安装的JRE(不是JDK!)对其进行了修改,并构建了appx包。运行此,我重现了问题。然后msvcr120.dll
,我将系统安装的JRE文件夹中的替换为APPX容器中包含的,来自:
https://www.microsoft.com/zh-cn/download/details.aspx?id=53176
提示:* .appx只是具有附加签名的ZIP文件,因此您可以重命名它们并提取内容。
我重建了测试用例,它可以正常工作(不再有COM初始化错误)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句