SetRegistryKeyをコメントアウトするとエラーに

[戻る]
ともこ 2012/01/05(木) 17:42:01
こんにちは。
実行ファイルと同じ場所にINIファイルを作成したく、
ネット上のサンプルをいくつか試したのですが、
実装する途中で次の問題が起きています。

WindowsXP、VC++2008のMFCにて、
SDIもしくはMDIのプロジェクトをデフォルト設定で新規作成し、
InitInstanceの中にあるSetRegistryKeyをコメントアウトしただけで、
実行時にafxregpath.cppの33行目でアサーションが発生するという点です。
※ダイアログベースでは発生しませんでした。

過去ログを読んでも、コメントアウトするだけでこういったことにはならないようです。
原因、解決に心当たりがつかないので、助言をいただけないでしょうか。

tetrapod 2012/01/05(木) 18:40:58
> 実行ファイルと同じ場所にINIファイルを作成したく、
これが
Windows XP では非推奨の動作であって (互換性のためにやむなく認められていた)
Vista/7 では UAC が明確に禁じている動作である、というのは理解している?
そういうコードを書くと Vista 以後では動作しなくなるよ。

VS2005 では SetRegistryKey をコメントにしても何一つ問題なく動作している。
VS2008 は手元にないのでチェックできない。

妄想と憶測で読み解くに VS2008 以後は INI ファイルのサポートを打ち切った。
だから assert で失敗するんではないかな・・・
INI ファイルではなく HKCU に設定を置け、という意思表示である、と思う。

PATIO 2012/01/05(木) 19:31:14
C#とかの動きを見ているとレジストリに置くのも微妙かなと思ったりします。
ただ、VC++でMFCを使っているような環境ではC#と同じ操作が提供されていないので
同じにするのが正解なのかと言われると自信はありません。

今のmicrosoftの動きを見ているとアプリケーションの設定情報はDocuments and
Settingsの下の各ユーザー毎の設定ファイル(XML)に保存する事を推奨しているのかなと
感じています。
ただ、VC+++MFCで考えるとその為の手段が用意されていないんですよね。
C#とかVBだとその辺の手段が提供されているから利用しやすいんですけれど。

いずれにせよ、Vista以降のUACの実装で状況が変わってしまっているのは事実なので
新しい環境に適応する為のアプリケーション設定の保存方法をきちんと把握して
実装していく必要があるのは間違い無いと思います。

できれば、MFCからも同じ設定ファイルを利用できるようにクラスライブラリを用意して
欲しいのが本音ですね。

PATIO 2012/01/05(木) 19:32:38
ああ、Documents and SettingsというのはXPでの話ですね。
Vista以降はフォルダ名が変わっていたはずです。
自分がVistaを使っていないので空では出てこないのですけれど。

ともこ 2012/01/05(木) 19:44:06
tetrapod 様
回答ありがとうございます。

知りませんでした…。
今の開発環境ではINIファイルでの管理はできないんですね。
また調べてみると、簡潔に何という違いなのか分かりませんが、
VS2008でもCWinAppを使うアプリでは可能で、
CWinAppExを使うアプリではアサートになることが確認できました。
CWinAppExはVS2008から提供されたものらしいので、納得できました。

最初の目的を諦めたところで気になった点があるのですが、
WriteProfileInt、WriteProfileStringなどの関数は
レジストリとINIファイルのどちらにも書き込めるんですね。
これはもしかして、初期設定でどこに書き込むかを設定しておけば、
後々INIファイル管理からレジストリ管理に変更したいとなった場合でも、
ソースコードを瞬時に修正できるということでしょうか?

ともこ 2012/01/05(木) 19:54:32
PATIO 様
回答ありがとうございます。

MFCはレジストリ推奨で、C#などはXML推奨ということですか…。
とりあえず現時点ではINIファイルのことは忘れて、レジストリにしておけばXP、Vistaで
も問題はないということですね。

tetrapod 2012/01/05(木) 23:36:29
CWinAppEx はレジストリに特化している = INI は使えない、という話は、
検索すればいくつも見つかるようだね。

以下 CWinAppEx は使わず CWinApp 限定の話として

> これはもしかして、初期設定でどこに書き込むかを設定しておけば、
それが CWinApp::SetRegistryKey なわけで。
呼ぶ=レジストリ HKCU に対して入出力
呼ばない=INI ファイルに対して入出力

ただし UAC と共存できる形で INI ファイルを使おうとすると結構面倒で、
Vista/7 でも動かす必要があるなら (MFC なら) レジストリ1択かと。

ともこ 2012/01/06(金) 01:08:00
[[解決]]
回答ありがとうございます。
それでは心おきなくレジストリを使うことにします。

PATIO 2012/01/06(金) 09:26:56
解決になっていますが、

Program Filesの配下に一般ユーザーで書き込むなとか
その辺りのUACに絡む部分は設定ファイル云々以前の問題としてあるので
把握しておいた方が良いです。
基本的にユーザーが自由に書き込めるのは各ユーザー毎のフォルダ配下になります。
なので、設定ファイルを置くのであればINIファイルを使うとしてもそこに置きなさい
と言う話です。ですから、基本的に書き換えが必要なファイルを実行ファイルと
同じフォルダに置くのはファイルの構成的に間違っていると言う事です。
インストール時に置いておいて後は読込のみなら問題ないんですけれど。

レジストリを使うにしてもUACは絡んできますのでご注意を。
HKCU (HKEY_CURRENT_USER)に書き込む分には問題ありませんが、
HKLM (HKEY_LOCAL_MACHINE)の場合はUACに引っかかります。
レジストリの場合、OS側で勝手にリダイレクトされて他の所に書き込まれたりする
(エラーにならない)ので注意が必要です。

Vista以降はUACが絡んできますので意識しておいた方が良いと思います。
UNIXとかだとこの辺の権限絡みの話は常識なんですけれど、
Windowsはゆるゆるだったので今更感ありありですね。

古いスレッドには追加発言できません。