Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Visual C++/MFC/WTL > Программа запускается только на моем компьютере... |
Автор: Smarts 23.4.2007, 02:01 |
Есть программа написанная в VS 2005, стоит режим Release, больше никаких настроек не менял. Используется один .dll файл, который лежит в папке с программой. MFC нет, это простое консольное приложение, все основные функции находятся в dll. На моем компьютере работает исправно, при переносе на другие - возникает такая ошибка: http://img144.imageshack.us/img144/2192/ldrerrorws8.gif Не знаю как исправить, у меня все работает нормально, а у других - нет. Посоветуйте, что можно сделать в данном случае? Если нужна какая-нибудь дополнительная информация - могу написать тут. |
Автор: Earnest 23.4.2007, 08:39 |
Дело наверняка, как всегда, в DLL. Кроме MFC, есть еще С Runtime, называется что-то типа msvcXXX.DLL. Вот ее нужно с собою таскать. Или слинковать как статическую. Лучше всего посмотреть с помощью Dependency Viewer, от каких DLL зависит твоя программа. |
Автор: dizzy1984 23.4.2007, 09:42 |
Проблема в том, что любая программа написанная под vs8.0 будет работать только с установленной .Net Framework. Твой выбор такой 1. Линковать MFC библиотеки статически. ALT P + P=> General=> Use Of MFC: Use MFC in a static library ALT P + P=> C/C++=> Code Generation=> Runtime Library : multi-threaded Ну и ALT P + P=> Linker=> Manifest File=> Generate Manifes=> No 2. По прежнему использовать динамическую линковку тогда тебе нужно Почитай http://file://localhost/script/ann/ServeHTML.aspx?C=False&id=2257&cb=1301530 Поставить на машину заказчика ту версую .net framework, которая была использована для разработки. Она потянет за собой IE и WindowsInstaller а также необходимые сервис паки. Или руками Я понял плохо но похоже порядок таков Убедиться в генерации манифеста Посмотреть список используемых тобой dll Создать папку(и) C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd, где имя последней папки зависит от версии сервис пака ОС, самой ОС, версии .Net Framework и версий конкретной используемой тобой dll. Скопировать туда все dll. После чего они будут грузиться динамически Т.е все дело в том, что с выходом vs2005 работа с динамическими библиотеками ведется через манифесты (загрузка). Манифест либо шьется в *.exe, либо кладется в папку *.exe как файл *.manifest. Программа написанная на VS2005 динамически не станет грузить dll, если не видит манифеста. Если видит, то грузить будет, но сами dll обязаны распологаться не в папке *.exe, не в папке system или system32 или winnt, а в папке winsxs в соответствующей подпапке. Что делать в случае смены сервис-пака или версии .net я не знаю. Короче, я был бы очень рад если бы мне кто-то объяснил как предполагается все это делать динамически. |
Автор: Earnest 23.4.2007, 10:30 |
dizzy1984, вовсе не обязательно наличие NET - если, конечно, проект NET не использует. Smarts писал, что приложение консольное, так что вряд ли там NET. Но проверить, конечно, стоит. И с манифестом ты усложняешь. Без манифеста будут загружаться стандартные библиотеки, не поддерживающие тем. Так что все работать будет, но без современной раскраски. Smarts, проблема поднималась неоднократно, поищи по форуму. |
Автор: Smarts 23.4.2007, 10:52 |
dizzy1984, спасибо за развернутый ответ, только первый пункт отпадает, так как там стоит WinXP SP2 и этот файл по умолчанию уже установлен, а вот .Net Framework скорее всего как раз 1.1 (включен в SP2), а обновление не устанавливали. Хотя .Net не использовался, но все равно сегодня обновлю и напишу тут. Кстати ссылка не открывается, к тому же ведет на localhost :( Earnest, поиском пользовался, но в каждом случае проблема имеет различные причины, обычно все сводилось к установке конфигурации Release и статической линковке библиотек, но сейчас это не помогает... |
Автор: dizzy1984 23.4.2007, 11:37 |
Earnest, ты сильно ошибаешься. Я полностью уверен в том, что абсолютно любая программа написанная на vs80 с динамической линковкой mfc не станет работать без манифестов на ОС windows xp. Я могу отдать свою правую руку на отсечение что это так. Earnest, File->New->Project->Win32->Win32 Console Application Ставим галочку напротив MFC. Release. Build. test1 - 0 error(s), 0 warning(s) w32dasm.exe load test1.exe Number of Imported Modules = 3 (decimal) Import Module 001: MFC80U.DLL Import Module 002: MSVCR80.dll Import Module 003: KERNEL32.dll Копирует указанные библиотеки в папку с *.exe файлом. Идем на машину с windows xp. .net не установлена. Запускаем программу Сообщение. Не удается выполнить указанную программу. Здесь дело не в том, что программа использует .net, а в том, что используется новый способ загрузки dll. Я не уверен, но думаю что здесь речь идет не о том манифесте о котором говоришь ты, т.к этот нушен не для тем, а исключительно для контроля версий dll. Smarts, вот ссылка извини за localhost http://www.codeproject.com/cpp/vcredists_x86.asp какой этот? если ты про dll, то варианты все равно могут быть. |
Автор: Earnest 23.4.2007, 11:43 |
??? dizzy1984, я честно сказать, с VC2005 не проверяла, но ты что же, хочешь сказать, что он не может создать приложение для не XP? Для всяких там 98-2000, которые про манифесты и нетворки слыхом не слыхали? Вот 2003 может, а стало быть 2005 - уже нет? Не такие же в MS придурки... |
Автор: Любитель 23.4.2007, 12:16 |
Насчёт dotnetfx. Его нужно таскать только если юзаем дотнет. Иначе - нафиг не надо. Второе - манифесты и всё, что с этим связано. Для начала лирическое отступление. В XP появилась такая ерунда как загрузка длл с помощью манифестов. В таблицу импорта кидается обычный импорт из длл-ки, именно он сработает не на XP (точнее до ИксПи). В ресурсы (или в папку с экзешником/длл-кой) кидается манифест, в котором описывается та длл-ка, которая нам нужна. На определённой машине будет загружена нужная длл-ка, берущаяся из %WinDir%\WinSxS\<arch_name>_<lib_name>_<key>. Где ключ берётся из версии либы и сертификата безопкасности производителя (какая там хеш-функция - не знаю). При этом гарантируется, что с одной сторона будет загружена последняя (доступная на компе) версия длл (со всеми хотфиксами), а с другой - бэквард компатибилити будет соблюено. Для этого и критерии в манифестах (+ папочка $WinDir%\WinSxS\Manifests). Библиотека commctl32.dll входит в XP в двух видах: 5-ая версия в system32 и 6-ая в недрах WinSxS. Последнюю соответственно загружаем с помощью манифестов. Отсюда Visual Styles и требуют манифестов. VS 2005 весь рантайм (VC Runtime, VC++ Runtime, ATL, MFC) грузит через манифесты по дефолту. Енто можно отключить в пропертях проекта, если нужно. Если же не отключаем, то: 1. До XP всё работает обычно. 2. Винда >= XP будет грузить эти либы только через манифесты (раз манифест есть). Иначе ни как. Наиболее грамотный способ такскать с собой маленький экзешник VC++ 2005 Redistutable (правильно написал? ![]() ![]() ЗЫ И читайте всякие What's new почаще. А то студию ставим, а посмотреть что й же здесь нового ленимся. ![]() |
Автор: Любитель 23.4.2007, 13:11 | ||||
Не, я верно сказал, только что точно в пропертях надо ставить не могу сказать - студии нет под рукой. Ты что хочешь? Варианты ответа: 1. Такскать инсталятор и нормально развёртывать приложение - юзай MS-шный пакет, ставящий рантайм (могу ссылку дать, если надо). 2. Таскать папочку и с неё сразу запускать - отключи манифест и таскай *.exe + msvcr80.dll + [msvcp80.dll] + [mfc80.dll] ... ([] - опционально). 3. Таскать один экзешник - ставь статическую линковку. Не только MFC, но и рантайма. Последнее, по-моему, в C++ > Code generation. Но может и где-то в ликер-опциях. Я не помню. :( Добавлено через 59 секунд Кстати, есть ещё (насколько я помню) опции Manifest Tool - посмотри, что там запрятано ![]() Добавлено через 4 минуты и 17 секунд
А вот это никогда не будет. Точно. |
Автор: dizzy1984 23.4.2007, 13:23 | ||||
Я бы хотел использовать динамическую линковку и конечно мне нет дело до манифестов.
Я не проникся идеологией манифестов.
Я проверил этот вариант. Отключение манифеста не приводит к обычному способу загрузки dll. Так и живем, но это неправильно. |
Автор: Любитель 23.4.2007, 13:24 | ||||
Разумней всего всё-таки таскать reditutable пакте рантайма. Он ставится корректно на любую винду и всё работает как надо. Статическая линковка - это крайний случай. Отключение манифестов - тоже не желательно. МС так старались, этот пункт (рантайм через манифесты) объявлен как один из рулезов VC++ 2005... ![]()
Добавлено через 1 минуту и 22 секунды
Ты как-то не так отключаешь. Сегодня вечером я посмотрю в студии, разберусь. На днях (как доберусь до инета) - расскажу. ОК? |
Автор: dizzy1984 23.4.2007, 13:33 | ||
Ты хочешь сказать, что для утилиты которая выполняет подсчет букв в слове (говорю условно чтобы показать простоту утилиты) мне нужно сделать примерно следующее. 1. Скачать и поставить последний сервис пак windows. 2. Поставить Windows Installer 2.0. 3. Поставить Windows Internet Explorer 6.0 4. Поставить Windows Installer 3.0. 5. Поставить VcRedist_x86.exe Наслаждаться выводом 15-ти строк на экране консоли. Я думаю это не тот случай, когда лучше использовать манифесты
OK ![]() |
Автор: Любитель 23.4.2007, 13:56 |
Этот - да, абсолютно верно. Я писал все три варианта выше, выбор зависит от масштабности проекта (ну и от личных вкусов). В данном случае я бы вообще линковал статически, но это уже "на вкуси цвет", т. е. мелочи и не подлежит обсуждению. ЗЫ А с манифестами разберусь - сейчас просто студии под рукой нет. |
Автор: Niko_ 24.4.2007, 11:21 |
Все тот же наболевший вопрос, откомпилил прогу на своей машине все работает, приношу заказчику вот такая ошибка, подскажите как побороть |
Автор: _hunter 24.4.2007, 11:46 |
в свойствах проекта ветка С++ (там кодогенератор) выбери вариант "многопоточная" |
Автор: Smarts 24.4.2007, 14:59 | ||||||
Cпасибо, это как раз то что нужно. Установил данный пак на том компьютере и все заработало без ошибок ![]() Niko, попробуй то же самое, должно помочь ;) |
Автор: vano 24.4.2007, 17:27 |
Скажите, статическая линковка это- Configuration proprieties -> general -> Use MFC in Static Library ? Если да, то как её использовать, как я понял она требует отключения опции /CLR. А без опции CLR не корректно следующее. #usig <System.dll>. А без System dll не могу сделать MessageBox::Show("Hellow World"); Вопрос. Как используя статическую линковку, использовать например MessageBox? ------------------------ Поставил Redistributable Pack - Тоже самое ( проекты с DLL MFC + /clr option не идут). --------------------------------------------- Похоже manifest отключать нельзя. Вот, что компилятор говорит "An application has made an attempt to load the C runtime library without using a manifest. This is an unsupported way to load Visual C++ DLLs." Я так понимаю, что из этого следует, что с MFC, без manifest работать нельзя. |
Автор: Любитель 28.4.2007, 16:55 |
1. CLR - Common Language Runtime, т. е. .Net Framework. Юзать его ради месаджбокса - очень жестоко. Вызывай месадж-бокс из ВинАПИ ![]() 2. Прикол в том, что ... это правда. Помогает патчинг DllMain (на неё любой дизасм вас выкинет ![]() Согласно, MSDN - лучший вариант таков (если нет доступа на запись в виндовые папки, но не хотим статик-линк): 1. Собираем со стандартными настройками. 1. У себя из %WinDir%\WinSxS\Manifests тащим манифест x86***Mirosoft.VC80.CRT***.manifest и (не уверен в необходимости) сертификат безопасности x86***Mirosoft.VC80.CRT***.cat в папку к экзехе. 2. Ренеймим его в Microsoft.VC80.CRT. Для локальных сборок (assembly) никакие хеш-ключи не нужны ![]() 3. Копируем сюды же (к экзехи) из %WinDir%\x86***Mirosoft.VC80.CRT*** длл-ки. msvcr80.dll - в любом случае, msvcp80.dll - плюсовая стандартная либа (не шаблонами едиными...), msvcm80.dll - поддержка OpenMP. Усё. В доикспишных системах будет идти загрузка длл-ок, исходя из таблицы импорта, а икспи и > - попробует вначале системный вариант, а затем (не найдя там ничего) - локальные сборки. PS Будьте внимательны. У меня было три версии CRT. И соответственно три манифеста (+ *.cat-ы). Хеш-ключи, конечно у всех разные. Причём один манифест (и одна длл-ка) ни с чем не состыковалась ![]() ![]() ![]() |