はじめまして、よろしくお願いいたします。
はじめての投稿なので失礼がありましたらご教示ください。
悩んでいるのは、
c#(.NET Framework)でビルドしたPCでは問題なくレジストリを読み込むことができるのに、
他のPCで実行すると、レジストリが読めないことです。
■手順
c#
1 RegistryKey key = Registry.CurrentUser; 2 key = key.OpenSubKey(@"Software\XXXXX\XXXXX\XXXXX"); 3 MessageBox.Show(key.ToString());
-
Installerクラス内にレジストリを読み込む処理を記載(dllファイル)
-
setupプロジェクトをビルドし、作成されたsetup.exeを実行する。
-
ビルドしたPC(端末A)でインストール実施→正常終了
-
作成されたsetup.exeを他のPC(端末B)で実行すると、
インストール中、「オブジェクト参照がオブジェクトインスタンスに設定
されていません。」でエラーになります。
■参考
コンソールアプリ(exe)で、上記1のコードを書くと正常終了しますので、
端末Bにも当該レジストリキーは存在します。
OSのバージョン(Win10 64bit)、ユーザ権限(admin)も同じです。
何かお気づきの点があればアドバイスいただけたら助かります。
よろしくお願いいたします。
■追記
c#
1 RegistryKey key = Registry.CurrentUser; 2 key = key.OpenSubKey(@"Software\XXXXX\XXXXX\XXXXX"); 3 MessageBox.Show(key.ToString()); ★
MessageBoxの記載(★)を削除すると、「オブジェクト参照がオブジェクトインスタンスに設定されていません。」の
エラーは発生しません。
ただ、端末A(ビルドしたPC)と端末B(その他のPC)で動作が違うのが未だに分かりません。。
.NET Core ではありませんか?
他のPCにも読むレジストリの項目が有り値は入っているのでしょうか?
いや、読み間違えました。タイトルは内容を表すものにしてください。できないのはレジストリを読むことではなく、セットアップです。
Zuishin様
大変失礼しました。記載を見直しました。ご指摘ありがとうございます。
Wind様
ありがとうございます。
はい、他のPCにも同様のレジストリが間違いなくあり、値も入っていることは確認済です。
同じコードでコンソールプログラムから実行すると読み込めるので。
いや、レジストリを読む以前にセットアップで失敗していませんか?
インストールできてないんですよね?
レジストリの問題ではなく、セットアッププロジェクトの作成に失敗しているのではありませんか?
それとも、レジストリを読もうとしているのは setup.exe ですか?
だとしたらそれをどのようにして作ったのかという情報が必要になります。
端末A,端末Bともに64ビット版Windowsなのですよね。その読みだすDLLは32ビット版ですか? HKEY_CURRENT_USER\Software\Wow6432Node にキーがあるのでは?
いえ。
セットアップが失敗しているのは、記載したコードでレジストリが取得できないからです。
レジストリを読み込むコードを削除するとセットアップは完了します。
MessageBox.Show(key.ToString());
を
MessageBox.Show(key?.ToString() ?? System.Environment.UserName);
にしてみてください。
dodox86様
ありがとうございます。DLLは32ビットです。
HKEY_CURRENT_USER\Software\Wow6432Node も疑ったのですが、値はありませんし、
レジストリの場所は間違いなくあっているのです。
hihijiji様
ありがとうございます。
端末Aでは正しく読めて、端末BではSYSTEMと表示されてしまいました。
何かあるんですね、お分かりでしょうか?
hihijiji様のアドバイスで気づいたのですが、MessageBoxの記載を削除すると、「オブジェクト参照がオブジェクトインスタンスに設定されていません。」のエラーは発生しませんでした。
ただ、端末間で動作が違うのが未だに分かりません。。
System.Environment.UserName);でのユーザー名が"SYSTEM"なのは、インストール過程でWindows InstallerサービスがそのDLLを動かしている(アクション)からです。"SYSTEM"ユーザーのHKEY_CURRENT_USERは当然、別のところなので読めません。実行されているアクションが違うのかな?解せませんが。
dodox86様
ありがとうございます。端末A、端末BともMessageBox.Show(Environment.UserName);ではSYSTEMと表示されました。それでも端末Aはレジストリ読めるんですよね。
HKEY_USERS 以下に各ユーザーの HKEY_CURRENT_USER の元が入っています。どのユーザーが見るかによってこの中のどれが HKEY_CURRENT_USER になるかが変わります。ここはまだ調べてないですよね?
Zuishin様
ありがとうございます。はい、ここは未チェックです!(勉強になりました)。
これから違いを調べてみて、気づいたところを投稿します。
>sparcさん
> 端末A、端末BともMessageBox.Show(Environment.UserName);ではSYSTEMと表示されました。それでも端末Aはレジストリ読めるんですよね。
そう言う意味でしたか。であればまた別の問題ですね。Windowsインストーラーは、*.msiを起動したときのユーザーアカウントで動作するUIのプロセスと、Windows Installerサービスのアカウント("SYSTEM")のWindowsサービスプロセスの協調動作でインストールを行います。レジストリを読むような独自のカスタムアクションの実行タイミングによって参照できるUserNameが変わるということで、それがHKEY_CURRENT_USERの参照先も変わる、ということにつながりますので、その線での指摘でした。
> *.msiを起動したときのユーザーアカウント
*.msiを内包するランチャーであるsetup.exeを使っているのであれば、ユーザーアカウント事情もまた複雑になりますけども。(以上、単なる参考情報です)
Zuishin様、みなさま
Zuishin様のヒントのおかげで、かなり前進しました。
失敗する端末Bのレジストリ、HKEY_USERS\S-1-5-18(システム)を見ると、当該キーがありませんでした。ここにキーを手動で作ってあげると、端末Bでも成功しました。
成功する端末Aには、もともとHKEY_USERS\S-1-5-18配下に、当該キーがありました。
つまり、端末Aと端末Bの違いは、HKEY_USERS\S-1-5-18配下にキーがあるかないか。でした。
ただなぜ、端末Bにはその値がないのかが分かりません。
ちなみに、端末C(HyperV)も見てみましたが、こちらもHKEY_USERS\S-1-5-18配下にキーはなく、レジストリ取得できません。
dodox86様
私のコメントが分かりにくくて申し訳ありません。
大変勉強になります!ありがとうございます。
HKEY_CURRENT_USER¥Softwareの下は、まさに個別のソフトウェア製品のキーが並ぶところなので、端末Aにしかインストールされていない何らかのソフトがあるのではないですか。それでも、あまりSYSTEMユーザー用の下にキーがあるのは見たことが無いですけど。(あっていけないものでもないが)
SYSTEMユーザー用の下にキーは当該ソフト以外にもAdobeやDropBoxなどのキーもありました。
ただ、おっしゃるとおり、インストールされている全てがある理由ではありませんね。
お付き合いいただいたみなさま
結論として、レジストリが取得できないのではなく、レジストリキーの配置に問題があることが分かりましたので、こちらはクローズさせていただきたいと思います。
CurrentUserの参照は辞めて、LocalMachineなど他のキーを参照することにしたいと思いますが、新たな問題が。。。散々悩んで分からなかったらこちらでお世話になれればと思います。
皆様、多くのアドバイスありがとうございました。勉強になりました!
すみません。なんだか結果を入力したら自分のがベストアンサーになってしまいました。
みなさま、特にZuishin様のアドバイスが解決のきっかけでした。失礼を申し訳ありません。
自分のがベストアンサーでいいと思いますよ。あとユーザーが違うことに気づいた hihijiji さんの功績が大きいんじゃないかと思います。
Zuishin様アドバイスありがとうございます。
確かに、hihijiji様のSYSTEMと出てきましたがこれは一体?というところがきっかけです!
hihijiji様、大変失礼しました。SYSTEM?あれ?ユーザ名が出てこない?となったことから、Zuishin様やdodox86様のアドバイスに繋がったものと思います。よろしければ今後とも宜しくお願いいいたします。
回答1件
あなたの回答
tips
プレビュー