2016-09-28 114 views
3

我的「嵌入互操作類型」的Netwonsoft.Json庫的屬性設置爲true並返回一個錯誤:可以將Json.Net嵌入到可執行文件中嗎?

Cannot embed interop types from assembly 
'c:\path\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll' 
because it is missing either the 'ImportedFromTypeLibAttribute' attribute or 
the 'PrimaryInteropAssemblyAttribute' attribute 
c:\path\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 

它看起來像在尋找失蹤的Newtonsoft.Json庫中的引用,但我不能完全肯定。可以將Json.Net嵌入到可執行文件中嗎?

回答

3

你沒有說你使用哪種語言,但這裏是你如何做到這一點的C#


首先,關閉「嵌入互操作類型」

然後,主可執行項目,卸載和編輯的.csproj文件,並以下線以下:

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

這個XML添加到項目文件,保存,並加載它回來了。

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

然後,您將添加一個新的代碼文件,主要項目上,並添加以下代碼到它(修改,以適應您的應用程序是如何命名/結構,在WPF應用程序的好地方把它將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; 
} 

最後,確保你的主要應用是對剛剛添加的項目的主要方法更新目標方法

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

相關問題