Как программно получить GUID приложения в .net2.0

100

Мне нужно получить доступ к сборке моего проекта на C # .NET2.0.

Я вижу GUID в диалоговом окне «Информация о сборке» в свойствах проекта, и на данный момент я только что скопировал его в константу кода. GUID никогда не изменится, так что это неплохое решение, но было бы неплохо получить к нему прямой доступ. Есть ли способ сделать это?

Натан
источник

Ответы:

152

Попробуйте следующий код. Значение, которое вы ищете, хранится в экземпляре GuidAttribute, прикрепленном к сборке.

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);
}
ДжаредПар
источник
4
как насчет использования «AppDomain.CurrentDomain.DomainManager.EntryAssembly» вместо «typeof (Program) .Assembly»? ну, мы могли бы изменить имя класса Program, не так ли?
Kenial
11
Чтобы сэкономить кому-то еще несколько секунд поиска в Google, GuidAttribute находится в пространстве имен System.Runtime.InteropServices.
Брайс Вагнер
5
@BryceWagner ctrl+.- ваш друг
maxp
@Kenial я получаю System.AppDomain.DomainManager.get returned null.за простое консольное приложение. Кажется, Assembly.GetEntryAssembly()это предпочтительный способ.
Джесси С. Слайсер,
11

Другой способ - использовать Marshal.GetTypeLibGuidForAssembly .

Согласно msdn:

Когда сборки экспортируются в библиотеки типов, библиотеке типов присваивается LIBID. Вы можете установить LIBID явно, применив System.Runtime.InteropServices.GuidAttribute на уровне сборки, или он может быть сгенерирован автоматически. Средство Tlbimp.exe (средство импорта библиотеки типов) вычисляет значение LIBID на основе идентификатора сборки. GetTypeLibGuid возвращает LIBID, связанный с GuidAttribute, если атрибут применен. В противном случае GetTypeLibGuidForAssembly возвращает вычисленное значение. В качестве альтернативы вы можете использовать метод GetTypeLibGuid для извлечения фактического LIBID из существующей библиотеки типов.

andrey.ko
источник
Мне удалось это сделать на F #, похоже, в сборке нет настраиваемого атрибута с Guid
fableal
Этот метод работает, даже Assembly.ReflectionOnlyLoadесли зависимые сборки не загружены.
Мартин Лоттеринг,
Таким образом, полный код: System.Runtime.InteropServices.Marshal.GetTypeLibGuidForAssembly(System.Reflection.Assembly.GetExecutingAssembly()).ToString(). Выглядит намного проще, чем другой метод. Есть ли минусы?
пользователь
7

Или так же просто:

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

Работает для меня...


источник
6

Вы должны иметь возможность читать атрибут Guid сборки через отражение. Это получит GUID для текущей сборки

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

Вы также можете заменить GuidAttribute другими атрибутами, если хотите читать такие вещи, как AssemblyTitle, AssemblyVersion и т. Д.

Вы также можете загрузить другую сборку (Assembly.LoadFrom и все) вместо получения текущей сборки - если вам нужно прочитать эти атрибуты внешних сборок (например, при загрузке плагина)

поражает святой
источник
6
Пожалуйста, не используйте приведение "as", если вы собираетесь использовать результат приведения, несмотря ни на что. Как правило, это плохой стиль, потому что вы получаете исключение NullReferenceException вместо более информативного исключения InvalidCastException, если приведение не выполняется. Приведения типа «as» используются, когда вы не знаете, принадлежит ли объект данному типу, и хотите использовать его только в том случае, если это так. Просто используйте прямое ((GuidAttribute) attribs [0]). Value вместо этого, если вы не ожидаете, что он будет другого типа (чего не должно быть)
poizan42
5

В случае, если кто-то еще ищет готовый рабочий пример, это то, что я в конечном итоге использовал на основе предыдущих ответов.

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

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

Обновить:

Поскольку этому было уделено немного внимания, я решил включить другой способ сделать это, который я использовал. Таким образом, вы можете использовать его из статического класса:

    /// <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();
        }
    }
Скотт Солмер
источник
1

Чтобы получить appID, вы можете использовать следующую строку кода:

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

Для этого вам нужно включить System.Runtime.InteropServices;

Drgmak
источник
1

Не повезло с другими ответами, но удалось решить это с помощью этого приятного лайнера:

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

Надеюсь это поможет!

0tombo0
источник