Wie erhalte ich programmgesteuert die GUID einer Anwendung in .net2.0?

100

Ich muss auf die Assembly meines Projekts in C # .NET2.0 zugreifen.

Ich kann die GUID im Dialogfeld "Baugruppeninformationen" unter Projekteigenschaften sehen und habe sie gerade in eine Konstante im Code kopiert. Die GUID wird sich nie ändern, daher ist dies keine so schlechte Lösung, aber es wäre schön, direkt darauf zuzugreifen. Gibt es eine Möglichkeit, dies zu tun?

Nathan
quelle

Antworten:

152

Versuchen Sie den folgenden Code. Der gesuchte Wert wird in einer GuidAttribute-Instanz gespeichert, die an die Assembly angehängt ist

using System.Runtime.InteropServices;

static void Main(string[] args)
{
    var assembly = typeof(Program).Assembly;
    var attribute = (GuidAttribute)assembly.GetCustomAttributes(typeof(GuidAttribute),true)[0];
    var id = attribute.Value;
    Console.WriteLine(id);
}
JaredPar
quelle
4
Wie wäre es mit 'AppDomain.CurrentDomain.DomainManager.EntryAssembly' anstelle von 'typeof (Program) .Assembly'? Nun, wir könnten den Namen der Programmklasse ändern, nicht wahr?
Kenial
11
GuidAttribute befindet sich im Namespace System.Runtime.InteropServices, um jemand anderem ein paar Sekunden Googeln zu ersparen.
Bryce Wagner
5
@BryceWagner ctrl+.ist dein Freund
maxp
@ Kenial bekomme ich System.AppDomain.DomainManager.get returned null.für eine einfache Konsolen-App. Scheint Assembly.GetEntryAssembly()der bevorzugte Weg zu sein.
Jesse C. Slicer
11

Eine andere Möglichkeit ist die Verwendung von Marshal.GetTypeLibGuidForAssembly .

Laut msdn:

Wenn Assemblys in Typbibliotheken exportiert werden, wird der Typbibliothek eine LIBID zugewiesen. Sie können die LIBID explizit festlegen, indem Sie das System.Runtime.InteropServices.GuidAttribute auf Assembly-Ebene anwenden, oder es kann automatisch generiert werden. Das Tool Tlbimp.exe (Type Library Importer) berechnet einen LIBID-Wert basierend auf der Identität der Assembly. GetTypeLibGuid gibt die LIBID zurück, die dem GuidAttribute zugeordnet ist, wenn das Attribut angewendet wird. Andernfalls gibt GetTypeLibGuidForAssembly den berechneten Wert zurück. Alternativ können Sie die GetTypeLibGuid-Methode verwenden, um die tatsächliche LIBID aus einer vorhandenen Typbibliothek zu extrahieren.

andrey.ko
quelle
Ich konnte dies in F # tun, es scheint, dass die Assembly kein benutzerdefiniertes Attribut mit dem Guid
Fableal
Diese Methode funktioniert auch mit Assembly.ReflectionOnlyLoadund auch dann, wenn abhängige Assemblys nicht geladen werden.
Martin Lottering
Der vollständige Code lautet also : System.Runtime.InteropServices.Marshal.GetTypeLibGuidForAssembly(System.Reflection.Assembly.GetExecutingAssembly()).ToString(). Sieht viel einfacher aus als die andere Methode. Gibt es Nachteile?
Benutzer
7

Oder genauso einfach:

string assyGuid = Assembly.GetExecutingAssembly().GetCustomAttribute<GuidAttribute>().Value.ToUpper();

Funktioniert bei mir...


quelle
6

Sie sollten in der Lage sein, das Guid-Attribut der Baugruppe durch Reflektion zu lesen. Dadurch wird die GUID für die aktuelle Assembly abgerufen

         Assembly asm = Assembly.GetExecutingAssembly();
        var attribs = (asm.GetCustomAttributes(typeof(GuidAttribute), true));
        Console.WriteLine((attribs[0] as GuidAttribute).Value);

Sie können das GuidAttribute auch durch andere Attribute ersetzen, wenn Sie Dinge wie AssemblyTitle, AssemblyVersion usw. Lesen möchten

Sie können auch eine andere Assembly laden (Assembly.LoadFrom und alle), anstatt die aktuelle Assembly abzurufen - wenn Sie diese Attribute externer Assemblys lesen müssen (z. B. beim Laden eines Plugins)

amazedsaint
quelle
6
Bitte verwenden Sie keine "als" Darsteller, wenn Sie das Ergebnis der Besetzung verwenden möchten, egal was passiert. Es ist im Allgemeinen ein schlechter Stil, da Sie eine NullReferenceException anstelle der informativeren InvalidCastException erhalten, wenn die Umwandlung fehlschlägt. "as" Casts sind für Fälle gedacht, in denen Sie nicht wissen, ob das Objekt vom angegebenen Typ ist, und es nur verwenden möchten, wenn dies der Fall ist. Verwenden Sie einfach ein direktes ((GuidAttribute) Attribut [0]). Wert stattdessen, wenn Sie nicht erwarten, dass es von einem anderen Typ ist (was es nicht sollte)
poizan42
5

Für den Fall, dass jemand anderes nach einem sofort einsatzbereiten Arbeitsbeispiel sucht, habe ich dieses anhand der vorherigen Antworten verwendet.

using System.Reflection;
using System.Runtime.InteropServices;

label1.Text = "GUID: " + ((GuidAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(GuidAttribute), false)).Value.ToUpper();

Aktualisieren:

Da dies ein wenig Aufmerksamkeit erregt hat, habe ich beschlossen, eine andere Methode einzuschließen, die ich verwendet habe. Auf diese Weise können Sie es aus einer statischen Klasse verwenden:

    /// <summary>
    /// public GUID property for use in static class </summary>
    /// <returns> 
    /// Returns the application GUID or "" if unable to get it. </returns>
    static public string AssemblyGuid
    {
        get
        {
            object[] attributes = Assembly.GetEntryAssembly().GetCustomAttributes(typeof(GuidAttribute), false);
            if (attributes.Length == 0) { return String.Empty; }
            return ((System.Runtime.InteropServices.GuidAttribute)attributes[0]).Value.ToUpper();
        }
    }
Scott Solmer
quelle
1

Um die AppID zu erhalten, können Sie die folgende Codezeile verwenden:

var applicationId = ((GuidAttribute)typeof(Program).Assembly.GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;

Dazu müssen Sie die einschließen System.Runtime.InteropServices;

drgmak
quelle
1

Kein Glück hier mit den anderen Antworten, aber es ist gelungen, es mit diesem schönen Einzeiler herauszufinden:

((GuidAttribute)(AppDomain.CurrentDomain.DomainManager.EntryAssembly).GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value

Hoffe das hilft!

0tombo0
quelle