2011-01-21 4 views
8

У меня есть проект библиотеки управления C++, скомпилированный с использованием/CLR. Внутри этого проекта есть пользовательский элемент управления, который вызывает вызов в родную DLL. Этот элемент управления пользователя появляется в панели инструментов дизайнера, как и должно быть, но я не могу перетащить его в форму. Без ссылки на DLL пользовательский элемент управления может использоваться отлично, но при ссылке я просто получаю сообщение «Не удалось загрузить элемент панели инструментов» при попытке его использовать.Дизайнер отклоняет пользовательский контроль

Натуральный вызов функциональный и не повредит User Control. Пользовательский элемент управления может быть хорошо рассмотрен в дизайнере самостоятельно с включенным вызовом DLL. Также, если элемент управления добавляется вручную в форму и выполняется как программа, он также будет отображаться в порядке.

Это заставляет меня подозревать, что проблема заключается только в том, что Visual Studio Designer должен знать, где находится эта родная DLL. Но я не уверен, как это сказать, или где разместить DLL, чтобы он мог ее найти. Насколько я знаю, в настройках проекта нет способа ссылаться на родную DLL. Поэтому для меня имеет смысл, что дизайнер просто жалуется, потому что он не может это исправить.

Есть ли способ сделать эту работу?

+0

Проблема с VS 2010 или также с VS 2008? У нас есть аналогичная парализующая проблема, которая заставила нас вернуться к VS 2008 ... –

+0

Я получаю эту проблему с VS 2008. Так что VS 2010 не лучше в этом отношении? – Nicholas

+0

Я думал, что добавление родной DLL в путь C: \ Windows \ System32 может быть успешным, но, к сожалению, это не так. – Nicholas

ответ

8

К сожалению, вы столкнулись с «ошибкой по дизайну» в VS (или, другими словами, «особенностью»).

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

Обходной путь заключается в компиляции исходных файлов на C++ с использованием /clr:pure для создания чисто управляемого EXE.


Другая возможность (также «ошибка по дизайну» в VS) заключается в том, что элемент управления, который вы пытаетесь добавить, был скомпилирован как 64-битный компонент. Поскольку Visual Studio представляет собой 32-разрядный процесс, он может выполнять только 32-битные модули. Хотя он позволяет вам добавить ссылку на 64-битную сборку, она не может на самом деле JIT компилировать эту 64-битную сборку и выполнять ее в процессе.

Обходной путь здесь состоит в том, чтобы скомпилировать вашу сборку пользовательских элементов управления с помощью параметра «AnyCPU», что приведет к его выполнению в виде 32-разрядного процесса в 32-разрядной среде и 64-разрядному процессу в 64- бит. На самом деле, это лучшее из обоих миров, если вы правильно написали свой код.


Наконец, если ни одна из этих работ, не всегда есть возможность обхода дизайнера.Вы все равно можете написать код, необходимый для создания экземпляра вашего пользовательского элемента управления и установки его свойств в инициализаторе формы. Все, что вы потеряете, - это возможность использовать элемент управления внутри конструктора внутри Visual Studio. Все будет работать так, как ожидалось во время выполнения.

+0

Пока я делаю x64 и x86 версии этого кода, я уже выделил проблему с платформой x64, которую вы упоминаете, а не проблему. – Nicholas

+0

Также из-за этой проблемы с дизайнером я уже обходил конструктора и вручную создавал элементы управления формой. – Nicholas

+0

Я согласен с тем, что компиляция с/clr: чистым флагом, вероятно, обойдет проблему дизайнера здесь, к сожалению, в этом случае мне нужна сборка смешанного режима. Однако, на мой взгляд, разработчику не нужно отражать функцию, которая использует родную DLL, если эта функция является только функцией утилиты класса, которую дизайнер не вызывает. – Nicholas

0

вещи попробовать:

VS2010: скопировать DLL в папку Program Files\Microsoft Visual Studio 9.0\Common7\IDE\PublicAssemblies.

VS2008, VS2010: скопируйте dll в папку AppData\Local\Microsoft\VisualStudio\<version>\ProjectAssemblies\.

+0

Я использую VS2008, поэтому не могу работать с первым вариантом. Второй вариант не работает, как указано. Папка «ProjectAssemblies» заполняется только со случайными именами. Эти папки, как представляется, автоматически генерируются разработчиком довольно часто. Слишком часто тестировать, потому что Visual Studio создает новую папку каждый раз, когда я что-то ткнул. Папка ProjectAssemblies выглядит теоретически как потенциальный кандидат, но назначение имен случайных папок делает это непрактичным. – Nicholas

0

Мне кажется, что управление со ссылкой на родную DLL не удается, потому что Visual Studio не может ее загрузить. Попробуйте установить переменную среды PATH либо глобально, либо исполняемую версию Visual Studio при ее запуске. Если это не помогает, попробуйте отладить поведение времени разработки вашего элемента управления, и вы сможете найти проблему.

+0

Я попытался покрыть это, поместив родную DLL в путь C: \ Windows \ System32, как указано выше. Разве это не повлияет на то, что вы имеете в виду? – Nicholas

+0

@Nicholas: попробуйте также зарегистрировать свою DLL - http://www.delphifaq.com/faq/windows_user/f668.shtml –

+0

Это не имеет никакого отношения к пути к DLL, или он не будет работать при запуске, время.Кроме того, вам не нужно регистрировать ничего, кроме COM/ActiveX DLL. Нет смысла (и на самом деле это нежелательно) регистрировать библиотеки DLL, которые только экспортируют функции, используемые вашим приложением. –

1

Я нашел это похоже на аналогичную проблему?

https://connect.microsoft.com/VisualStudio/feedback/details/388107/winforms-designer-fails-to-load-managed-dll-having-unmanaged-dependencies#details

Так MS, кажется, официально говоря, обновление от VS2008 к VS2010 в качестве обходного пути.

Вы когда-нибудь находили другое обходное решение?

Это проблема, которую я испытываю прямо сейчас в VS2008 с помощью управляемого проекта C# .net с использованием управляемого проекта оболочки C++ с использованием неуправляемого проекта на C++.

Это, безусловно, выглядит как временные сборки дизайнера, которые использует Visual Studio, - проблема заключается в загрузке обнаруженной сборки оболочки зависимостей во временную папку, но не в неуправляемых зависимостях сборки обертки. Я вижу это в C: \ Users \ Username \ AppData \ Local \ Microsoft \ VisualStudio \ 9.0 \ ProjectAssemblies. Когда я пытаюсь загрузить конструктор, там создается новая папка с управляемой DLL, но не неуправляемыми зависимостями. К сожалению, я не могу понять, что говорит человек из вопроса из вышеперечисленного Microsoft, это обходной путь с использованием $ (TargetDir).

+0

На самом деле я обнаружил, что если я добавлю папку со всеми зависимыми DLL-файлами в переменную среды Windows PATH, дизайнер Forms отобразит все. Теперь мне просто нужно посмотреть, есть ли более элегантный способ, чем иметь путь abosulte, поэтому другим разработчикам в команде не нужно обходиться. –

3

Свяжите свою библиотеку с /DELAYLOAD:"your_native.dll ". Для меня это решило ту же проблему.

0

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

Для записи, здесь было мое решение:

1) Измените параметры решения для x86. Это позволило мне установить контроль над дизайнером, переместить его и т. Д. 2) По завершении вы можете вернуться к AnyCPU или x64. Я действительно использую только конструктор, чтобы упростить установку нескольких значений, и кажется, что проблема с 32/64 бит вызывает проблемы.

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