2010-12-27 1 views
3

Я пишу приложение .NET 3.5 (WinForms), которое использует классы из внешней DLL, и я все время получаю System.TypeLoadException каждый раз, когда приложение пытается запустить.
Вот исключение VS дисплеях:Help on TypeLoadException

 
System.TypeLoadException was unhandled 
    Message=Could not load type 'PolyMorph.Common.Settings' from assembly 'PolyMorph, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. 
    Source=PolyMorph 
    TypeName=PolyMorph.Common.Settings 
    StackTrace: 
     at PolyMorphApp.App.Initialize() 
     at PolyMorphApp.App.Main() 
     at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

Вот код, который я бегу:

Friend NotInheritable Class App 

    <STAThread()> Shared Sub Main() 
     'set the exception handlers' 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException) 
     AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf UnhandledExceptionHandler 
     AddHandler Application.ThreadException, AddressOf ThreadExceptionHandler 
     'initialize the application' 
     App.Initialize() 

     'and then run the application' 
     Dim mainForm As New PolymorphHost 
     Application.Run(mainForm) 
    End Sub 

    Shared Function Initialize() As FunctionResult 
     If App.InitializeDataDirectory() = False Then 
      Return New FunctionResult(False, "the application's data directory") 
     End If 


     _settings = New PolyMorph.Common.Settings(AppDataDirectory & "\Settings.dat") 
     ......code continues to load settings from the _settings variable 
    End Function 
End Class 



Что меня удивляет, что VS2010 Отладчик останавливается на линии App.Initialize() без даже вступая в функцию Initialize.

Если, однако, я комментирую все ссылки на внешнюю DLL в функции Initialize, приложение инициализируется правильно.


После прочтения вокруг, я понял, что число людей, сообщающих эту ошибку использовали различные сборки на своих проектах (как в x64 DLL которые ссылаются из приложения x86). Поэтому я изменил конфигурацию сборки, поэтому DLL и приложение были x86, но у меня все еще есть TypeLoadException.

Есть ли что-нибудь, что мне не хватает?

+0

Я получил эту ошибку, когда у меня было неправильное имя dll в манифесте приложения. – ZX9

ответ

2

Оказывается, один Nutzy также имел similar problem, и он решил ее, скопировав все классы, формы и элементы управления для нового проекта. Я сделал то же самое, и проблема была решена.

Спасибо, Джим Мишель и Пол Александер за вашу помощь. Я проголосовал за ваши усилия, чтобы помочь мне решить эту проблему.

+0

У меня была аналогичная проблема. Когда я столкнулся с этим, я заметил, что по какой-то причине я получал предупреждение, подобное «Не удалось удалить файл« C: \ SomeDll \ SomeDll.dll ». Доступ к пути «C: \ SomeDll \ SomeDll.dll» отклонен. Поэтому я закрыл визуальную студию, удалил .dll и .pdb, которые бросали ошибку (поскольку я не мог удалить их с помощью VS open) и перезапустил Visual Studio. Проблема решена после этого. – edhubbell

1

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

Или вы можете использовать операторы Debug (см. System.Diagnostics) после загрузки каждого значения, чтобы определить, где он неисправен.

+0

Как я указал в вопросе, отладчик даже не вступает в метод «Initialize», поэтому нет способа узнать, что может вызвать ошибку. Программа не имеет возможности загружать * любые * настройки вообще. –

+1

@Alex: Вы правы. Извините, это так. Павел Александр указывает вам в правильном направлении. –

4

Вы должны посмотреть свойства InnerException и LoadException, чтобы получить более подробную информацию о том, почему зависимая сборка не загружается должным образом.

Причина, по которой это исключение до Инициализация происходит из-за того, как метод скомпилирован JIT. Когда метод выполняется в первый раз, CLR проверяет и разрешает все инструкции MSIL в этом методе, прежде чем компилировать его в эквивалент времени выполнения. Так как тип PolyMorph.Common.Settings используется методом Initialize, CLR пытается его решить при компиляции. Поскольку загрузка не выполняется, инициализация никогда не выполняется.

, чтобы зафиксировать исключение в вашем собственном коде, просто переместите весь код инициализации на другой метод, а затем вызовите этот метод в блоке try ... catch из Initialize.

Try 
    InitializeInternal() 
Catch ex As TypeLoadException 
    System.Diagnostics.Debugger.WriteLine(ex.ToString()) 
End Try 
+0

Я пробовал код, который вы дали, и я все еще получаю исключение. Исключение не содержит никаких данных в его 'InnerException', которое я считаю странным, поэтому я не могу отслеживать источник исключения. –

+0

@Alex: исключение, вероятно, находится в конструкторе Shared класса 'PolyMorph.Common.Settings' или в одном из его общих (статических) инициализаторов. –

+0

@Alex: Опубликовать все результаты вызова ex.ToString(). Это может помочь нам предложить более глубокое понимание. –

1

У меня была такая же проблема, и я убежден, что это ошибка в VisualStudio или JIT-компиляторе. Я знаю, что это не имеет ничего общего с DLL или x64 vs x86, так как у меня не было специальных ссылок в моем тестовом проекте. Я отслеживал строку нарушения для переменной-члена структуры.Не было ничего интересного в этой конкретной переменной-члене (это был простой класс :)

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct Foo 
    { 
     int x; 
    } 

и был членом следующим образом. Он работает, если значение #if было истинным. Если изменить его #false, она компилируется без ошибок, но во время выполнения, когда я достигаю что-либо вообще во всем классе, это дает мне TypeLoadException

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct uartparam_t 
    { //size 112 
     public UInt16 portnum; //0 
     public Byte conntype; 
     public Byte baud; 
     public Byte databits; 
     public Byte stopbits; 
     public Byte parity; 
     public Byte flowctrl; 
#if true 
     public int remoteip; 
#else 
     public Foo remoteip; //8 -- for some reason this is making the program crash! ?!?!? 
#endif 

    .... 

, которая была частью

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct config { 
... 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAXUARTPORT)] 
     public uartparam_t[] uartparam; //(size 1792) 
... 
    } 

Это не имеет никакого смысла. Я попытался полностью перестроить приложение, а также создать новый проект в новом решении, и ничто из этого не помогло. Единственный способ заставить его работать - это сменить структуру на int и обработать преобразование типа из int в Foo вне структуры.

0

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

0

Моя проблема была в родительской сборке, и у DLL было такое же имя сборки.

например. Application.exe и Application.dll

Я изменил каждое на отдельное имя в свойствах проекта (например, Application.exe и Library.dll), и он исправил проблему. Я думаю, что выбранный ответ («переход на новое решение») они переименовывают проекты.