使用Fody(Costura)嵌入DLL到EXE后,如何解决Mono运行时兼容问题?
I’ve run into this exact frustration before—even after calling CosturaUtility.Initialize(), Mono still throws that annoying FileNotFoundException for embedded assemblies like CommandLine.dll. Let’s walk through the fixes that got my app working cross-platform:
1. Confirm Your DLL Is Actually Being Embedded
First, double-check that Costura is including the missing DLL (CommandLine, Version=2.2.1.0) in your compiled EXE:
- Open your
FodyWeavers.xmlfile and make sure there’s no exclusion rule blocking CommandLine.dll:<Costura> <ExcludeAssemblies> <!-- Remove CommandLine from this list if it’s here --> </ExcludeAssemblies> </Costura> - Use a tool like ILSpy to inspect your EXE—look for the DLL under the
Costuraembedded resource namespace to confirm it’s present.
2. Prioritize Costura Initialization (Don’t Rely on Static Constructors)
Mono handles static constructor execution timing differently than .NET Framework, which can mean Costura’s resolver isn’t hooked up before Mono tries to load your dependencies. Move the initialization call to the very first line of your Main method:
class Program { static void Main(string[] args) { // Initialize Costura BEFORE any other code runs CosturaUtility.Initialize(); // Now execute your application logic // ... } }
This guarantees the assembly resolver is active before Mono attempts to load CommandLine.dll.
3. Fallback: Manual Embedded Assembly Loading
If Costura’s automatic resolver still fails on Mono, bypass it by manually loading the embedded DLL yourself:
- In your project, right-click CommandLine.dll > Properties > Set Build Action to
Embedded Resource. - Add this helper method to load the assembly early:
using System; using System.IO; using System.Reflection; class Program { static void Main(string[] args) { // Replace "YourProjectNamespace.CommandLine.dll" with your actual resource name LoadEmbeddedAssembly("YourProjectNamespace.CommandLine.dll"); // Rest of your application code // ... } static void LoadEmbeddedAssembly(string resourceName) { var currentAssembly = Assembly.GetExecutingAssembly(); using (var resourceStream = currentAssembly.GetManifestResourceStream(resourceName)) { if (resourceStream == null) { throw new FileNotFoundException("Could not find embedded resource", resourceName); } var assemblyBytes = new byte[resourceStream.Length]; resourceStream.Read(assemblyBytes, 0, assemblyBytes.Length); Assembly.Load(assemblyBytes); } } }
You can find the exact resource name by inspecting your EXE in ILSpy (look under the embedded resources list for your project’s namespace).
4. Update Mono to the Latest Stable Version
Older Mono releases have known quirks with assembly resolution and embedded resources. Updating to the newest stable version often resolves subtle compatibility issues with tools like Costura.
内容的提问来源于stack exchange,提问作者Rishav

