C# MonoMac-链接器中断应用程序

C# MonoMac-链接器中断应用程序,c#,.net,macos,mono,monomac,C#,.net,Macos,Mono,Monomac,如果我用“Link SDK only”来构建我的应用程序的发布版本(用于在没有Mono的机器上进行beta测试),它将不再启动——它似乎会立即崩溃 以下是运行应用程序命令行时发生的崩溃: [ERROR] FATAL UNHANDLED EXCEPTION: System.TypeInitializationException: An exception was thrown by the type initializer for System.Xml.Serialization.XmlSeria

如果我用“Link SDK only”来构建我的应用程序的发布版本(用于在没有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 ---
[ERROR]致命的未处理异常:System.TypeInitializationException:System.Xml.Serialization.XMLSerializator的类型初始值设定项引发异常---->System.Configuration.ConfigurationErrorsException:初始化配置系统时出错。-->System.MissingMethodException:找不到System.Configuration.ExecutionHost类型的默认构造函数。
在:0中的System.Activator.CreateInstance(System.Type类型,布尔非公共)[0x00000]处
在0中的System.Activator.CreateInstance(System.Type类型)[0x00000]处
在:0中的System.Configuration.InternalConfigurationSystem.Init(System.Type类型ConfigHost,System.Object[]hostInitParams)[0x00000]处
在:0中的System.Configuration.InternalConfigurationFactory.Create(System.Type typeConfigHost,System.Object[]hostInitConfigurationParams)[0x00000]处
在System.Configuration.ConfigurationManager.OpenExeConfigurationInternal(ConfigurationUserLevel用户级别,System.Reflection.Assembly调用_Assembly,System.String exePath)[0x00000]中:0
在System.Configuration.ClientConfigurationSystem.get_Configuration()[0x00000]中:0
---内部异常堆栈跟踪的结束---
在System.Configuration.ClientConfigurationSystem.get_Configuration()[0x00000]中:0
在0中的System.Configuration.ClientConfigurationSystem.System.Configuration.InternalConfigSystem.GetSection(System.String configKey)[0x00000]处
在:0中的System.Configuration.ConfigurationManager.GetSection(System.String sectionName)[0x00000]处
在:0中的System.Configuration.ConfigurationSettings.GetConfig(System.String sectionName)[0x00000]处
位于System.Xml.Serialization.XmlSerializer..cctor()[0x00000]中:0
---内部异常堆栈跟踪的结束---
有没有办法在这里添加适当的
[Preserve]
属性?或者强制链接器保留这个类

更多信息:

  • 我的应用程序是一个游戏,叫做
  • 如果我不链接任何程序集,它运行得很好,但我的应用程序要大10MB
  • 最初,我从带有Tao.Sdl.dll的链接器中得到了一些错误,但我在主项目中引用了它,修复了它
  • 我的目标是10.6或更高
    • 有几个想法:

      • 控制台应用程序中是否打印了任何内容
      • 尝试从终端执行MyApp.app/Contents/MacOS/(binary),这至少会向终端打印一些内容

      与MonoTouch的
      mtouch
      相比,MMP(MonoMac Packer)的一个主要区别在于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文件反馈给MMP(-XML=file),以便链接器不会尝试从链接的应用程序中删除这些类型/方法

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

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

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

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

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

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


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

      谢谢你让我知道了这个错误。关于上面的堆栈跟踪有什么想法吗?poupou,很好的信息。那么,XML文件只是要跳过链接的名称空间/类型的列表吗?您的博客文章对XML文件中的内容有点模糊。“我会在这段时间内玩弄它的。@jonathanpeppers将我的博客文章链接到了
      monolinker使用的一些(真实的)XML文件
      ->”