文字化けを防止するには??

解決


AS  2018-07-02 01:59:46  No: 49261

下記のプログラムでプロダクトIDを取得してパスワードを作成してい
ましたが、Windouws10では、更新の度にプロダクトIDが変わるようで、
パスワードの変更が相次いでいます。

このプログラムは2種類のアプリに使っていて、今回3番目のアプリに
組み込みましたが、

Edit1.text:=GetWindowsProductId;

として使用したら、文字化けを起こしました。

他の2つのアプリでも、新しくコンパイルすると同様の文字化けを起こ
します。
何が悪いのか、分かる人がいたら教えてほしいのですが??
XE5で、win8とwin10で両方で文字化けが起こります。
よろしくお願いします。

function GetWindowsProductId: string;
var
  VerInfo: TOSVersionInfo;
  SubKey: string;
  hReg: HKEY;
  PValue: PByte;
  DataType, DataSize: DWORD;
  m:string;
begin
  // *************************************************** バージョンの取得 **
  VerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
  GetVersionEx(VerInfo);

  // ***************************** レジストリのプロダクトID記録位置を取得 **
  if VerInfo.dwPlatformId = VER_PLATFORM_WIN32_NT then
     SubKey := 'SOFTWARE\Microsoft\Windows NT\CurrentVersion'
  else
     SubKey := 'SOFTWARE\Microsoft\Windows\CurrentVersion';

  // *********************************** レジストリからプロダクトIDを取得 **
  // ================================================= レジストリオープン ==
  RegOpenKeyEx(HKEY_LOCAL_MACHINE, PChar(SubKey), 0, KEY_READ, hReg);
  // =========================================================== 値の取得 ==
  GetMem(PValue,255);
  try
    DataType := REG_SZ;
    DataSize := 255;
    RegQueryValueEx(hReg, 'ProductId', nil, @DataType, PValue, @DataSize);
    // ------------------------------------------ 取得した値をEdit1に設定
    m:= PChar(PValue);
  finally
    FreeMem(PValue);
  end;

  // ================================================= レジストリクローズ ==
  RegCloseKey(hReg);

  result:=m;

end;


Mr.XRAY  2018-07-02 03:50:00  No: 49262

>何が悪いのか、分かる人がいたら教えてほしいのですが??

あんたが悪い !! (笑)
で,実は私は分かる人ではないのですが,
明確な環境が不明なので少しだけエスパーになったつもりで 

KEY_READ
  ↓ (以下に変更)
KEY_READ or KEY_WOW64_64KEY

とするとどうなりますか ?

(1) 前に文字化けしないという環境は ?
(2) TRegistry を使用する方法ではダメですか ?
(3) GetMem よりも AllocMem の方が良いかも知れない

分からない人からのレスはいらないと言うのであれば,このレスは無視してください.


igy  2018-07-02 05:43:25  No: 49263

確認ですが、Windows 8 や Windows 10では、そのレジストリの場所に、
ProductId の情報は、書き込まれているのですか?


AS  2018-07-02 06:03:13  No: 49264

igyさん、ありがとうございます。

昨日は、以前からある2種類のアプリはコンパイルしても文字化けしていませんでした。
今朝も文字化けしなかったような気がします。

3種類目のアプリが完成に近づいて、コンパイルしたら文字化けがするので、
その原因を探っていました。

過去15年間無事動いていたものですから、どこかを変更したらどうこうというものではない気がします。

以前からあるアプリもおかしくなったので、ウィルスかなと不安になり、ウィルスバスターで
調べましたが、異常はありませんでした。

なんか、コンパイルの設定に問題があるのではとか、何か変更があったのではとか
と思っています。

提案していただいた点も試してみます。

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


igy  2018-07-02 06:05:55  No: 49265

あと、この掲示板で「プロダクトID」で検索すると、

Windows7で、プロダクトIDを取得するには?
https://www.petitmonte.com/bbs/answers?question_id=7793

とかも、ありますね。参考までに・・


AS  2018-07-02 06:42:00  No: 49266

igyさん、ありがとうございます。

3台目のPCでもコンパイルしたら文字化けしたのであきらめて、
下記のように使おうかとしたら、TRegistry;のところに赤下線が出ました。
USESに何を書いたらいいのか、分かりませんか??

var
  AppKey:string;

  Reg:TRegistry;
  m:string;
 begin

  AppKey:='\SOFTWARE\Microsoft\Windows NT\CurrentVersion';

  Reg:=TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);

  with Reg do
  begin
   try
     RootKey:=HKEY_LOCAL_MACHINE;

     if OpenKey(AppKey,false) then
     begin

      m:=ReadString('ProductId');

     end;
   finally

     Free;

   end;

  end;


igy  2018-07-02 07:08:40  No: 49267

> USESに何を書いたらいいのか、分かりませんか?? 

おそらく
Registry
だと思います。


通りすがり  2018-07-02 07:31:27  No: 49268

HKLMを読むならOpenKeyじゃなくOpenKeyReadOnly
http://docwiki.embarcadero.com/Libraries/XE5/ja/System.Win.Registry.TRegistry.OpenKeyReadOnly
のほうがいいですね。

あとエラーインサイトで赤線が出たり、コンパイルしたときに未定義と出た場合は、そのクラスや型の定義が
されているユニットをusesに追加します。え?どのユニットかわからない?その型でヘルプを引けばユニット名が
書いてありますよ。


Mr.XRAY  2018-07-02 08:44:28  No: 49269

AS さんが提示されたコードをコピペしたらコンパイルできたのでテストしてみました.

実行環境は以下です.
Microsoft Windows [Version 10.0.10586] - 64 bit
Delphi XE4(UP2) Pro VCL-32

KEY_READ or KEY_WOW64_64KEY にして,
プロダクト ID が取得できました.

>確認ですが、Windows 8 や Windows 10では、そのレジストリの場所に、 
>ProductId の情報は、書き込まれているのですか? 

レジストリエディタでも該当キーと名前があることを確認しました.
取得した値と同じであることも確認しました.

なお,KEY_READ の時の結果は「文字化け」ではありません.「ゴミ」です.
「文字化け」は本来の文字ではなく,別の文字が表示されることです.
GetMem で確保したメモリ領域が初期化していないためと思われます.
AllocMem にしたら空文字となりました.

以上です.

>調べましたが、異常はありませんでした。 

レジストリでの有無を訊いているのですから,実際に確認しないとね.
確認しても結果を報告しなければ確認しないのと同じです.
人の話も聞いてね ! お願い !


AS  2018-07-03 08:41:02  No: 49270

X-RAYさん、お礼言うのを忘れてすみませんでした。
確認ですが、KEY_READ だけでは正常な値は取得できなかったんですよね?
KEY_READ→KEY_READ or KEY_WOW64_64KEYは、私のメモに残しておきますので。
ありがとうございました。

通りすがりさん、ありがとうございます。
「そのクラスや型の定義がされているユニット」の中で、クラス??
型??ユニット??という感じですので、ご理解ください。
実は、私も紹介していただいたのと同じようなところを検索したのですが、
どこをusesに書いたらいいのか分からなくて、質問しました。
例えば、TRegistryの前にあるRegistryを書けばいいんですよね?

igyさん、ありがとうございました。
お蔭で、無事に動きました。15年以上も正常に動いていたものが、
急に動かくなるのでは困るので、次のを使うようにします。

var
  WindowsID: TWindowsID;
    m:string;
implementation
uses Registry;
{$R *.dfm}

procedure TWindowsID.OnCreate(Sender: TObject);
var
  AppKey:string;
  Reg:TRegistry;
begin
  AppKey:='\SOFTWARE\Microsoft\Windows NT\CurrentVersion';
  Reg:=TRegistry.Create(KEY_READ or KEY_WOW64_64KEY);

  with Reg do
  begin
   try
     RootKey:=HKEY_LOCAL_MACHINE;
     if OpenKey(AppKey,false) then
     begin
       m:=ReadString('ProductId');
     end;
   finally
     Free;
   end;

  end;
end;


Mr.XRAY  2018-07-03 18:14:15  No: 49271

>X-RAYさん、お礼言うのを忘れてすみませんでした。 

そういう問題なんですか ?
このスレッドを読み直して変なところはありませんか ?
今回に限りませんが.
私には「慇懃無礼」としか思えないのです.

少なくても 15 年は Delphi をお使いなんですね.そうですか.


AS  2018-07-03 21:29:40  No: 49272

X-RAYさん、すみません。

慇懃無礼と言われるのは、残念ですが、
気に障るところがあれば、謝ります。

X-RAYさんのHPでは昔からお世話になっていて、
感謝しております。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加