none
ソースからVisualStudioのバージョンを特定する方法について RRS feed

  • 質問

  • VB.NETで開発したソースファイル(.sln,.vbproj)から、実際に使用したVisualStudioのバージョンを特定する方法を探しています。

    ソリューションファイル(.sln)に記述されているバージョンと、プロジェクトファイルに記述されているProject ToolsVersion,ProductVersion,OldToolsVersionで判断できそうなのですが。

    たとえば、ソリューションファイルに下記のとおり記述されています。

    Microsoft Visual Studio Solution File, Format Version 11.00
    # Visual Basic Express 2010

    プロジェクトファイルには下記のとおり記述されています。

    <Project ToolsVersion="4.0">

    <ProductVersion>9.0.21022</ProductVersion>

    <OldToolsVersion>3.5</OldToolsVersion>

    ソリューションファイルの記述がVB2010で、プロジェクトのProductVersionが9.0.21022なので、

    もともと2008で開発したものを2010にバージョンアップしたのではないかと思われるのですが。

    この方法で正しくバージョンが特定できているでしょうか。

    もしくは他に特定する方法があれば、教えていただけないでしょうか。

    2017年11月7日 5:30

回答

  • .Net のモジュールであればもしかすると EXE や DLL の中に Visual Studio のバージョンが直接埋まっているのかもしれませんが、私にはわかりませんでした。別の方法として Dumpbin などのツールで EXE や DLL の PE ヘッダーを覗くと Visual Studio のバージョンの特性が見えてくるかもしれません。例えば、下記の項目は以下のようになっていました。他の項目等比較するともう少し特定できるかもしれません。

    ※ 数値は Visual Studio の初期設定でビルドを行った結果です。環境や設定の違いによって別の結果になることがあります。

    エクスプローラからドロップされた EXE や DLL の PE ヘッダーを表示するツールを公開しています。
    https://github.com/kenjinote/GetPEHeader
    もし良かったら使ってみてください。

    • 回答としてマーク DSC0803 2017年11月7日 13:56
    • 編集済み kenjinoteMVP 2017年11月8日 0:48 補足を追記
    2017年11月7日 12:55
  • これも既に説明しましたが、MajorSubsystemVersionはコンパイラーには依存せずプロジェクトのターゲットフレームワークバージョンの設定に依存します。

    まずMajorSubsystemVersionはWindowsがプログラム起動時にサポートしているバージョンかどうかのチェックに使われる値です。そして.NET Framework 4.5以降はWindows XPをサポート外としています。そのため、ターゲットフレームワークバージョンが4.5以上を指定された場合に、Windows XPで動作しないようにするためにMajorSubsystemVersionの値が6に変更されます。

    先のkenjinoteさんの表にVB2012 => 6 と記されていますが、これは単にkenjinoteさんが確認を行う際に作成したプロジェクトのターゲットフレームワークバージョンが4.5以降を設定していたことを示しているだけに過ぎず、4.0以下に設定し直せばこの値が 4 に変化します。

    結局、現時点で判明しているのは

    • VB2010でプロジェクトのコンバートが行われた
    • VB2010 / VB2012 / VB2013いずれかを使用した
    • VB2012 / VB2013でプロジェクトの設定変更は行っていない
    • VB2012の可能性は低い(VB2012のMicrosoft.VisualBasic.PowerPacks.Vs.dllが使われていない)
    • .NET 4以降でビルドされた

    くらいです。

    • 回答としてマーク DSC0803 2017年11月8日 9:33
    2017年11月8日 8:19

すべての返信

  • Visual Studio 2010以降は.slnファイル、.projファイル共に互換性が強化され、コンバートなしで開くことができるようになっています。そのため、コンバートを行ったのはVB2010かもしれませんが、その後、VB2012 / VB2013 / VB2015 / VB2017で開かれたことがないかと問われると不明です。

    逆に、上記のような互換性がありますので、質問者さんがバージョンを特定しようとする目的を教えて頂けたらと思います。

    2017年11月7日 6:28
  • 返信ありがとうございます。

    各種ソースファイルとexeファイル・dllファイルだけが存在している状態で、

    実際にどのバージョンでビルドされているのか知りたいのです。

    少なくとも2010以降であることは間違いないが、

    2012以降であっても.sln,.vbprojの中身は質問のような状態になりうる。

    それ以上詳細に特定することは.sln,.vbprojからでは難しいということでしょうか。

    2017年11月7日 7:01
  • 各種ソースファイルとexeファイル・dllファイルだけが存在している状態で、実際にどのバージョンでビルドされているのか知りたいのです。

    ビルドとなると更に厄介です。Visual StudioはWindowsにインストールされているコンパイラーを呼び出しているだけですので、Visual Studioのバージョンに依らず.NET Framework 4.7.1がインストールされていれば、.NET Framework 4.7.1コンパイラーが使われてしまいます。

    なお、Visual Studio 2015以降はRoslynコンパイラーが登場していて、(おおよそ)Visual Studio付属のコンパイラーが使われるようにはなっていますが…質問の内容から察するにVB2015やVB2017の可能性は低いですよね?

    2017年11月7日 7:44
  • いちおう.vbprojには、<TargetFrameworkVersion>v2.0と指定されていました。

    それと付属のインストーラーでインストールしたフォルダを確認したところ、

    VB2010版のMicrosoft.VisualBasic.PowerPacks.Vs.dllが配置されているようです。

    これだけではVB2010であるという根拠にはならないでしょうか?

    2017年11月7日 8:23
  • まったく頓珍漢な返信かもしれませんが。。。
    Exe / Dll 等のバイナリ ファイルから、ビルドに使用した Visual Studio のバージョンを割り出したい。。。ということでしょうか?
    もしそーいうことであれば、Dependency Walker (depends.exe) でそのバイナリ ファイルがインポートしている外部 DLL の依存関係を調べてみては?

    -----------------------------------------
    Visual C++ アプリケーションの依存関係の理解
    https://msdn.microsoft.com/ja-jp/library/ms235265.aspx
    -----------------------------------------

    VB のことは全くわからないのでズレてるかもしれませんが。。。
    Visual C++ 再頒布可能みたく、バージョン毎に個別の DLL がリンクされているのではないかと思った次第です。
    (頓珍漢な返信でしたら、ご容赦ください。)
    2017年11月7日 9:31
  • >お馬鹿 さん

    返信ありがとうございます。

    DependencyWalkerでDLLを調べてみましたが

    Windows系のDLLばかりでVB関連のDLLは見当たりらないようです。

    せっかく教えていただいたのですが、

    残念ながらこの方法でVisualStudioのバージョンを特定するのは難しそうです。

    2017年11月7日 11:28
  • .Net のモジュールであればもしかすると EXE や DLL の中に Visual Studio のバージョンが直接埋まっているのかもしれませんが、私にはわかりませんでした。別の方法として Dumpbin などのツールで EXE や DLL の PE ヘッダーを覗くと Visual Studio のバージョンの特性が見えてくるかもしれません。例えば、下記の項目は以下のようになっていました。他の項目等比較するともう少し特定できるかもしれません。

    ※ 数値は Visual Studio の初期設定でビルドを行った結果です。環境や設定の違いによって別の結果になることがあります。

    エクスプローラからドロップされた EXE や DLL の PE ヘッダーを表示するツールを公開しています。
    https://github.com/kenjinote/GetPEHeader
    もし良かったら使ってみてください。

    • 回答としてマーク DSC0803 2017年11月7日 13:56
    • 編集済み kenjinoteMVP 2017年11月8日 0:48 補足を追記
    2017年11月7日 12:55
  • 本筋については確定的な追い込み方はないと思っています。
    また、今時の .NET は Visual Studio のバージョン合わせ込みはあまり効果がないように思っています。
    どうして、特定したいのか、その理由・背景を明らかにしていった方が良いですね。

    VB のことは全くわからないのでズレてるかもしれませんが。。。
    Visual C++ 再頒布可能みたく、バージョン毎に個別の DLL がリンクされているのではないかと思った次第です。
    (頓珍漢な返信でしたら、ご容赦ください。)

    すでに質問者からもコメントがありますが、VB.NET および C# でコンパイルされる、MSIL の exe および dll は、mscoree.dll への依存のみでバージョン特定には至りません。
    マネージコードにおける依存関係はネイティブコードのように DependencyWalker で見えるようなところには出てこない感じです。
    .NET 独自のメタデータになっている…はず。さらに、そのメタデータに出てくるバージョンも開発環境によって特有の情報が残らないに等しい状態)


    2017年11月7日 13:18
    モデレータ
  • DSC0803 さま よろしく。

    以下、参考になりますでしょうか。  例示は VS2008 SP1 のケースです。

    My Project の中の Settings.Designer.vb に 以下の記述があります。

    Namespace My
        <Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(),  _
         Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0"),  _
         Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)>  _

    また、 Debug / Release  Folder があれば、 xxx.vshost.exe に以下の属性があります(オブジェクトブラウザ上)。 

    System.Reflection.AssemblyProductAttribute("Microsoft (R) Visual Studio (R) 2008"),

    違っていれば、お許しを。
    ただし、意味があるのでしょうか?。 バージョンを特定する事に。

    • 編集済み ShiroYuki_Mot 2017年11月7日 13:56 (オブジェクトブラウザ上)追記
    2017年11月7日 13:37
  • >kenjinote さん

    返信ありがとうございます。

    PEヘッダーの内容を確認したところ、

    MajorLinkerVersion は11、MajorSubsystemVersion は 4 でした。

    この2つに該当するバージョンは2010だけのようなので、

    2010と特定してよさそうですね。

    ありがとうございました。

    2017年11月7日 13:49
  • 先に説明したようにVisual Studioは.NET Frameworkに付属のコンパイラーを呼び出すだけですので、この表はあくまでビルドに使用したコンパイラーの生成結果であり、つまりビルドを実行したPCにインストールされている.NET Frameworkのバージョンを示すものでしかありません。
    MajorLinkerVersionはコンパイラーにより決定される値であり、MajorSubsystemVersionはプロジェクトのターゲットフレームワークバージョンに依存します(.NET 4.0ターゲットでは4を示し、4.5以降では6?になります)。
    2017年11月7日 14:38
  • >Azulean さん

    返信ありがとうございます。

    ソースやexeからバージョンを厳密に特定は難しく、

    この状態で確実に言えることはVB2010以降で作成されているくらいということですね。

    お手数をおかけしました。

    2017年11月8日 2:54
  • >ShiroYuki_Mot さん

    返信ありがとうございます。

    そんなところにも情報が存在したのですね。参考になりました。

    2017年11月8日 4:48
  • 佐祐理 さん

    ご指摘ありがとうございます。

    ちなみに.NET4.0までインストールされている環境でも、

    プロジェクトの対象Frameworkに2.0を指定した場合、

    そのプロジェクトは2.0でビルドされる認識です。

    よって今回の例では<TargerFrameworkVersion>が2.0なので、

    .NET2.0でビルドされていると思っています。

    2017年11月8日 5:01
  • 根拠のない思い違いです。

    .NET Frameworkは2.0から過去バージョン向けのバイナリも生成できるようになっています。そのため、Visual Studioはターゲットバージョンに依らず呼び出すコンパイラーは常に同じです。

    2017年11月8日 6:31
  • 佐祐理 さん

    ご指摘ありがとうございます。

    そうすると今回の例ではMajorLinkerVersion は11、MajorSubsystemVersion は 4 なので、

    VB2010と.NETFramework4.0でコンパイルされたと考えられるということですね。

    2017年11月8日 7:40
  • これも既に説明しましたが、MajorSubsystemVersionはコンパイラーには依存せずプロジェクトのターゲットフレームワークバージョンの設定に依存します。

    まずMajorSubsystemVersionはWindowsがプログラム起動時にサポートしているバージョンかどうかのチェックに使われる値です。そして.NET Framework 4.5以降はWindows XPをサポート外としています。そのため、ターゲットフレームワークバージョンが4.5以上を指定された場合に、Windows XPで動作しないようにするためにMajorSubsystemVersionの値が6に変更されます。

    先のkenjinoteさんの表にVB2012 => 6 と記されていますが、これは単にkenjinoteさんが確認を行う際に作成したプロジェクトのターゲットフレームワークバージョンが4.5以降を設定していたことを示しているだけに過ぎず、4.0以下に設定し直せばこの値が 4 に変化します。

    結局、現時点で判明しているのは

    • VB2010でプロジェクトのコンバートが行われた
    • VB2010 / VB2012 / VB2013いずれかを使用した
    • VB2012 / VB2013でプロジェクトの設定変更は行っていない
    • VB2012の可能性は低い(VB2012のMicrosoft.VisualBasic.PowerPacks.Vs.dllが使われていない)
    • .NET 4以降でビルドされた

    くらいです。

    • 回答としてマーク DSC0803 2017年11月8日 9:33
    2017年11月8日 8:19
  • >佐祐理 さん

    現時点で判明している内容をもとに、

    該当のソースをVB2010+.NET4.0の環境でビルドしてみました。

    簡単に疎通確認してみたところ問題なく動作しているようなので、

    もう少し検証してみようと思います。

    ありがとうございました。

    2017年11月8日 9:33