如果我使用“仅限Link SDK”构建我的应用程序用于发布版本(在没有Mono的计算机上进行beta测试),它将不再启动 - 它似乎立即崩溃。
如果我运行我的app命令行,那么崩溃是这样的:
[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]
属性的任何方法?或者可能强制链接器保留这个类?
更多信息:
答案 0 :(得分:4)
与MonoTouch的mtouch
相比, MMP (MonoMac Packer)的主要区别在于MonoMac使用完整的.NET框架。这使得链接应用程序变得更加复杂。
为什么?主要是因为System.Configuration
(它是一个程序集,但它也是其他几个程序集中的命名空间)。它使用反射和.config
文件进行自我设置 - 链接器无法知道(因为它可以在执行之间进行更改)确切地说是应用程序所需的文件。
MMP 尝试来涵盖最常见的情况(例如System.Net),但目前它并不处理在BCL内部使用System.Configuration的所有情况。
现在要修复... 你需要告诉链接器包含应用程序在运行时需要的所有内容。 E.g。
[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
并且链接器无法检测到它(它通过反射使用)。
从那里你需要build an XML file 教导链接器关于那些必需的类型(将有其他人,可能还有许多其他类型)。然后将该XML文件反馈给MMP(--xml = FILE),以便链接器不会尝试从链接的应用程序中删除这些类型/方法。
替代方案不链接或不链接某些程序集(例如--linkskip=System
)。 YMMV。
UPDATE:新的Xamarin.Mac是MonoMac的超集,它包含一个增强版的链接器,可以解决这个异常(但可能不是所有其他的,请填写错误报告他们)。
答案 1 :(得分:1)
一些想法:
答案 2 :(得分:1)
这是因为mmp(内置于MonoDevelop中的MonoMac打包器)从框架中消失了太多。特别是在使用XML时。
我发现你必须将这些额外的参数传递给mmp才能使XML工作:
--linkskip=System.Net --linkskip=System --linkskip=System.Configuration --linkskip=mscorlib
不幸的是,monodevelop中项目配置中的mmp参数不起作用(不保存)。我已经报告了这些错误并且已经修复但似乎不会因为某种原因它们在更高版本之前可用。
现在,您可以从命令行运行mmp。构建输出显示当前命令,因此您可以使用它,但添加上面的参数。
要做到这一点仍然非常值得,即使没有链接这些库,我的应用程序从20mb下降到10mb。