2

如果我使用“仅链接 SDK”构建我的应用程序以进行发布构建(用于在没有 Mono 的机器上进行 beta 测试),它不再启动 - 它似乎立即崩溃。

如果我运行我的应用程序命令行,这是崩溃:

[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for System.Xml.Serialization.XmlSerializer ---> System.Configuration.ConfigurationErrorsException: Error Initializing the configuration system. ---> System.MissingMethodException: Default constructor not found for type System.Configuration.ExeConfigurationHost.
  at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0 
  at System.Configuration.InternalConfigurationSystem.Init (System.Type typeConfigHost, System.Object[] hostInitParams) [0x00000] in <filename unknown>:0 
  at System.Configuration.InternalConfigurationFactory.Create (System.Type typeConfigHost, System.Object[] hostInitConfigurationParams) [0x00000] in <filename unknown>:0 
  at System.Configuration.ConfigurationManager.OpenExeConfigurationInternal (ConfigurationUserLevel userLevel, System.Reflection.Assembly calling_assembly, System.String exePath) [0x00000] in <filename unknown>:0 
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Configuration.ClientConfigurationSystem.get_Configuration () [0x00000] in <filename unknown>:0 
  at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection (System.String configKey) [0x00000] in <filename unknown>:0 
  at System.Configuration.ConfigurationManager.GetSection (System.String sectionName) [0x00000] in <filename unknown>:0 
  at System.Configuration.ConfigurationSettings.GetConfig (System.String sectionName) [0x00000] in <filename unknown>:0 
  at System.Xml.Serialization.XmlSerializer..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---

有什么方法可以在这里添加适当的[Preserve]属性吗?或者也许强制链接器保留这个类?

更多信息:

  • 我的应用是一个MonoGame游戏,名为Draw a Stickman: EPIC
  • 如果我不链接任何程序集,它运行得很好,但我的应用程序要大 10MB
  • 最初我从带有 Tao.Sdl.dll 的链接器中得到了一些错误,但我在我的主项目中引用了它,并修复了它。
  • 我的目标是 10.6 及更高版本
4

3 回答 3

4

与 MonoTouch 相比,MMP (MonoMac Packer)的一个主要区别mtouch是 MonoMac 使用完整的 .NET 框架。这使得链接应用程序变得更加复杂。

为什么 ?主要是因为System.Configuration(它是一个程序集,但它也是其他几个程序集中的命名空间)。它使用反射和.config文件来设置自己 - 链接器无法确切知道(因为它可以在执行之间更改)您的应用程序需要什么。

MMP试图涵盖最常见的情况(例如 System.Net),但目前它不能处理在 BCL 中使用 System.Configuration 的所有情况。

现在要解决这个问题......需要告诉链接器包含您的应用程序在运行时需要的所有内容。例如

[ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: 
An exception was thrown by the type initializer for System.Xml.Serialization.XmlSerializer 
---> System.Configuration.ConfigurationErrorsException: Error Initializing the configuration system. 
---> System.MissingMethodException: Default constructor not found for type System.Configuration.ExeConfigurationHost.

这意味着您的应用程序正在使用(即使是间接使用)System.Configuration.ExeConfigurationHost并且链接器无法检测到它(它通过反射使用)。

从那里,您需要构建一个 XML 文件链接器介绍这些所需的类型(可能会有其他类型,可能还有很多其他类型)。然后将该 XML 文件反馈给 MMP (--xml=FILE),因此链接器不会尝试从链接的应用程序中删除这些类型/方法。

替代方案是不链接或不链接某些程序集(例如--linkskip=System)。YMMV。

更新:新的Xamarin.Mac是 MonoMac 的超集,包含将解决此异常的链接器的增强版本(但可能不是所有其他异常,请为它们填写错误报告)。

于 2012-12-10T16:45:50.900 回答
1

几个想法:

  • 控制台应用程序中是否打印了任何内容?
  • 尝试从终端执行 MyApp.app/Contents/MacOS/(binary) ,这至少应该在终端上打印一些东西。
于 2012-12-10T14:10:14.013 回答
1

发生这种情况是因为 mmp(MonoDevelop 中内置的 MonoMac 打包程序)从框架中剥离了太多内容。尤其是在使用 XML 时。

我发现您必须将这些附加参数传递给 mmp 才能使 XML 工作:

--linkskip=System.Net --linkskip=System --linkskip=System.Configuration --linkskip=mscorlib

不幸的是,monodevelop 项目配置中的 mmp 参数不起作用(不保存)。我已经报告了这些错误并已修复,但由于某种原因,它们似乎直到更高版本才可用。

现在,您可以从命令行运行 mmp。构建输出显示当前命令,因此您可以使用该命令,但添加上面的参数。

这样做仍然很值得,即使没有链接这些库,我的应用程序也从 20mb 降到了 10mb。

于 2012-12-10T16:49:44.587 回答