DOBON.NET DOBON.NETプログラミング掲示板過去ログ

Msvcrt80.dllについて

環境/言語:[WindowxXP Visual Studio 2005 SP1 ATL セキュリティ更新プログラム]
分類:[その他]

Visual Studio 2005 SP1の環境でDLLを開発していました。
Microsoft Updateの設定を行っていたため、
いつの間には使用されるMsvcr80.dllが
8.0.50727.762から
8.0.50727.4053に変わってしまいました。

8.0.50727.4053の再配布用のランタイムが用意されているので
それを使えば動くのですが、
8.0.50727.4053を入れたくないユーザがいて困っています。

「Visual Studio 2005 Service Pack 1 ATL セキュリティ更新プログラム」を
アンインストールして元に戻すのもなんなので、
8.0.50727.762で動かす方法がないかどうか探しています。

8.0.50727.762しかインストールされていない環境で
DLLをDepends.Exeで確認すると
Msvcrt80.dllが見つからないというメッセージが表示されました。

試しに書きのようなDllName.dll.manifestというファイルを作成したところ、
Depends.exeで8.0.50727.762が表示されました。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<configuration>
<windows>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<publisherPolicy apply="no"/>
</assemblyBinding>
</windows>
</configuration>

しかし、
そのDLLを使用しているEXEを実行すると
「アプリケーションを正しく初期化できませんでした(0xc0150002)」と表示され
8.0.50727.4053が見つからないため起動できないようでした。

なにか手はありませんでしょうか?
よろしくお願いします。
これなんかどうだろう
http://crys.uijin.com/program/vc2005/msvcr80.html

もしくは新バージョンのMsvcr80.dllを同梱して配布してしまう。
うまくうごくかしらんが。
返信ありがとうございます。

> これなんかどうだろう
> http://crys.uijin.com/program/vc2005/msvcr80.html

使用するDLLが複数あるため、
スタティックリンクにしてしまうと
ファイルサイズが大きくなったり
メモリの使用量が多くなったりしそうで、
敬遠しています。

> もしくは新バージョンのMsvcr80.dllを同梱して配布してしまう。
> うまくうごくかしらんが。

ユーザーはそれが嫌なようなので。。。。
>>もしくは新バージョンのMsvcr80.dllを同梱して配布してしまう。
>>うまくうごくかしらんが。
>
> ユーザーはそれが嫌なようなので。。。。
Msvcr80.dllをリソースとしてアプリケーションに埋め込んでしまうとか。

マニフェストがいるので、ここらへん参照
http://dev.activebasic.com/egtra/?p=28
返信ありがとうございます。

> Msvcr80.dllをリソースとしてアプリケーションに埋め込んでしまうとか。
>
> マニフェストがいるので、ここらへん参照
> http://dev.activebasic.com/egtra/?p=28

ユーザー側の対応が期待できない状態にあります。
配布するDLLとともにサイズの小さなファイルを置くくらいなら
対応してもらえると思うのですが、
アプリケーションの変更などはしてもらえそうにありません。

SideBySideやマニフェストについて調べているのですが、
理解できずにいます。

現在テスト用のアプリケーションでは
8.0.50727.762を使用するように
マニフェストが埋め込まれています(mt.exeで抽出して確認済)。

DLLの使用には
8.0.50727.4053が必要ですが、
マニフェストは埋め込まれていないようです。(mt.exeで抽出を試みるとエラーになる)。
DLLにはマニフェストがないのに、
なぜ8.0.50727.762で動作しないのでしょうか?
どこで8.0.50727.4053が指定されているのでしょうか?
自己レス

> DLLの使用には
> 8.0.50727.4053が必要ですが、
> マニフェストは埋め込まれていないようです。(mt.exeで抽出を試みるとエラーになる)。
> DLLにはマニフェストがないのに、
> なぜ8.0.50727.762で動作しないのでしょうか?
> どこで8.0.50727.4053が指定されているのでしょうか?

インポートライブラリに指定があるようですね。
DLLの検索・ロードの仕様は・・・
環境変数PATHにも依存していますが、カレントが最優先だったはず。
なので、EXEと同じところにその必要なDLLを置けば、それをロード
し使用しない?

もし、例えばC:\Windows\System32\〜にあるDLLを使用しているのか
カレントのDLLを使用しているのか調べるならば、そのEXEを起動し
てカレントのDLLを削除等してみれば解るかと。

削除できない(ロックされている)ならば、そのDLLが使用されて
いる。削除できてしまえば・・・残念ながら別の方法で指定する
しかない・・・

以上。参考まで
  • 題名: Re[7]: Msvcrt80.dllについて
  • 著者: zantetsu
  • 日時: 2009/10/09 10:39:38
  • ID: 25565
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示

> 自己レス
> インポートライブラリに指定があるようですね。

間違えました。
インポートライブラリは関係ないようです。

回答ありがとうございます。
> DLLの検索・ロードの仕様は・・・
> 環境変数PATHにも依存していますが、カレントが最優先だったはず。
> なので、EXEと同じところにその必要なDLLを置けば、それをロード
> し使用しない?
WindowsXP以降では異なるようです(Side By Side)。
Msvcr80.dllをEXEと同じフォルダにおいても動作しません。
マニフェストを書けば動作するようにできるようですが。。。

>>マニフェストがいるので、ここらへん参照
>>http://dev.activebasic.com/egtra/?p=28
>
> ユーザー側の対応が期待できない状態にあります。
> 配布するDLLとともにサイズの小さなファイルを置くくらいなら
> 対応してもらえると思うのですが、
> アプリケーションの変更などはしてもらえそうにありません。

Msvcr80.dllとマニフェストファイルをコピーすれば
アプリケーションの変更は不要ですね。
とりあえず現時点ではそれが一番無難な解決方法のようです。

ただ、下記の2点が疑問として残っています。
(1) 作成したDLLでどのようにMsvcr80.dllのバージョンが指定されているのか?
mt.exeでマニフェストは抽出できないので、
作成したDLLにはマニフェストが埋め込まれていないと思われる。
(2) DLLが使用するMsvcr80.dllのバージョンを変更できないのか?
DLL用のマニフェストを記述するとDepends.exeでエラーがでなくなったので、
効果はあるようだがアプリケーションで作成したDLLを呼び出した際は
効果がない。
  • 題名: Re[6]: Msvcrt80.dllについて
  • 著者: zantetsu
  • 日時: 2009/10/09 11:21:12
  • ID: 25567
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
自己レス

> (1) 作成したDLLでどのようにMsvcr80.dllのバージョンが指定されているのか?
> mt.exeでマニフェストは抽出できないので、
> 作成したDLLにはマニフェストが埋め込まれていないと思われる。

マニフェストが埋め込まれていました。
mt.exeでエラーになったのですが、
Visual Studio2005から直接開いたところ、
マニフェストを確認できました。

mt.exeの使い方が悪かっただけかもしれません。
> Msvcr80.dllとマニフェストファイルをコピーすれば
> アプリケーションの変更は不要ですね。
> とりあえず現時点ではそれが一番無難な解決方法のようです。

と思ったのですが、
やっぱり動きませんでした。
EXEでMsvcr80.dllを使用している場合は機能しても
DLLで使用している場合は機能しないのかもしれません。

> (1) 作成したDLLでどのようにMsvcr80.dllのバージョンが指定されているのか?
> mt.exeでマニフェストは抽出できないので、
> 作成したDLLにはマニフェストが埋め込まれていないと思われる。

抽出したマニフェストは以下のようになっていました。
これはどういう意味なんでしょうか?
(A) 8.0.50727.4053がなかったら8.0.50727.762を使う
(B) 8.0.50727.4053と8.0.50727.762を両方使う

(A)だったら動いてくれてよいと思うのですが。

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.4053" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
</dependentAssembly>
</dependency>
</assembly>
2009/10/09(Fri) 12:36:33 編集(投稿者)

> 抽出したマニフェストは以下のようになっていました。
> これはどういう意味なんでしょうか?
> (A) 8.0.50727.4053がなかったら8.0.50727.762を使う
> (B) 8.0.50727.4053と8.0.50727.762を両方使う
> 
> (A)だったら動いてくれてよいと思うのですが。

どうも見てると(B)のようです。


(A) のように動作させるなら <bindingRedirect> 要素を使うみたいですね。
以下 MSDN の使用例が参考になりそうです。

http://msdn.microsoft.com/ja-jp/library/eftw1fys(VS.80).aspx

これを参考にしてアプリケーションフォルダのDLLを優先的に使用させるなら
762 をマニフェストから削除し、

<dependentAssembly>
   <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" 
       version="8.0.50727.4053" processorArchitecture="x86" 
       publicKeyToken="1fc8b3b9a1e18e3b">
   </assemblyIdentity>
   <bindingRedirect oldVersion="8.0.50727.762"
                    newVersion="8.0.50727.4053"/>
</dependentAssembly>

とマニフェストを編集するようですが、これでどうでしょうか?
■No25569に返信(ひらぽんさんの記事)
> 2009/10/09(Fri) 12:36:33 編集(投稿者)

書いた後に「編集」で変更したらちょっとおかしくなりました。
ご了承ください。<(_ _)>
返信ありがとうございます。

> どうも見てると(B)のようです。

確認したところ、
DLL内部で使用していたスタティックリンクライブラリが
古い環境でビルドしたものでした。

SideBySideってDLL地獄を避けるためのようですが、
僕はSideBySide地獄に落ちているように感じます。

作成しなおしたところ、4053の方だけ記述されるようになりました。

> これを参考にしてアプリケーションフォルダのDLLを優先的に使用させるなら
> 762 をマニフェストから削除し、
> とマニフェストを編集するようですが、これでどうでしょうか?

参考になります。
ただ、ユーザーがそこまでしてそうにないので。。。。

EXEと同じフォルダに.manifestを置くくらいならしてもらえると思ったのですが、
Vista以降はEXEに埋め込まれたマニフェストが優先されてしまうそうで。。。。
■No25571に返信(zantetsuさんの記事)
> SideBySideってDLL地獄を避けるためのようですが、
> 僕はSideBySide地獄に落ちているように感じます。

実行環境が古くてそれを変更(更新)できないのに、開発環境を新しくしていることが問題では?
顧客のサポートが必要であるならば、その時点のビルド環境ぐらい残すべきでしょう。(最近なら仮想環境も手でしょう)
それを怠っている以上は、苦しんでも致し方ないかと思います。

なお、本来は 4053 が必要なはずなのに無理に古いバージョンである 763 を要求するように書き換えた場合、ビルド環境とバージョンが一致しないため、何らかの問題が生じても保障は受けられないでしょう。
返答ありがとうございます。

> 実行環境が古くてそれを変更(更新)できないのに、開発環境を新しくしていることが問題では?
> 顧客のサポートが必要であるならば、その時点のビルド環境ぐらい残すべきでしょう。(最近なら仮想環境も手でしょう)
> それを怠っている以上は、苦しんでも致し方ないかと思います。

残す残さないではなくて、
ユーザが要求したのが今回は762だったのです。
ユーザは不特定多数なので、
ひょっとしたら今後は「うちは42だ」という
ユーザも出てくるかもしれません。

ランタイムをDLLで使用する場合は、
古い環境の方が無難なんですね。
■No25574に返信(zantetsuさんの記事)
> 残す残さないではなくて、
> ユーザが要求したのが今回は762だったのです。
元々、762 ではリリースしていなかったと言うことでしょうか?
そうだとすると、「環境を残していなかったのが問題だ」とした指摘は的外れで申し訳ありません。

ただ、4053 で使うことを前提に開発・テストしてきたものに対して、いきなりバージョンを下げるのはリスクがある行為である点は変わりません。
もし、顧客の要望が強く、飲まざる得ないのであれば、開発環境のバージョンを合わせて必要なテストも実施するべきかと思います。
場合によっては、ランタイムのバージョン間の組み合わせのテストもいるかもしれませんね。

DOBON.NET | プログラミング道 | プログラミング掲示板