Can Json.Net be embedded into the executable?

前端 未结 1 1394
慢半拍i
慢半拍i 2020-12-31 19:54

I set the \'Embed Interop Types\' property of the Netwonsoft.Json library to true and it returns an error:

Cannot embed interop typ         


        
相关标签:
1条回答
  • 2020-12-31 20:24

    You didn't say which language you were using but here is how you'd do it for C#


    First, turn off "Embed Interop Types"

    Then, to the main executable project, unload and edit the .csproj file, and below the following line:

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    

    Add this XML to the project file, save, and load it back up.

     <Target Name="AfterResolveReferences">
      <ItemGroup>
        <EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
          <LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
        </EmbeddedResource>
      </ItemGroup>
    </Target>
    

    You’ll then add a new code file to the main project and add the following code to it (modified to fit how your application is named / structured, in a WPF application, a good place to put it would be App.xaml.cs):

    [STAThread]
    public static void Main()
    {
        AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
    
        App.Main(); // Run WPF startup code.
    }
    
    private static Assembly OnResolveAssembly(object sender, ResolveEventArgs e)
    {
        var thisAssembly = Assembly.GetExecutingAssembly();
    
        // Get the Name of the AssemblyFile
        var assemblyName = new AssemblyName(e.Name);
        var dllName = assemblyName.Name + ".dll";
    
        // Load from Embedded Resources - This function is not called if the Assembly is already
        // in the same folder as the app.
        var resources = thisAssembly.GetManifestResourceNames().Where(s => s.EndsWith(dllName));
        if (resources.Any())
        {
    
            // 99% of cases will only have one matching item, but if you don't,
            // you will have to change the logic to handle those cases.
            var resourceName = resources.First();
            using (var stream = thisAssembly.GetManifestResourceStream(resourceName))
            {
                if (stream == null) return null;
                var block = new byte[stream.Length];
    
                // Safely try to load the assembly.
                try
                {
                    stream.Read(block, 0, block.Length);
                    return Assembly.Load(block);
                }
                catch (IOException)
                {
                    return null;
                }
                catch(BadImageFormatException)
                {
                    return null;
                }
            }
        }
    
        // in the case the resource doesn't exist, return null.
        return null;
    }
    

    Finally, make sure you update the target method for your main application to be the main method for the project you just added

    Source: http://www.paulrohde.com/merging-a-wpf-application-into-a-single-exe/

    0 讨论(0)
提交回复
热议问题