Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2013年04月09日] [更新 2017年11月20日] Delphi 一般・その他
   
.NET Framework のバージョンと Delphi
動作確認等 .NET Framework 1.1 は Windows 98 以降が対象
[整理番号 - 0450]







01_.NET Framework のバージョンと Delphi


最近のプログラミング言語の開発環境は,.NET Framework の機能を使用しています.Delphi (の IDE) も例外ではありません.

新しいバージョンの開発言語は,より新しいバージョンの .NET Framework を必要とします.逆に古いバージョンの開発現場は,より古いバージョンの .NET Framework を必要とします.
したがって,システムにインストールされている .NET Framework のバージョンによっては,インストールできない開発言語のバージョンが存在することになりますが,Delphi の場合,.NET Framework のインストールを促すダイアログが表示され,同時にインストールできるようになっています.


[備考]
Delphi にはかって,Delphi 8 という .NET Framework 専用のバージョンがありました.
「Borland Developer Studio 2005, 2006」では「Delphi 2005 (2006) for .NET」という開発環境が提供されていました.また「CodeGear RAD Studio 2007」には「Delphi 2007 for .NET」という .NET 用の開発環境も提供されていました.Delphi 2009 からは,これらは提供されていません.

.NET の開発環境として Delphi 2010 で利用可能な Delphi Prism (その後 Embarcadero Prism となる) が提供されましたが,これも Delphi XE3 で終了となっています.





02_.NET Framework のダウンロードリンク


以下は,.NET Framework の各バージョンのダウンロードのリンクです.
これ以外にも,Windows のバージョン別に更新プログラムがあります.リンク先の Download Center で確認してください.

コンピュータにインストールされている古いバージョンの .NET Framework をアンインストールしてしまうと,古いバージョンの .NET Framework で作成したアプリが動作しないことがあります.
また,.NET Framework のアプリが動作しない場合,該当バージョンの .NET Framework が必要になることがあるかも知れません.そのような時の参考用です.

開発用として使用する場合は,SDK も必要です.SDK は,Service Pack や日本語 Language Pack をインストールした後にインストールした方が確実です.
.NET Framework 3.0 以降には,SDK の名前が付いたダウンロードファイルは存在しません.代わりに開発用の Windows SDK 関係のインストールが必要ですが,Delphi に限って言えば,Delphi のインストール時に,Windows SDK のサブセットがインストールされます (.NET Framework を必要としない古いバージョンの Delphi を除く).

.NET Framework 3.0 Service Pack 1 をインストールするには,3.0 が必要ですが,ダウンロードのページを見つけることができませんでした.このバージョンは Windows Vista には標準でインストールされています.
また,3.5 をインストールすると,2.0, 3.0 も同時にインストールされるようになっています.


.NET Framework 4.5 は,Windows XP にはインストールできません.したがって,このバージョンで開発したアプリは,Windows XP では動作しません.また,.NET Framework 4.5 を使用する開発言語のバージョンは,Windows XP にはインストールできないことになります.
なお,.NET Framework 4.x は他の 4.x とは共存できません.

.NET Framework 1.1 は,Windows 7 以降ではサポート外となっていますが,.NET Framework 3.5 SP1 をインストールすれば Windows 7 にインストールできるようです.[Microsoft コミュニティ] でマイクロソフトの方がレスしていました.


[備考]
Microsoft コミュニティでの書き込みは,マイクロソフトの公式の発言ではありません.




03_インストールされている .NET Framework のバージョン


システムにインストールされている .NET Framework のバージョンを調べるのは少し面倒です.
[コントロールパネル] [プログラムと機能] に表示される .NET Framework は後から手動でインストールしたバージョンだけです.Windows に最初からインストールされているか,Windows の Update 等でインストールされた .NET Framework のバージョンは表示されません.

自アプリからインストール済みの .NET Framework のバージョンを知る必要がある場合は,マイクロソフトの記事にあるようにレジストリから読み取らなければならないようです.PowerShell 用のスクリプトを掲載しているサイトがあります.Delphi から PowerShell を操作して,それらのスクリプトを利用する方法も考えられます.



実際にインストールされている .NET Framework のバージョンをレジストリから取得してみました.
参考リンクのマイクロソフトの説明に従ってコーティングしています.

以前手動で Version 4.5 をインストールしました.これは今でも [コントロールパネル] [プログラムと機能] に表示されますが,下図の結果には表示されていません.2017年09月の Windows Update で 4.7 がインストールされました.そのためと思われます.4.x では複数のバージョンは共存できません. 1 つのバージョンだけか有効となります.



[備考]
本サンプルの実行結果では,Version 4 と 4.7 が表示されていますが,レジストリの 4 には Full という項目があるので,4.5 以上がインストールされていることが確認できます.つまり,有効なバージョンは 4.7 となります.後述の .NET Version Detector というツールでは,この使用できない状態が示されています. dotNekoChecker というツールでは,4 はリストに表示されません.


図1
実行結果

リスト1
インストールされている .NET Framework のバージョンをリスト
動作確認環境は Windows 7 U64(SP1) + Delphi XE(UP1) Pro
implementation

uses
  Registry,
  StrUtils,
  Generics.Collections,
  Generics.Defaults;

{$R *.dfm}

//---------------------------------------------------
//  取得したバージョン関係の値を格納するレコード型
//---------------------------------------------------
Type
  TVersionInfo = record
    Version : string;
    SP      : string;
    Full    : Integer;
  end;
  PVersionInfo = ^ TVersionInfo;

//=============================================================================
//  インストールされている.NET Frameworkのバージョンをリスト
//  Version 1 は未対応(このコードでは検出できない)
//
//  usesにRegistry,StrUtils,Generics.Collections,Generics.Defaultsが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LRegistry    : TRegistry;
  LRegKey      : string;
  LBaseKeyList : TStringList;
  LRegItemSub  : string;
  LvStr        : string;
  LVersionList : TList<TVersionInfo>;
  LVerRec      : TVersionInfo;
  LVerStr      : string;
  LIsFull      : Boolean;
  LVerStrTemp  : string;
  LRecLoopCnt  : Integer;
  LRecNo       : Integer;
  i            : Integer;
begin
  LRegistry        := TRegistry.Create;
  LRegistry.Access := KEY_READ;

  LRegistry.RootKey := HKEY_LOCAL_MACHINE;
  LRegKey := 'SOFTWARE\Microsoft\NET Framework Setup\NDP';

  LVersionList := TList<TVersionInfo>.Create;
  LBaseKeyList := TStringList.Create;
  try
    //上で指定したキー項目の一覧を取得
    if LRegistry.OpenKey(LRegKey, False) then begin
      LRegistry.GetKeyNames(LBaseKeyList);
    end;
    LRegistry.CloseKey;

    for i := 0 to LBaseKeyList.Count - 1 do begin
      try
        if LRegistry.OpenKey(LRegKey + PathDelim + LBaseKeyList[i], False) then begin
          LvStr := LBaseKeyList[i];

          //バージョンによって格納形式が異なる
          if LeftStr(LvStr, 1) <> 'v' then Continue;

          if StrUtils.LeftStr(LvStr, 4) = 'v1.1' then begin
            LRegistry.CloseKey;
            LVerRec.Version := LvStr;

            LRegItemSub := LRegKey + PathDelim + LvStr;
            if LRegistry.OpenKey(LRegItemSub, False) then begin
              if LRegistry.ValueExists('SP') then begin
                LVerRec.SP := IntToStr(LRegistry.ReadInteger('SP'));
              end else begin
                LVerRec.SP := '-';
              end;
            end;
          end else
          if LvStr < 'v4' then begin
            LRegistry.CloseKey;
            LRegItemSub := LRegKey + PathDelim + LvStr;

            if LRegistry.OpenKey(LRegItemSub, False) then begin
              LVerRec.Version := LRegistry.ReadString('Version');

              if LRegistry.ValueExists('SP') then begin
                LVerRec.SP := IntToStr(LRegistry.ReadInteger('SP'));
              end else begin
                LVerRec.SP := '-';
              end;
            end;
            LVerRec.Full := 0;
          //(v4.0とv4 (v4の方が新しい)
          //レジストリの構成仕様が変わらなければv5以降も検出可能
          //処理コードは[v4.0][v4]とも同じ
          end else begin
            if LRegistry.KeyExists('Full') then begin
              LRegItemSub := LRegKey + PathDelim + LvStr + PathDelim + 'Full';
              LVerRec.Full := 1;
            end else
            if LRegistry.KeyExists('Client') then begin
              LRegItemSub := LRegKey + PathDelim + LvStr + PathDelim + 'Client';
              LVerRec.Full := 0;
            end;

            LRegistry.CloseKey;
            if LRegistry.OpenKey(LRegItemSub, False) then begin
              LVerRec.Version := LRegistry.ReadString('Version');

              if LRegistry.ValueExists('SP') then begin
                LVerRec.SP := IntToStr(LRegistry.ReadInteger('SP'));
              end else begin
                LVerRec.SP := '-';
              end;
            end;
          end;
        end;
      finally
        LRegistry.CloseKey;
      end;

      //リストにバージョンのレコードをセット
      if Trim(LVerRec.Version) <> '' then begin
        LVersionList.Add(LVerRec);
      end;
    end;

    //-------------------------------------------------------------------------
    //  リストのソート
    //  TComparer関係の使用にはusesにGenerics.Defaultsが必要
    //-------------------------------------------------------------------------
    LVersionList.Sort(TComparer<TVersionInfo>.Construct(
      function(const Left, Right: TVersionInfo): Integer
      begin
        //versionの値(文字列)でソート
        Result := SysUtils.CompareText(Left.Version, Right.Version);
      end)
    );
    //-------------------------------------------------------------------------


    //4.5以降は同じCLRの複数のバージョンは共存できないようなのでその検出
    //5以降にも対応(5以降も同じ仕様になるのかは不明だが)
    LRecLoopCnt := LVersionList.Count - 1;
    while True do begin
      if LRecLoopCnt = 0 then Break;

      LVerStr := LVersionList[LRecLoopCnt].version;
      LIsFull := LVersionList[LRecLoopCnt].Full = 1;
      if (LVerStr >= '4.5') and LIsFull then begin
        for LRecNo := LRecLoopCnt - 1 downto 0 do begin
          LVerStrTemp := LVersionList[LRecNo].Version;
          if (LVerStrTemp >= (LVerStr[1] + '.0'))
              and (LVerStrTemp < LVerStr) then begin

            LVerRec.Version := LVersionList[LRecNo].Version
                             + ' (UpgradeTo ' + LVerStr + ')';
            LVerRec.SP           := LVersionList[LRecNo].SP;
            LVerRec.Full         := LVersionList[LRecNo].Full;
            LVersionList[LRecNo] := LVerRec;

            Dec(LRecLoopCnt);
          end;
        end;
      end;
      Dec(LRecLoopCnt);
    end;

    //結果の表示
    Memo1.Lines.Clear;
    Memo1.Lines.BeginUpdate;
    for LVerRec in LVersionList do begin
      Memo1.Lines.Add('Version : ' + LVerRec.Version);
      Memo1.Lines.Add('SP : ' + LVerRec.SP);
    end;
    Memo1.Lines.EndUpdate;
  finally
    FreeAndNil(LRegistry);
    FreeAndNil(LBaseKeyList);
    FreeAndNil(LVersionList);
  end;
end;


細かいバージョン表示が不要であれば,以下のようにしてもいいかも知れません.ただし,v9 を超えるバージョンになったら工夫が必要です.


図2
実行結果

    for LVerRec in LVersionList do begin
      LvStr := 'Version ' + LeftStr(LVerRec.Version, 3) + ' SP ' + LVerRec.SP;
      Memo1.Lines.Add(LvStr);
    end;




04_インストールされている .NET Framework を確認するツール


インストールされている  .NET Framework バージョンを確認するだけであれば,下図のようなツールが利用できます.いずれもインストールしないで,EXE を起動するだけで利用できます.


図3
.NET Version Detector
  • .NET Framework のダウンロードも可能
  • .NET Framework SDK のダウンロードも可能
  • Delphi 製
図4
dotNekoChecker
  • [検出実行] ボタンをクリックすると調査開始
  • リモート PC も調査可能

下図は Evrnet .NET Check というツールです.リストされているバージョン全てが有効ではないので,おそらくインストールしたバージョンの履歴に近いリストなのかも知れません.
このツールには [locale] というフォルダに ja.ini という日本語を定義したテキストファイルが添付されていますが,下の図はそれを使用しないで実行しています.


図5
Evrnet .NET Check
  • .NET Framework のダウンロードも可能