Как заставить родное приложение использовать более старую среду выполнения C - PullRequest
4 голосов
/ 23 июня 2010

Visual Studio 2010 устанавливает версию ... 4974 среды выполнения VC9, чьи .pdbs недоступны .Как заставить мой GME.exe использовать более старую среду выполнения VC9?

Я пытался поместить это в GME.exe.config:

<?xml version="1.0"?>
<configuration>
  <windows>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <assemblyIdentity type="win32" name="GME" processorArchitecture="x86" version="1.0.0.1"/>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86" />
        <bindingRedirect oldVersion="9.0.21022.8-9.0.21022.4974" newVersion="9.0.30729.4148" />
        <bindingRedirect oldVersion="9.0.30729.0-9.0.30729.4974" newVersion="9.0.30729.4148" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86" />
        <bindingRedirect oldVersion="9.0.21022.8-9.0.21022.4974" newVersion="9.0.30729.4148" />
        <bindingRedirect oldVersion="9.0.30729.0-9.0.30729.4974" newVersion="9.0.30729.4148" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.ATL" publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86" />
        <bindingRedirect oldVersion="9.0.21022.8-9.0.21022.4974" newVersion="9.0.30729.4148" />
        <bindingRedirect oldVersion="9.0.30729.0-9.0.30729.4974" newVersion="9.0.30729.4148" />
      </dependentAssembly>
    </assemblyBinding>
  </windows>
</configuration>

Однако отчеты sxstrace:

INFO: Resolving reference Microsoft.VC90.CRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8"
....
INFO: Publisher Policy redirected assembly version.

Добавление <publisherPolicy apply="no"/> в <dependentAssembly> приводит к ERROR: Activation Context generation failed. без другой полезной информации в Windows 7.

Обратите внимание, что это только для отладки моей локальной копии, а не для перераспределения, поэтому яне беспокоиться об обновлениях безопасности или других преимуществах политики издателя.

Ответы [ 4 ]

6 голосов
/ 23 июня 2010

Ответ приходит от http://blog.kalmbachnet.de/?postid=80

Хитрость заключается в том, чтобы удалить из манифеста приложения атрибут publicKey в assemblyIdentity, чтобы WinSxS не использовался.

GME.exe.manifest:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="x86">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.30729.4148" processorArchitecture="x86">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.ATL" version="9.0.30729.4148" processorArchitecture="x86">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*">
      </assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

Вложите манифест в GME.exe (для модификации dll подставьте 1 для 2):
mt -manifest GME.exe.manifest -outputresource:GME.exe;1

Затем скопируйте необходимые библиотеки:
cp -a windows/winsxs/x86_microsoft.vc90.{atl,crt,mfc}*30729.4148*/*dll path-to-app/

Затем создайте манифесты для каждой сборки, для которых SxS не используется, и поместите их рядом с приложением.Манифесты основаны, например, на C:\Windows\WinSxS\Manifests\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_5090ab56bcba71c2.manifest:
Microsoft.VC90.CRT.Manifest:

<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="x86"></assemblyIdentity>
    <file name="msvcr90.dll"></file>
    <file name="msvcp90.dll"></file>
    <file name="msvcm90.dll"></file>
</assembly>

Невозможно удалить ссылки на сборки из манифеста приложения, так как CRT жалуется, что он не загружаетсячерез SxS.

К сожалению, кажется, что необходимо изменить манифест для каждой зависимой библиотеки DLL в приложении, включая библиотеки DLL, скопированные из WinSxS, или может быть загружено несколько версий.

Вот скрипт bash, которыйработал для меня, где ~ / Documents / sxs-hack / содержит библиотеки CRT и измененные манифесты:

rm -rf bin
mkdir bin
cp -a ~/Documents/sxs-hack/* bin/
find -iname \*.dll -or -iname \*.ocx -or -iname \*.exe | while read -r file; do
  cp -a "$file" bin/"$(basename $file)"
  export file=bin/"$(basename $file)"
  export res=$file\;2
  if [ ${file:${#file}-3} = "exe" ]; then export res=$file\;1; fi
  echo $file
  mt.exe -nologo -inputresource:"$res" -out:extracted.manifest &&
  perl -pli -e 's/(Microsoft.VC90.[^>]*)version="[^"]*"([^>]*)publicKeyToken="[^"]*"/$1 $2 version="9.0.30729.4148"/g;' extracted.manifest &&
  mt -nologo -manifest extracted.manifest -outputresource:"$res"
  regsvr32 /s "$file" || true
done
2 голосов
/ 25 июня 2010

Вот способ заставить приложение Config работать с Win2003 и более поздними версиями:

http://www.tech -archive.net / Archive / VC / microsoft.public.vc.ide_general / 2008-01/msg00033.html

По сути, необходимо добавить приложение в базу данных совместимости с помощью «EnableAppConfig»

Это задокументировано здесь:

http://msdn.microsoft.com/en-us/library/ee710783%28VS.85%29.aspx

Работает GME.exe.Config:

<?xml version="1.0"?>
<configuration>
  <windows>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
        <publisherPolicy apply="no"/>
        <bindingRedirect oldVersion="9.0.21022.0-9.0.21022.4974" newVersion="9.0.30729.1" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86"/>
        <publisherPolicy apply="no"/>
        <bindingRedirect oldVersion="9.0.21022.0-9.0.21022.4974" newVersion="9.0.30729.1" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity type="win32" name="Microsoft.VC90.ATL" publicKeyToken="1fc8b3b9a1e18e3b" processorArchitecture="x86"/>
        <publisherPolicy apply="no"/>
        <bindingRedirect oldVersion="9.0.21022.0-9.0.21022.4974" newVersion="9.0.30729.1" />
      </dependentAssembly>

    </assemblyBinding>
  </windows>
</configuration>

Кажется, это нужно делать и для загруженных .dll.

0 голосов
/ 25 июня 2010

Вот как отключить политику издателя в Vista или 7:

Перейдите в HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ SideBySide \ Winners \ x86_policy.9.0.microsoft.vc90.crt_1fc8b3b9a1e18e3b_none_02d0010672fd8213 * 9.0

Установите ключ по умолчанию для нужной версии, например, 9.0.30729.4148. Установите версию, которую вы не хотите, равной 0, например, "9.0.30729.4974" = 00.

Вы должны сделать это для crt, atl, mfc и т. Д.

WinSxS, кажется, кеширует политику. Это сработало для меня: коснитесь (1) приложения, затем установите HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ SideBySide \ PublisherPolicyChangeTime на что-то низкое, например, 10.

Это отключит более новую среду выполнения для всей системы.

0 голосов
/ 23 июня 2010

Если у вас есть источник, вы всегда можете статически связать библиотеку c-runtime, которую вы хотите использовать ... Не всегда самая лучшая идея, но если вы унаследовали библиотеку монстров, которая будет работать только в режиме отладки, ине может перераспределить CRT отладки, он сделает свое дело ...

...