Delphi Programming / Object Pascal
サイトのトップページへ リンクのページへ ロゴマーク
[掲載 2008年10月08日] [更新 2017年03月25日] Delphi 一般・その他
   
Windows Vista 以降の OS で Delphi
動作確認等 Windows Vista, Windows 7, Windows 8/8.1, Windows 10 を対象とした記事
説明用の図は主に Windows 7 のもの
[整理番号 - 330]



  • 2011年10月16日
  • [Delphi Library 利用上の注意等] から記事をこちらに移動
  • UAC 関係を中心にした記事へ大幅に修正
  • 2012年05月18日
  • [他のアプリケーションの場合] の項目等に,msi 形式のインストーラの説明を追加
  • 2012年05月20日
  • アプリのインストールと実行の際,UAC を無効にする必要がないことを再確認 (ネット上で,UAC を無効にしないとインストールと実行に不具合があるという話題があったので)
  • 記事の構成を若干変更・修正
  • 2015年08月12日
  • Windows 8.1 用の WinHlp32.exe の記事を更新
  • 2015年09月25日
  • Delphi XE7 以降で BDE を使用する方法を別項目にした
  • 2015年10月08日
  • システム関係フォルダや特殊フォルダの操作の注意を別項目にした
  • 自アプリが管理者権限で実行しているか確認する方法を別項目にして,Delphi 2009 以前でも動作するコードに変更




Windows Vista 以降の OS での使用


Windows Vista 以降,OS の仕様にいろいろな変更がありました.コンポーネントやサンプルコードが動作しなかったり,動作しても正しい結果が得られないことがあります.
プログラマー側から見た大きな変更として,プログラムの実行権限に関する「UAC (ユーザアカウント制御)」と「レジストリとファイルの仮想化」機能があります.UAC が有効の時は,ユーザーインターフェイス特権の分離 (UIPI) により,メッセージ関係の処理にも注意が必要です.



ユーザーインターフェイス特権の分離 (UIPI) については,下記の記事も参考にしてください.フックやドラッグ・アンド・ドロップは UIPI の影響を受けるメッセージ処理の 1 つです.


[備考]
当サイトの記事は全て,UAC を有効にした状態での操作に関する内容となっています.以前は,本ページ以外にも,UAC が無効の場合についての文章を随所に記述していましたが,現在は全て削除しています.
UAC を無効にすると,管理者権限ではできない操作が可能になる一方で,UAC が無効の状態だと操作できない機能もあります.UAC を無効にすることと,管理者権限の付与とは,必ずしも同じというわけではありません.




管理者でログインしても,管理者権限で実行とは限らない


Windows XP までは,管理者でログインすれば,そのまま管理者権限の操作ができました.
Windows Vista 以降では,たとえ管理者でログインしても標準ユーザ (一般ユーザー) 以下の権限しかありません.管理者でログインとは,必要な時に管理者に昇格可能という意味となっています.

管理者に昇格するには,メニューから [管理者として実行] を選択します.



図1
[管理者として実行]
  • 管理者権限での実行となる




インストールも実行も管理者権限が必要


レジストリの操作やシステムフォルダの操作には管理者権限を必要とします.
Delphi だけでなく,多くのアプリケーションのインストールにはレジストリやシステムフォルダの操作を伴います.したがって管理者権限が必要です.
もちろん管理者権限を必要としないものもあります.それはアプリケーションによります.

Windows Vista 以降の UAC に対応していないアプリケーション類は,下図のように [管理者として実行] で実行しないと,管理者権限で実行してくれません.管理者権限で実行しないと,Windows Vista 以降に採用された「レジストリとファイルの仮想化」機能によって,必要なファイルが別の場所に格納されてしまい,それらのファイルを認識できないことが原因のトラブルが発生することになります.

Delphi 2007 以降のインストーラは [管理者として実行] で実行する設定になっています.もちろんこの方法で実行してもかまいません.
自作のアプリケーションで,起動時に [ユーザーアカウント制御] ダイアログを自動的に表示するようにできます.それには,アプリケーションマニフェストを EXE に組み込みます.


[備考 1]
インストールに管理者権限が必要なアプリケーションは,管理者権限でインストールします.
実行時に管理者権限が必要なアプリケーションは,管理者権限で実行します.
インストールや実行時に管理者権限が必要であるかどうかは,そのアプリケーションによります.
Delphi は,インストールも実行時にも管理者権限が必要なアプリケーションです.
管理者権限で実行するには,[管理者として実行] で実行します.

[備考 2]
Windows Vista 以降では,プログラムがインストーラの時は UAC の影響を受けます.
実行ファイル名に SETUP, INSTALL, UPDATE 等の文字列が含まれている場合,それらはインストーラとみなされます.



図2
管理者権限でインストール開始
  • DVD の自動再生で開始された場合は,一度閉じる
  • Delphi の DVD の Install.exe を実行
  • これは Delphi 7 Pro の DVD のファイル
図3
ユーザーアカウント制御
  • Windows 7 で [管理者として実行] で実行した場合
図4
ユーザーアカウント制御
  • Vista で [管理者として実行] で実行した場合
  • 当然 [許可] を選択

上の図は [管理者として実行] で実行した場合のダイアログですが,標準ユーザのまま起動すると次のようなダイアログとなります.

例えば,当サイトのプログラム類をダウンロードして,アプリケーションである EXE を起動するとセキュリティの警告,「発行元が確認できませんでした」のダイアログが現れるこがあります.これを回避するためには,提供者である筆者がデジタル署名を取得する必要があります.
自分の環境でコンパイルし直せば,現れなくなります.


図5
セキュリティの警告
  • デジタル署名を取得していないアプリを管理者に昇格しないで起動した場合
図6
ユーザアカウント制御
  • デジタル署名を取得して,管理者権限で実行するように作成したアプリの場合
  • UAC に対応したアプリはこのダイアログが表示される
  • 自作アプリでこのダイアログを表示するには [コードサイニング証明書] の取得が必要

Windows Vista 以降に対応していないアプリケーションの場合は,下図のような [プログラム互換性アシスタント] ダイアログが表示される場合があります.
このダイアログが現れるアプリケーションは,このまま実行して,正常に動作しない場合でも,[互換モード] であれば動作可能なようです.このダイアログは非表示にもできます.

  • 図7 
  • 続行するには [プログラムを実行する] をクリックする
  • [オンラインで解決策の有無を確認する] にしても解決できない




ショートカットを作成して管理者権限で起動


管理者権限が必要なアプリケーションは,「管理者として実行」で実行します.そうしないと,たとえエラーが発生しなくても正常に動作するとは限りません.そのため,デスクトップ等にショートカットを作成して常に [管理者として実行] 可能なようにしておくと便利です.
この設定をして Delphi を起動すると [ユーザーアカウント制御] のダイアログが現れます.



[備考]
次項の説明のように,Delphi の大元の EXE を管理者権限で実行するように設定すれば,ショートカットのプロパティの設定は不要です.



図7
起動用ショートカットの作成
  • [コピー] して,デスクトップ等に [ショートカットの貼り付け]
  • ここでは,Delphi 7 起動用のショートカットを作成
図8
起動ショートカットの設定
  • ショートカットのプロパティを開く
  • [ショートカット] タブの [詳細設定]
  • [管理者として実行] にチェック




プロジェクトの開き方


Delphi のプロジェクト (拡張子 .dpr) を開く際,拡張子の関連付けをしていても,ダブルクリックで開いてしまうと,[管理者として実行] での実行にならない場合があります.
[管理者として実行] で Delphi を起動して,IDE のメニューからプロジェクトを開くか,上記の説明で作成した Delphi のショートカットに,ドラッグ・アンド・ドロップして開くようにします.

下図のように,Delphi の EXE そのものを管理者権限で起動するように設定しておくと,プロジェクトをダブルクリックで開く際,自動的に管理者への昇格ダイアログ ([ユーザアカウント制御] ダイアログ) を表示することができます.
また,[スタート] メニューから Delphi を起動する際も,[管理者として実行] の操作をする必要がなくなります.



図9
IDE の EXE のプロパティ変更
  • Delphi インストール先の [bin] フォルダ内の bds.exe のプロパティダイアログを表示
  • [互換性] のタブで [管理者としてこのプログラムを実行する] をチェックする
  • この図は Delphi XE の場合

上図の設定をして Delphi のショートカットを作成すると, 下図のように,管理者権限で実行するという意味の「盾」付きのアイコンになります.



図10
ショートカットを作成すると自動的に盾アイコンが付く

上記の設定内容は,レジストリの以下の場所に記録されます.レジストリの,この値を編集することによっても,管理者権限での起動の設定ができます.
このレジストの場所は,Windows XP 等の互換モードを設定した場合に,その設定が記録される場所と同じです.



HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers


図11

[備考 1]
後述の [互換モード] の設定をしている場合は,ダブルクリックすると,自動的に [ユーザアカウント制御] ダイアログが表示され,管理者への昇格を問い合わせてきます.

[備考 2]
違うバージョンの Delphi で作成したプロジェクトを開く時にエラーが発生することがあります.これはまた別の問題です.




IDE 上での実行と EXE 単独起動の違い


Delphi を [管理者として実行] で起動し,IDE 上でコンパイルして実行する場合は,既に管理者として実行しています.作成した EXE を直接実行した時と動作が異なることもあることに注意します.

作成した EXE に管理者権限が必要な動作が含まれている場合,その EXE は管理者権限で実行しなければなりません.実行時にたとえエラーが発生しなくても,正常に動作するとは限りません.

実行時に管理者権限が必要かどうかは,そのプログラムの作成,開発者,つまりプログラマーが把握しなければなりません.
アプリケーション全体ではなく,あるボタンクリックで管理者権限で実行する場合,そのボタンに,管理者権限で実行するという意味の「盾アイコン (シールドアイコン)」を表示できます.
ElevationRequired プロパティを True にします.このプロパティは Delphi 2009 以降にあります.




図12
「盾」アイコン表示用のプロパティ

盾 (シールド) アイコンが別途必要であれば,システムのリソースから取得できます.
下のコードは,その取得コードの例です.




図13
シールド (盾) アイコン

uses
  ShellAPI;

{$R *.dfm}

//-----------------------------------------------------------------------------
//  システム関係のアイコンを取得する関数
//  usesにShellAPIが必要
//-----------------------------------------------------------------------------
function GetStockIcon(Id: Integer; ASize: Cardinal; AIcon: TIcon): HRESULT;
var
  LSHIconInfo : TSHStockIconInfo;
  LuFlags     : Cardinal;
  LResCode    : HResult;
begin
  Result := 0;
  LSHIconInfo.cbSize := SizeOf(LSHIconInfo);

  LuFlags  := SHGSI_ICON or ASize;
  LResCode := SHGetStockIconInfo(id, LuFlags, LSHIconInfo);

  Result := LResCode;
  if Result = S_OK then AIcon.Handle := LSHIconInfo.hIcon;
end;

//=============================================================================
//  システムの盾(シールド)アイコン画像を取得する
//  必要であればビットマップ画像等に変換して使用する
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LIcon : TIcon;
begin
  LIcon := TIcon.Create;
  try
    //大きいアイコン
    if GetStockIcon(SIID_SHIELD, SHGSI_LARGEICON, LIcon) = S_OK then begin
      Image1.Canvas.Draw(0, 0, LIcon);
    end;
    //小さいアイコン
    if GetStockIcon(SIID_SHIELD, SHGSI_SMALLICON, LIcon) = S_OK then begin
      Image1.Canvas.Draw(50, 0, LIcon);
    end;
  finally
    FreeAndNil(LIcon);
  end;
end;




自アプリが管理者権限で実行しているか確認する方法


実行中のプログラムが管理者権限で実行されているかは,IsUserAnAdmin 関数を使用して確認できます.この関数は,Windows Vista までのサポートとなっていますが,Windows 7, 8.1, 10 でも使用可能であることを確認しています.
CheckTokenMembership という関数もあります.こちらは特にサポート上限のについての記述はないようです.CheckTokenMembership 関数は,Delphi XE6 までに定義はありませんが,JEDI API には実装されています.




管理者権限で実行しているかの確認用コードの例
IDE が管理者権限で起動していかるかの確認には利用できない
uses
  Registry;

{$R *.dfm}

  //IsUserAnAdminはDelphi2010以降には実装されている
  //Delphi2010以降では,usesにShlObjを追加すれば,この定義文は不要
  function IsUserAnAdmin: Boolean; stdcall; external 'Shell32.dll';

//=============================================================================
//  以下の状態を調べるコード
//  (1) UACが有効か無効かを調査
//  (2) 管理者権限での実行か非管理者権限での実行かを調査
//
//  TRegistryの使用にはusesにRegistryが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
  LRegistry : TRegistry;
  LRegKey   : String;
  LRegItem  : Integer;
begin
  if DebugHook <> 0 then begin
    MessageBox(Handle, 'デバッグ中は調査しません', '情報', MB_ICONINFORMATION);
    exit;
  end;


  LRegistry := TRegistry.Create;
  try
    LRegistry.Access  := KEY_READ;
    LRegistry.RootKey := HKEY_LOCAL_MACHINE;
    LRegKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System';

    if not LRegistry.OpenKey(LRegKey, False) then begin
      MessageBox(Handle, 'UAC が無効の状態です', '情報', MB_ICONINFORMATION);
    end else begin
      LRegItem := LRegistry.ReadInteger('EnableLUA');

      if LRegItem = 0 then begin
        MessageBox(Handle, 'UAC が無効の状態です', '情報', MB_ICONINFORMATION);
      end else begin
        if IsUserAnAdmin then begin
          //管理者権限で実行中
          MessageBox(Handle, '管理者権限で実行中', '情報', MB_ICONINFORMATION);
        end else begin
          //管理者権限以外で実行中
          MessageBox(Handle, '標準ユーザで実行中', '情報', MB_ICONINFORMATION);
        end;
      end;
    end;
    LRegistry.CloseKey;
  finally
    FreeAndNil(LRegistry);
  end;
end;




コマンドラインを管理者権限で実行


コマンドラインも,管理者権限が必要な操作は管理者としての実行が必要です.
例えば,regsvr32.exe で DLL や OCX (ActiveX コントロール) を登録する時等です.
regsvr32.exe はレジストリの操作ですから,当然,管理者権限での実行が必要です.

アプリケーションでコマンドラインの操作が必要な場合は,サンプルプログラム集に以下の様な参考コードと記事があります.



[備考 1]
DLL や OCX (ActiveX コントロール) には 32 ビット版と 64 ビット版があります.
32 ビット版の DLL 等は 64 ビットのアプリケーションでは使用できません.64 ビット版の DLL 等は 32 ビットのアプリケーションでは利用できません.32 ビット版の DLL 等の登録は,基本的には 32 ビット版のコマンドプロンプトを管理者権限で起動して行うことになります.


[備考 2]
エクスプローラからフォルダやファイル名をドラッグ・アンド・ドロップすれば,コマンドプロンプトにそのフォルダ名等を貼り付けることができます.この時,パス名に空白文字ある場合,自動的に " (ダブルクォーテーション) が付加されます.
この機能は,コマンドプロンプトを管理者権限で起動している時は無効となります.



下図の [スタート] メニューから起動するのは,Windows が 64 ビット版の場合,64 ビット版のコマンドプロンプトです.



図14
コマンドプロンプトの起動
  • Windows 7 の場合
  • [管理者として実行] で実行
  • 64 ビットの Windows 7 では 64 ビット版のコマンドプロンプトが起動する
図15
コマンドプロンプトの起動
  • Windows 8.1 の場合
  • 画面左下のウィンドウのロゴのポップアップメニューから起動可能

実際の Windows 7 のコマンドプロンプトの起動画面です.管理者権限で起動すると,キャプション (タイトル) に「管理者」という文字が表示されます.



図16
標準ユーザのコマンドプロンプト
  • キャプションが [コマンド プロンプト]
  • 管理者でログインしても [管理者として実行] で実行しなければ,これになる
図17
管理者のコマンドプロンプト
  • [管理者として実行] で実行した場合は,キャプションが[管理者: コマンド プロンプト]

下図のように,[スタート] メニューの [プログラムとファイルの検索] 窓に cmd とタイプした検索結果から選択して,[Ctrl] + [Shift] + [Enter] でも管理者権限で起動できます.

Windows 10 では,[Cortana に何か聞いてみてください] の入力欄に cmd とタイプします.
[Cortana に何か聞いてみてください] への入力を可能にするには [スタート] ボタンで,スタートメニューが表示された状態にします.[スタート] ボタンはトグル動作になっています.



図18
コマンドプロンプトを管理者権限で起動する別の方法
  • 選択中の項目を
    [Ctrl] + [Shift] + [Enter]
    で起動する
  • 項目の選択は矢印キーで操作
  • [cmd.exe - 32bit] は筆者が作成したショートカット

Windows 8.1, Windows 10 では下図のように,エクスプローラのメニューからコマンドプロンプトを管理者権限で起動できます.
エクスプローラでドライブ C (システムドライブ) を選択した状態で [ファイル] をクリックします.



図19
エクスプローラのメニューからコマンドプロンプトを起動
  • Windows 8.1 の場合
図20
エクスプローラのメニューからコマンドプロンプトを起動
  • Windows 10 の場合

下図は,サンプルプログラム集の [552] を [管理者として実行] して,コマンドラインのコマンドを実行する例です.
[552] のサンプルは,32 ビットのアプリとして作成すれば,32 ビット版のコマンドを実行できます.64 ビットのアプリとして作成すれば,64 ビット版のコマンドを実行できます.



図21
コマンドラインの実行例
  • サンプルプログラム集の [552] を [管理者として実行],コマンドラインを設定
  • [管理者として実行] で実行しなくても成功することもあるが,正常に登録されるとは限らないので注意
  • 例は,regsvr32 "D:\000\XlsCrt2.DLL"

コマンドプロンプトにも,下図のように,コピーや貼り付けの機能があります.
編集のメニューは,ウィンドウの左上のシステムメニューの [編集] から,または,コマンドプロンプトの任意の位置のマウスの右ボタンクリックで表示できます.



図22
コピーや貼り付けの機能
  • Windows 10 では [Ctrl] + [C] で貼り付けが可能
図23
ポップアップメニュー

以下の記事に,コマンドプロンプトに貼り付け操作を行うサンプルがあります.





旧タイプ ( 拡張子 .HLP ) のヘルプを利用可能にする - Windows 8 以前


Delphi 7 までの,拡張子が .HLP のヘルプは,Windows Vista 以降では表示できません.表示するには,Windowws のバージョンに応じて,以下のプログラムを実行します.
すぐにはダウンロードできませんでした.筆者の環境では,ダウンロードの前に [Genuine Windows Validation (正規 Windows 検証)] の実行メニューが表示されました.

Windows 8.1 用は,次項の記事を参考にしてください.




図24
更新プログラムのダウンロード
  • 今回は 64bit 版の Windows なので赤枠のものをダウンロード
  • 32bit 版の Windows の場合は x86 をダウンロードする
図25
ヘルプを表示

もし自分自身がヘルプファイルの提供者である場合,CHM 形式のヘルプに変更することも考えてもいいかも知れません.
ウェブページ用に作成した HTML ファイルを CHM ファイルに変換するソフトがあります.下記のリンクの「ヘルプましん」もその一つで,筆者が一時期,当サイトの記事を CHM ファイルとして提供していた時に利用していたソフトです.「ヘルプましん」は Delphi で開発されています.






旧タイプ ( 拡張子 .HLP ) のヘルプを利用可能にする - Windows 8.1


Windows 8.1 の場合は,以下の [XXX 用更新プログラム (KB917607)] をダウンロードしてインストールします.最初のリンクが 32 ビット版の Windows 8.1 用,次のリンクが 64 ビット版の Windows 8.1 用となっています.
マイクロソフトでは,同じ名前のファイルを別に提供していますが,2015年08月12日現在,下記のリンクのファイルが最新のものです.古いファイルはリンク先が違います.古いファイルの場合,更新プログラム KB3000850 がインストールされていると動作しない場合があります.





旧タイプ ( 拡張子 .HLP ) のヘルプを利用可能にする - Windows 10


2015年10月08日現在,マイクロソフトからは,関係するプログラムの提供はないようです.

以下のリンクから WinHlpXP.zip をダウンロードします.この ZIP ファイルにある WinHlpXP.exe を使用すると,Windows 10 で .HLPファイルが表示できることを確認しています.詳しくはリンクの記事で確認してください (2017年03月25日追記).



以下は, Windows XP 環境を持っている方が対象の方法です.
Windows XP の WinHlp32.exe を Windows 10 で使用可能にする方法を教えて頂きました.Windows XP の WinHlp32.exe は,デフォルトでは [Windows] ディレクトリ内にあります.

  • (1) 作業用のフォルダーを,例えば D:\TEMPZ6 という名前で作成する
  • (2) この D:\TEMPZ6 に,Windows XP の WinHlp32.exe をコピーする
  • (3) テキストエディタで,下のコードのバッチファイル Win10-Hlp32-Fix.cmd を作成する
  • (4) 作成したバッチファイル Win10-Hlp32-Fix.cmd を作業用フォルダ D:\TEMPZ6 内に置く
  • (5) コマンドプロンプトを管理者権限で起動する
  • (6) ディレクトリを作業用フォルダ D:\TEMPZ6 に移動する
  • (7) Win10-Hlp32-Fix.cmd を実行する
作業用のフォルダ名とバッチファイルの名前は任意です.


上記の手順で説明したバッチファイル Win10-Hlp32-Fix.cmd のコード
@echo off
set currdir=%CD%
takeown /f "%windir%\winhlp32.exe" >nul
icacls "%windir%\winhlp32.exe" /grant *S-1-5-32-544:F >nul
copy /y "%currdir%\winhlp32.exe" %windir%
icacls "%windir%\winhlp32.exe" /setowner "NT Service\TrustedInstaller" >nul
echo.
echo Done.
echo.
echo Press any key to Exit
pause >nul
exit



[備考 1]
マイクロソフトが Windows Vista, 7, 8, 8.1 用に提供している「Windows Help プログラム」でインストールした WinHlp32.exe を使用しても,.HLP ファイルは表示できません.


[備考 2]
本項の記事掲載時の 2015年10月08日では,Windows 7 で動作確認していました.
2015年11月24日に 32 ビット版と 64 ビット版の Windows 10 で動作確認しています.

上のコードは,WinHlp32.exe をシステムフォルダにコピーしているだけです.システム関係フォルダ内のファイルの操作には所有権の設定,変更が必要なので,その処理を行っています.つまり,上のコードは Windows のバージョンには関係ないコードとなっています.


[備考 3]
システム関係フォルダ内のファイル類は,多くの場合,所有者を Administrarors に変更すれば操作が可能になります.上のリンクの [ファイルの所有者を... ] の記事を参考にしてください.単にファイルのコピーや貼り付け操作をしたり,所有権を正しく設定しないと,次回の Windows 起動時に自動修復機能が働く可能性があります.


[備考 4]
WinHlp32.exe は,再配布可能なファイルではありません.
アプリケーションに組み込んでの配布は可能なようですが,既に WinHlp32.exe が使用可能になっている状態も考慮する必要があります.





アンインストール


Delphi 2007 よりも前の Delphi のように,Vista の UAC 未対応のアプリケーションのアンインストールも [管理者として実行] で実行して,管理者権限で行います.そうしないと正常にアンインストールできない場合があります.
Vista の UAC に対応しているアプリケーションでは,[コントロールパネル] の [プログラムと機能] からアンインストールできます.また,専用のアンインストーラーが用意されている場合もあります.
自作のアプリケーションにアンインストーラーを実装する時は注意が必要です.

Delphi 6, 7 では,Install.exe を [管理者として実行] すれば,アンインストールできます.



[備考]
何かのトラブル回避策として Delphi をアンインストールする際には,レジストリの削除も行う必要があります.そうしないと,関係する情報がレジストリに残ってしまいます.そのため,再インストールしてもトラブルの回避策にならないことがあります.
アンインストールでは,レジストリの情報を削除するかの選択項目がありますが,以下のリンクの記事も参考にしてください.

また,レジストリと Program Files (Program Files (x86)) 以外にも,関連フォルダやファイルも削除することをお勧めします.
トラブルが発生して,再インストールが必要な場合は特にこの作業が重要です.再インストールとは,システムの状態を,そのアプリなりソフトを新規にインストールする時と極力同じにする,と捉えるとよいのではないかと思われます.



図26
アンインストール
  • Vista の UAC 未対応のアプリでは正常にアンインストールできない場合がある




管理者に昇格しないで実行してしまった場合 ( 仮想化の問題 )


Vista 以降の UAC に対応していないアプリケーションでは,管理者に昇格しないでインストールやアンインストールを実行,あるいは,設定の変更操作してしまった場合,改めて [管理者として実行」で実行して,これらの操作を行ったとしても正常に動作しない場合があります.
正常に動作するように見えても,設定変更や他のユーティリティ類導入後の動作に問題が発生することがあります.
これは,Windows Vista 以降の「ファイルとレジストリの仮想化」機能によるものです.このような場合はマイクロソフトの以下のページを参考にして対処する以外にありません. 上のリンク先のページにある [互換性ファイル] は,下図の説明のようにして閲覧することができます.[互換性ファイル]は,仮想化機能によって作成された仮想化フォルダやファイルのことです.具体的には以下の場所となっています.
なお,この「ファイルとレジストリの仮想化」は,64 ビットアプリケーションでは使われません.

C:\Users\アカウント名\AppData\Local\VirtualStore
C:\ユーザ\ユーザ名\AppData\Local\VirtualStore



図27
互換性ファイル 1
  • 全てのファイルの表示が可能な状態にしておく
  • [互換性ファイル] をクリック
  • この図は Windows 7
図28
互換性ファイル 2
  • 右ペインに互換性ファイルだけが表示される
  • この中に仮想化ファイルがある
図29
互換性ファイル 3
  • 上の図で,右ペインのフォルダのどれかをマウスで選択する
  • 実際に存在する場所が,左ペインで選択状態になる
図30
レジストリでの場所
  • [Classes] のツリーは一部省略
  • 正常インストールでない場合,アンインストール後,仮想ファイルとこのレジストリの該当キーも削除する必要がある (存在すれば)




ファイルの仮想化と設定関係ファイル ( バーチャルストア )


前項の説明と重複しますが,Program Files フォルダ階層下のファイルは,管理者権限でないと,変更等の操作はできません.

例えば,プログラムの設定関係ファイル等を,どこからか持ってきてコピーしても,反映されないことがあります.そのようなファイルが存在している場合,アプリケーションから設定した内容を保存する際にアクセス拒否等のエラーが発生しない場合があります.この時,設定した内容は,前項で説明した仮想化ファイルに保存されます.これを「バーチャルストア」と言うことがあります.

前項の図で分かるように,Windows 等のシステム関係のフォルダ内のファイルも,ファイルの仮想化の影響を受けます.






アプリケーションマニフェストの設定で仮想化を無効にできる


アプリケーションが,アプリケーションマニフェストを使用してして,そのマニフェストに要求実行レベル属性 (requestedExecutionLevel 要素の level 属性) が含まれている場合,レジストリの仮想化やファイルの仮想化の機能は,そのアプリケーションでは無効になります.
また,64 ビットのアプリケーションでは,レジストリとファイルの仮想化は行われません.

基本的には,配布するアプリケーションにはアプリケーションマニュフェストを組み込む方が良いと思われます.






互換モード


アプリケーション類のインストールに失敗する場合,[互換モード] を [Windows XP (Service Pack 3)] に設定して実行するとほとんど成功するようです.筆者は動作確認していません.Delphi 6 と 7 のインストール後にこの設定でも動作することは確認しました.この設定をすると,[管理者として実行] から実行しなくても [ユーザアカウント制御] ダイアログが表示されます.
この場合,Windows XP の互換モードで動作させることになりますが,これは [XPモード] で動作することではありません.

この [互換モード] での Delph と,ネイディブな環境で起動する Delphi とでは,動作仕様が異なることがあります.


[備考]
64 ビット版の Windows Vista 以降でも,今までの 32 ビットのアプリケーションは,基本的には動作します.64 ビット版の Windows には,32 ビットのアプリケーションを動作させるための仕組みが実装されています.
筆者は,Windows XP 時代に使用していた 32 ビットのアプリケーションをインストールして使用していますが,現在のところ全て問題なく動作しています.互換モードを利用しているアプリケーションは全くありません.



図31
互換モードの設定
  • 実行ファイルのショートカットを作成して [プロパティ] を表示
  • 念のため [特権レベル] にもチェックを入れておいた方がいいだろう




他のアプリケーションの場合 -  msi インストーラには注意


拡張子が .msi のファイルは実行形式のファイルではありません.
msi 形式のファイルには,[管理者として実行] の項目はありません..msi 形式は,msiexec に関連付けされたファイルです.

管理者権限が必要なアプリケーションのインストーラが msi 形式で提供されている場合,次のようなパッチファイルを作成して,このパッチファイルを [管理者として実行] で実行することでインストールできます.
デジタル署名 (コードサイニング証明書) があるアプリケーション,あるいは管理者権限での実行が必要でないアプリケーションであれば,.msi ファイルを直接実行できます.


msiexec /i msiファイルのフルパス





アプリケーションマニフェストの作成方法


[アプリケーションマニフェスト] をリソースとして EXE に組み込んでおけば,実行時に,管理者への昇格ダイアログ (ユーザアカウント制御ダイアログ) を自動的に表示させることができます.

以下の手順で作成しますが,Delphi 7 以前には [ランタイムテーマ] の設定はありません.Delphi 7 では uses に XPman を追加しておきます.

  • (1) [プロジェクト] [オプション] の [アプリケーション] で [ランタイムテーマ] を有効にする
  • (2) プロジェクトをコンパイルして EXE を作成する
  • (3) その EXE をリソースエディタで開き,[XP Theme maifest] のコードを開く
  • (4) そのコードをコピーして,テキストエディタに貼り付ける
  • (5) level="asInvoker" を level="requireAdministrator" に変更する
  • (6) これを UTF-8 形式で,plXRAY.manifest 等の名前で保存する (plXRAY の部分は任意)

アプリケーションマニフェストに,要求実行レベル属性 (requestedExecutionLevel 要素の level 属性) が含まれている場合,レジストリの仮想化やファイルの仮想化の機能は,そのアプリケーションでは無効になります.



[備考 1]
一般的には,アプリケーションにはアプリケーションマニュフェストを組み込むべきです.
ただし,旧いバージョンの Delphi では,アプリケーションマニフェストを使用する場合と,使用しない場合とでアプリの挙動が異なることがあります.特に描画関係に注意が必要です.

[備考 2]
Delphi 10.1 Berlin 等,より新しいバージョンの Delphi であれば,本項で述べている手順は必要ありません.メニューの [プロジェクト] [オプション] のダイアログで [アプリケーション] で設定できます.
[マニュフェストファイル] を自動生成にすれば,自動的に EXE に組み込まれます.また,[管理者権限の有効化] をチェックすれば,作成した EXE を起動すると自動的に管理者への昇格ダイアログを表示します.どのようなマニュフェストファイルがてきるかは,以下のサンプルを使用すると確認できます.


Vista 以降の UAC に対応するためのアプリケーションマニフェストファイルの例
このコードはコピーして使用可能だが,UTF-8 で保存する必要がある
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity
    type="win32"
    name="DelphiApplication"
    version="1.0.0.0" 
    processorArchitecture="*"/>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <!--Windows 10-->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
      <!--Windows 8.1-->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
      <!--Windows 8-->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
      <!--Windows 7-->
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
      <!--Windows Vista-->
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
    </application>
  </compatibility>
</assembly>


表1
マニフェストの <requestedExecutionLevel/> 要素の値

level="asInvoker" プロセスを作成するユーザと同じトークンを使用してプロセスを起動する
level="highestAvailable" 管理者は,昇格の同意を求められる
ユーザに管理者権限がないと,標準ユーザとして起動される
level="requireAdministrator" 管理者は,昇格への同意を求められる
標準ユーザは「管理者への昇格」のためのログインダイアログが表示される


<requestedExecutionLevel> 要素の uiAccess 属性は False となっています.デジタル署名を取得していないアプリケーションでは Falas にします.デジタル署名を取得したアプリケーションは True にすることにより,UIPI の制限を回避することができます.
デジタル署名のないアプリケーションで True にしても,警告ダイアログが表示されて起動しません.

なお,Windows 7 で新しく追加された compatibility 要素がないマニフェストを使用したアプリケーションは,Windows Vista 互換モードで動作します.詳しくは以下のリンクの記事内の [Windows Vista 互換モードの解除] の項を参考にしてください.




図32
EXEを作成
  • [プロジェクト]
  • [オプション]
  • [アプリケーション]
  • [ランタイムテーマ] を有効にしてコンパイル
図33
マニフェストのコード
  • EXE ファイルをリソースエディタで表示
  • [XP Theme manifest] のコードをコピペして UTF-8 で保存
    拡張子を.manifest とする
  • あるいは [リソースを外部に保存] で保存




アプリケーションマニフェストの使用方法 - Delphi XE 以前


作成したマニフェストファイルは次のようにしてプロジェクトで使用しますが,Delphi 7 以降で uses に XPMan があれば削除しておきます.

  • 下のリスト2のようなリソースファイルを作成して XXX.rc の名前で保存 (XXX の部分は任意)
  • このリソースファイルをプロジェクトに追加
  • [プロジェクト][オプション] の [アプリケーション] で [ランタイムテーマ] を無効にする
  • プロジェクトをコンパイルして EXE を作成する
拙作のコンポーネント類,サンプルプログラム集には,[管理者として実行] であることを前提に作成されているものが多くあります.一部のサンプルでは,アプリケーションマニフェストを使用して,[ユーザアカウント制御] ダイアログを起動時に自動表示するようになっています.

マニフェストファイルの内容を変更したり,リソースファイルの内容を変更した場合は,プロジェクトの再構築が必要となることがあります.


マニフェスト .manifest を EXE に埋め込むためのリソースファイル
ここでは plXRAY.rc の名前で保存
1 24 "plXRAY.manifest"


図34
プロジェクトフォルダ内に保存
図35
プロジェクトに追加
  • plXRAY.rc をプロジェクトに追加
  • プロジェクトをコンパイル
図36
プロジェクトマネージャーでも可能
  • この図では既に plXRAY.rc は追加済み
  • manifest ファイルを変更したら [再構築]




アプリケーションマニフェストの使用方法 - Delphi XE2 以降


Delphi XE2 の場合は,リソースファイルを作成する必要はありません.[ランタイムテーマ] を [カスタムマニフェストを使用する] にして,作成したマニフェストファイルを指定するだけです.

マニフェストファイルの内容を変更したり,リソースファイルの内容を変更した場合は,プロジェクトの再構築が必要となることがあります.


図37
Delphi XE2 の場合




プログラム互換性アシスタントのダイアログ


実行可能なファイルの名前に Install, setup や update 等があるファイルを実行して終了すると,下図のようなダイアログが現れることがあります.このダイアログが現れても,通常は [このプログラムは正しくインストールされました] を選択して閉じて問題はありません.

この [プログラム互換性アシスタント] ダイアログは,[ローカルグループポリシーエディタ] を起動して,[管理用テンプレート] [Windows コンポーネント] [アプリケーションの互換性] の [アプリケーションの互換性エンジンをオフにする] の設定を [有効] にすると,Windows を再起動すれば表示しなくなります.

アプリケーションマニフェストに,<compatibility> 要素を追加して,該当する Windows のバージョンの <supportedOS Id= の記述を追加すれば,このプログラム互換性アシスタントのダイアログは現れません.




図38
[プログラム互換性アシスタント] ダイアログの例
図39
[プログラム互換性アシスタント] のダイアログが現れないようにする




デジタル署名 ( コードサイニング証明書 )


自作のアプリケーションで [セキュリティの警告] ダイアログ等の発行元を不明にしないようにするには,デジタル署名 (コードサイニング証明書 - 例:日本ベリサイン株式会社) を購入します.現在,マイクロソフトでの証明書発行は行っていません.

アクティベーション回避ツールもあるようですが,筆者はお勧めしません.トラブル発生の原因となる可能性があります.
ある回避ツールについて,Micorsoft では,トラブルの回避策があるとしていますが,本来は回避策ツール側で対応すべき問題と思われます.






BDE の設定と制限



[備考 1]
BDE (ビーディーイー,Borland Database Engine) は,各種データベースへの接続を仲介するためのソフトウェアです.
Paradox, dBASE, Oracle, INFORMIX, SYBASE, IBM DB2, MS SQL Server, InterBase Server 等との接続を可能します.このような,データベースとの接続を仲介するソフトウェアはミドルウェアと呼ばれています.BDE は汎用的なミドルウェアということになります.
Delphi XE6 までは,この BDE と,Paradox, dBASE のサンプルデータが付属していて,Delphi をインストールすると自動的にセットされていました.(Paradox, dBASE というデータベースのソフトが付属していたわけではありません)

サードパーティが提供しているデータベースには,多くの場合,そのデータベース専用のミドルウェアが付属しています.BDE を使用する必然性はありません.それらの専用のミドルウェアは,一般的に,そのデータベースの機能を十分に引き出すことが可能です.一方,BDE を使用する場合,機能的な制限があります.



当サイトで提供しているテストプログラムに,BDE 接続で Paradox のデータベースを扱うものがあります.BDE も Paradox も,Borland 社でのサポートが 1997年10月21日で終了しています.新規の業務で採用するようなことはないと思われますが,Delphi に添付されていて,テストに便利なので利用しています.
Vista 以降で BDE を利用するには, C:\ のルートディレクトリにファイルを書き込まないように BDE を設定する必要があります.この設定を行わないと,

ネットワークの初期化に失敗しました.
ファイルまたはディレクトリが存在しません.
ファイル: C:\PDOXUSRS.NET
アクセスは拒否されました.
ディレクトリ: C:\

という内容のダイアログが現れて実行できません.Windows Vista 以降では,たとえ管理者権限を持つユーザーであっても,システムドライブのルート直下のファイルは操作できません.
また BDE はマルチプロセッサ環境では正常動作しない場合があります.詳細については以下を参考にしてください.


BDE は,32 ビットの Windowsアプリケーション用です.64 ビット版の Windows でも,BDE を使用したアプリの開発はできますが,作成できるのは,32 ビットのアプリケーションだけです.
また,4G を超えるファイルは扱えません.

BDE の単独配布は許可されていません.アプリに組み込んでの配布であれば可能です.



図40
C:\ ルートへのアクセス拒否
図41
一般的なルート直下の操作
  • ルート直下のファイル操作は特権が必要

BDEAdmmin.exe を起動し,PARADOX の NET DIR の値をルートディレクトリ以外の場所に変更します.
この時,Program Files (または Program Files (x86)) やシステム関係のディレクトリは指定しないようにします.
当然ですが,管理者用ツールですから,BDEAdmin.exe は管理者権限で起動します.ネット上には,UAC を無効にしないと更新できないという記事もあるようですが,筆者の環境ではそのような現象は確認できていません.


[備考 2]
BDEAdmmin.exe は,Delphi 7 等の旧バージョンの Delphi がインストールされている環境では,[コントロールパネル] を起動して,[大きいアイコン] 表示にするとすぐ見つかります.
また,BDEAdmin.exe, データベースデスクトップ共に,[スタート] メニューから起動できます.メニューの項目は [BDE Administrator], [Database Desktop] です.



  • 図42
  • BDEAdmin のある場所.この BDEAdmin.exe を [管理者として実行] で起動する
  • Windows 7 64bit 版の場合は,"C:\Program Files (x86)" フォルダ内

  • 図44 
  • PARADOX の NET DIR の値を例えば,C:\Users\Public\Documents\RAD Studio に変更

Paradox の [データベース・デスクトップ] (database desktop) も下図の場所にあります.
サンプルプログラム集で使用している Paradox のデータベースファイルも,これを使用して動作を再確認しています.


  • 図43
  • Windows 7 64 ビット版の場合は,"C:\Program Files (x86)" 以下のフォルダ内

  • 図44
  • [データベース・デスクトップ] のテーブルの新規作成画面




BDE の初期化中にエラーが発生


BDE を使用するアプリの実行時に,下図のような初期化のエラーが発生することがあるようです.

Borland Database Engine の初期化中にエラーが発生しました (エラー $210D)
Borland Database Engine の初期化中にエラーが発生しました (エラー $2501)
Borland Database Engine の初期化中にエラーが発生しました (エラー $2A06)


図45
初期化中にエラー

BDE の再インストールと言う手段もあるかも知れませんが,この項目の値を範囲内の値に修正すれば回避できるという記事があります.下図では $3BDE という値にしています.BDE の設定なので,BDE という値があるのは分かりやすいかも知れません.



  • 図48 
  • BDEAdmmin.exe を起動して,[System] [INIT] の SHAREDMEMLOCATION の値を変更する





Delphi XE7 以降で BDE を使用する


Delphi XE7 では BDE は添付されなくなりました.Delphi XE7 以降で BDE を使用するには,以下のリンクから別途ダウンロードしてインストールする必要があります.
インストール用のプログラムは,Delphi のバージョンによって異なります.

BDE + Paradox のように手軽に使用できるデータベースとして,以下のようなものもあります.
また,ADO でも接続可能なデータベースがあります.





システム関係フォルダや特殊フォルダの操作には要注意


アプリケーションで,システム関係のフォルダや特殊フォルダにアクセスする場合,コードで直接絶対パスを指定しないようにします.絶対パスが必要な場合は,実行時に絶対パスに変換にします.
これは,Windows Vista 以降に限りません.Windows XP 以前でも同じです.

絶対バスを使用してしまうと,別のバージョンの Windows や別のコンピュータで実行したり,あるいは別のユーザが操作すると正常に動作しなくなる場合があります.また,32 ビット版の Windows では正常に動作していたアプリが,64 ビット版の Windows では正常動作しない現象が発生することがあります.当然その逆の現象が発生することも考えられます.