Как проверить, существует ли определенная сборка? - PullRequest
8 голосов
/ 07 февраля 2011

Я использую Activator для создания экземпляра нового класса, основанного на коротком имени сборки (например, CustomModule).Выдает FileNotFoundException, потому что сборки там нет. Есть ли способ проверить, присутствует ли определенное имя сборки?

Я использую следующий код:

System.Runtime.Remoting.ObjectHandle obj = 
    System.Activator.CreateInstance(assemblyName, className);

Основная цель - скорее проверитьна наличие сборки, чем ждать возникновения исключения.

Ответы [ 4 ]

8 голосов
/ 07 февраля 2011

Если вы заметите мой комментарий к вашему вопросу, будет очевидно, что я не совсем уверен, точно как вы хотите или должны это сделать, но пока у нас нет более подробного описания, яможет предложить вам это только в надежде, что оно хорошо подходит для вашей ситуации (ключ находится в «поиске» сборок):

var className = "System.Boolean";
var assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var assembly = (from a in assemblies
                where a.FullName == assemblyName
                select a).SingleOrDefault();
if (assembly != null)
{
    System.Runtime.Remoting.ObjectHandle obj = 
        System.Activator.CreateInstance(assemblyName, className);             
}

.NET 2.0 совместимый код

Assembly assembly = null;
var className = "System.Boolean";
var assemblyName = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";

foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
    if (a.FullName == assemblyName)
    {
        assembly = a;
        break;
    }
}

if (assembly != null)
{
    System.Runtime.Remoting.ObjectHandle obj =
        System.Activator.CreateInstance(assemblyName, className);
}

ЕслиВы хотите определить, существует ли файл, прежде чем пытаться загрузить его (хорошая практика), а затем, если у вас есть его имя и вы знаете желаемое местоположение, просто попробуйте найти файл, когда сборка разрешается:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

var className = "StackOverflowLib.Class1";
var assemblyName = "StackOverflowLib.dll";
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var obj = Activator.CreateInstance(Path.Combine(currentAssemblyPath, assemblyName), className);

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    if (File.Exists(Path.Combine(currentAssemblyPath, args.Name)))
    {
        return Assembly.LoadFile(Path.Combine(currentAssemblyPath, args.Name));
    }
    return null;
}
2 голосов
/ 07 февраля 2011

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

if (DoesAssemblyExist(asmName)) {
    object = Activator.CreateInstance(typeName);
}
else {
    MessageBox.Show("Assembly does not exist");
}

, то в ОС с многозадачной ОС всегда существует риск, что сборка может быть добавлена ​​/ удалена между проверкой и фактическим созданием.Да, я понимаю, что этот риск минимален, но я все еще думаю, что вариант исключения выглядит лучше, потому что он атомарный.

1 голос
/ 07 февраля 2011

Отсутствие сборки определенно является исключением, попробуйте / поймайте FileNotFoundException и обработайте ситуацию в соответствии с вашей логикой.

0 голосов
/ 12 марта 2017

Я надеюсь, что это поможет кому-то в будущем:

На каждом используемом вами внешнем .dll создайте свой собственный уникальный ключ, например:

string key = "fjrj3288skckfktk4owoxkvkfk4o29dic";

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

If (isMyLib.Variables.key== ключ) // продолжить

, иначе // .dll не существует или поврежден.

...