2011-02-07 3 views
8

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

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

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

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

+0

Вы имеете в виду загруженный в текущий домен приложения? Что такое 'assemblyName'? Полноценное имя сборки или физический путь к файлу? –

+0

@MrDisaapointment Единственное, что я знаю, это то, что у меня есть «CustomModule» в моей базе данных. Если в моем ящике или GAC (!?) Присутствует файл CustomModule.dll, он будет создавать класс, указанный классом. –

+0

Посмотрите мое последнее обновление, надеюсь, этого достаточно, чтобы продолжить. –

ответ

8

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

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; 
} 
+0

@MrDisappointment, спасибо за код. Я не смог указать, что я работаю в .Net 2.0 –

+1

Не возвращает ли это только сборки, которые уже загружены в AppDomain? – mmix

+0

@mmix имеет действительную точку. Я мог бы иметь dll в каталоге bin, который не был загружен. –

1

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

+0

100% истинно! Но я бы хотел проверить это, а не ждать появления исключения. –

+0

На вершине моей головы я не думаю, что вы справитесь с этим легко, так как вам нужно подражать полному алгоритму зондирования. Он также подвержен ошибкам (должен сказать, что домен приложения устанавливает собственный процесс зондирования). Для первого взгляда на остановку, если вы все еще хотите это, проверьте эту ссылку: [Как время выполнения находит сборки]: http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx – mmix

2

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

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

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

-1

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

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

строка ключ = «fjrj3288skckfktk4owoxkvkfk4o29dic»;

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

Если (isMyLib.Variables.key == ключ) // continue

else // .dll не существует или не работает.

Смежные вопросы