2013-08-03 8 views
6

kann nicht gefunden werden Ich habe eine VSIX-Erweiterung, die von Code aus einer nicht verwalteten DLL bereitgestellt wird. Ich habe die DLL mit der VSIX hinzugefügt, und ich öffnete die VSIX mit einem Zip-Programm, um zu bestätigen, dass es korrekt bereitgestellt wird. Wenn ich jedoch das DllImport-Attribut verwende, behauptet das .NET Framework, dass es es nicht finden kann. Wie kann ich Funktionen aus einer DLL in meinem VSIX importieren?VSIX dlls mit DllImport

+1

Vielleicht fehlende Pfade? Hilft das hier? http://StackOverflow.com/a/10800260/71312 – Diryboy

+0

Haben Sie bestätigt, dass die nicht verwaltete DLL korrekt in das Installationsverzeichnis der Erweiterung extrahiert wird? Ich stelle ein einfaches VSIX zusammen, das ein Shell-Paket bereitstellt, das eine nicht verwaltete DLL aufruft. Ich habe die nicht verwaltete DLL dem Projekt mit einer Build-Aktion von Content hinzugefügt und sie in VSIX eingefügt. Es wird sowohl im Debug als auch als regulär implementierte Erweiterung korrekt ausgeführt. – WarrenG

+0

@WarrenG: Ich habe keine Ahnung, wo das ist. Meine Build-Aktion für meine DLL ist auch "Inhalt" und ich habe sie so eingestellt, dass sie in VSIX enthalten ist. – Puppy

Antwort

3

Ich weiß nicht, was hier falsch läuft, aber ich habe Windows und Visual Studio neu installiert, keine Änderungen am Projekt vorgenommen, und jetzt ist alles in Ordnung. Ich hatte einige andere Probleme mit der Suche nach DLLs für andere Anwendungen, und ich denke, sie waren verwandt, ich muss nur ein paar Einstellungen vermasselt haben.

2

Windows kann DLL-Dateien, die in komprimierte .zip eingebettet sind, nicht öffnen. Sie müssen sie daher entpacken und in einen Ordner legen, in den Sie schreiben können.

Das .NET Framework sucht nach den Pfaden Ihrer DLLs in %LocalAppData%, so dass es sinnvoll ist, Ihre DLL dort zu entpacken.

+0

Visual Studio extrahiert die Dateien aus dem VSIX in ein Installationsverzeichnis. – Puppy

+0

Können Sie das Ereignisprotokoll öffnen und überprüfen, von welchem ​​Pfad das Paket versucht, die DLL zu laden? https://en.wikipedia.org/wiki/Event_Viewer –

+0

Und dieses Tool kann wahrscheinlich helfen: http://technet.microsoft.com/en-us/sysinternals/bb896645 –

1

Ich habe in scheinbar zufälligen Situationen fehlerhafte Paketlastfehler bekommen. Die Probleme betrafen hauptsächlich Erweiterungen, die aus mehr als einer DLL-Datei bestanden. Ich habe sie schließlich gelöst, indem ich das [ProvideBindingPath] Attribut an das Haupt Package anwendete, das in der Erweiterung zur Verfügung gestellt wurde.

Sie müssen die Quelle für das Attribut in Ihrem Projekt einschließen.

/*************************************************************************** 

Copyright (c) Microsoft Corporation. All rights reserved. 
This code is licensed under the Visual Studio SDK license terms. 
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY 
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR 
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. 

***************************************************************************/ 

using System; 
using System.Text; 

namespace Microsoft.VisualStudio.Shell 
{ 
    /// <summary> 
    /// This attribute registers a path that should be probed for candidate assemblies at assembly load time. 
    /// 
    /// For example: 
    /// [...\VisualStudio\10.0\BindingPaths\{5C48C732-5C7F-40f0-87A7-05C4F15BC8C3}] 
    ///  "$PackageFolder$"="" 
    ///  
    /// This would register the "PackageFolder" (i.e. the location of the pkgdef file) as a directory to be probed 
    /// for assemblies to load. 
    /// </summary> 
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)] 
    public sealed class ProvideBindingPathAttribute : RegistrationAttribute 
    { 
     /// <summary> 
     /// An optional SubPath to set after $PackageFolder$. This should be used 
     /// if the assemblies to be probed reside in a different directory than 
     /// the pkgdef file. 
     /// </summary> 
     public string SubPath { get; set; } 

     private static string GetPathToKey(RegistrationContext context) 
     { 
      return string.Concat(@"BindingPaths\", context.ComponentType.GUID.ToString("B").ToUpperInvariant()); 
     } 

     public override void Register(RegistrationContext context) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException("context"); 
      } 

      using (Key childKey = context.CreateKey(GetPathToKey(context))) 
      { 
       StringBuilder keyName = new StringBuilder(context.ComponentPath); 
       if (!string.IsNullOrEmpty(SubPath)) 
       { 
        keyName.Append("\\"); 
        keyName.Append(SubPath); 
       } 

       childKey.SetValue(keyName.ToString(), string.Empty); 
      } 
     } 

     public override void Unregister(RegistrationContext context) 
     { 
      if (context == null) 
      { 
       throw new ArgumentNullException("context"); 
      } 

      context.RemoveKey(GetPathToKey(context)); 
     } 
    } 
} 
+0

Ja, aber ich spreche nicht über das Laden von Paketen hier. Nicht verwaltete DLLs und Pakete verwenden recht unterschiedliche Mechanismen. – Puppy