Я недавно прошел набор автономных служебных приложений, записанных в VB6, чтобы удостовериться, что виртуализация реестра выключена для Windows Vista и выше. Я создал автономный файл манифеста для каждого exe, установите requestedExecutionLevel
соответственно (некоторые из них должны изменить HKEY_LOCAL_MACHINE
ключи реестра, другие не делают), и протестировал их. Они все, кажется, работают правильно.
У меня есть только одна небольшая проблема, оставаясь. Так как они - автономные утилиты, люди привыкли только к копированию их вокруг сети и выполнения их вручную. Если кто-либо забудет копировать файл манифеста, а также exe, то exe тихо запишет в виртуализированный ключ реестра вместо реального и вызовет трудные к отладке проблемы.
Очевидное решение состоит в том, чтобы встроить декларацию в exe как ресурс. Все статьи, которые я прочитал в сети, говорят Вам встраивать ресурс как это:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
#define RT_MANIFEST 24
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "app.manifest"
Это должно работать просто великолепно, за исключением того, что компилятор VB всегда создает значок приложения с идентификатором ресурса = 1. Когда я попробовал вышеупомянутый код, Windows отказался выполнять exe, жалующийся на ошибку ресурса (я обновлю это сообщение с деталями позже). Я пытался изменить идентификатор ресурса на другое число, после которого Windows запустил программу успешно, но не распознал явное содержание.
Кто-либо знает о способе заставить встроенную декларацию работать в VB6 exe, или я должен просто придерживаться внешнего файла?
ОБНОВЛЕНИЕ 1
Текст, данный выше, является целым содержанием .rc
файл. Я компилирую его в a .res
файл как это:
"%ProgramFiles%\Microsoft Visual Studio\VB98\Wizards\rc.exe" /r /fo "Resources.res" "Resources.rc"
И встройте его в файл проекта VB6 как это:
Type=Exe
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\..\WINDOWS\system32\stdole2.tlb#OLE Automation
Form=Main.frm
ResFile32="Resources.res"
IconForm="FMain"
Startup="FMain"
HelpFile=""
Title="Windows Vista Registry Test - VB6"
ExeName32="RegistryTestVB6.exe"
Path32=""
Command32=""
Name="RegistryTestVB6"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionComments="Windows Vista Registry Test - VB6"
VersionCompanyName=""
VersionFileDescription="Windows Vista Registry Test - VB6"
VersionLegalCopyright=""
VersionProductName="Windows Vista Registry Test - VB6"
CondComp=""
CompilationType=0
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1
Когда я считал скомпилированный exe в редактора ресурса VS2008, он похож на это:
RegistryTestVB6.exe
Icon
1 [Neutral]
RT_MANIFEST
1 [English (United States)]
Version
1 [English (United States)]
Когда я создаю точное эквивалентное тестовое приложение VB.NET в VS2008, затем загружаю это в редактора ресурса, он похож на это вместо этого:
RegistryTestNET.exe
Icon
32512 [Neutral]
RT_MANIFEST
1 [Neutral]
Version
1 [Neutral]
ОБНОВЛЕНИЕ 2
При тестировании-.NET exe хорошо работает и на Windows XP и на Windows 7. Однако VB6 exe производит следующую ошибку на XP:
Этому приложению не удалось запуститься, потому что конфигурация приложения является неправильной. Переустановка приложения может решить эту проблему.
и следующая ошибка на 7:
Приложению не удалось запуститься, потому что бок о бок конфигурация является неправильной. См. журнал событий приложения или используйте инструмент sxstrace.exe командной строки для большего количества детали.
Взгляд в конечном счете регистрируется, я вижу следующую запись:
Поколение контекста активации перестало работать для "RegistryTestVB6.exe". Ошибка в декларации или файле политики "RegistryTestVB6.exe" на строке 10. Недопустимый синтаксис XML.
Само собой разумеется, XML не недопустим, это - точно тот же файл с тем же кодированием, которое я использовал для.NET exe, и что каждый работает.
РАЗРЕШЕНИЕ
Компилятор VB6 действительно требует, чтобы произвольный текстовый файл, включенный в ресурс, был точным несколько 4 байта. Я просто добавил пробелы к XML, пока Блокнот ++ не сказал мне, что общий размер файла включая BOM был кратным 4.
И благодаря Michael и благодаря Jim для указания на меня в корректном направлении. Просто жалость я не могу отметить Вас обоих как ответ!
Интересно, что недавно мне пришлось сделать то же самое. Следуя шагам, описанным Кристианом, я заставил это работать с первого раза. Для процветания вот весь рабочий процесс, которому я следовал:
Создал app.manifest, сохранив пробельные символы, которые ОЧЕНЬ ВАЖНЫ для того, чтобы это работало. Как указывалось в предыдущих ответах, размер файла должен быть кратным 4.
Запуск RC.EXE, как описано в исходном вопросе, против rc для создания файла .res
ResFile32 = "Resources.res"
Встроенный EXE в стандартной среде vb6. При развертывании на машине Vista или Win7 появляется экран, и пользователю предлагается запустить его от имени администратора. При открытии EXE-файла в студии я проверил ресурсы.
Notepad ++ сообщает мне, что в моем файле app.manifest используется кодировка ANSI. Он не включал отметку порядка байтов в начале файла.
Если у вас все еще есть проблемы, дайте мне знать, и я поделюсь с вами всем, чем смогу. Кроме этого, я не знаю, что вам сказать, кроме Работает на моей машине!
VB6 имеет причуду в том, что любой ресурсный элемент должен быть точным кратным 4 в длину. Попробуйте заполнить файл манифеста пробелами, чтобы убедиться в этом, и посмотрите, изменит ли это поведение.
Эта причуда была задокументирована в статье Microsoft Q297112 (архив) .
Также, вы можете добавить ресурс, используя VB6 IDE вместо редактирования VBP. Эффект может быть таким же, но редактор ресурсов является стандартным средством для этого.