トップ回答者
Windows10+VB2017でWin32APIが呼び出せない。

質問
-
Windows10+VB2017でWin32APIが呼び出せません。最終的にはRegQueryValueExを呼び出し、Internet ExplorerによりDownload Folderに設定されているフォルダを特定したいと考えているのですが、これに先立ちInternet ExplorerのキーをオープンするRegOpenKeyExが起動せず、悩んでいます。
下記のSubを起動すると、サブキーのオープンに失敗しました、とのメッセージと共に、エラーコード87で終了してしまいます。このエラーはパラメーターが間違っているときに発生するようですが、API宣言の引数の型はLong型からInteger型に変更してありますし、呼び出しの際の型もInteger型からShort型に変更してあります。これ以上はどこを修正すればいいのか分かりません。どうすればよいのでしょうか?p.s.
本フォーラムにて、類似する質問を見つけましたが、System.Text.StringBuilderが使われていたりと、私では理解できない構文が使われていたため、改めて質問させていただきます。
https://social.msdn.microsoft.com/Forums/ja-JP/888cc88a-4533-438e-a704-d69b82cfac15/vb2005win32apigetprinterdriverdirectory?forum=vbgeneralja
Option Explicit OnPublic Class Form1
Private Const HKEY_CURRENT_USER = &H80000001 '現在のユーザーの設定に対するHKEY_USERのリンクPrivate Const KEY_CREATE_LINK = &H20 '他のサブキーへのシンボリックリンクの作成を許可
Private Const KEY_CREATE_SUB_KEY = &H4 'サブキーの作成を許可
Private Const KEY_ENUMERATE_SUB_KEYS = &H8 'サブキーの列挙を許可
Private Const KEY_NOTIFY = &H10 '変更通知を有効にする(WIN95は未対応)
Private Const KEY_QUERY_VALUE = &H1 'サブキーの値の参照を許可
Private Const KEY_SET_VALUE = &H2 'サブキーの書き込みを許可
'KEY_CREATE_SUB_KEY + KEY_SET_VALUEPrivate Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or
KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
'KEY_EXECUTE + KEY_NOTIFYPrivate Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or
KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
(ByVal hKey As Integer, ByVal lpSubKey As String,
ByVal ulOptions As Integer, ByVal samDesired As Integer, phkResult As Integer) As IntegerPrivate Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim hKeyResult As Short 'キーハンドル
Dim SubKey As String 'サブキー
Dim ret As Short '戻り値'----------------------------------
'オープンするサブキーの設定SubKey = "Software\Microsoft\Internet Explorer\Main"
'レジストリのサブキーのオープン(読み込みのみ)ret = RegOpenKeyEx(HKEY_CURRENT_USER, SubKey, 0,
KEY_READ, hKeyResult)If ret <> ERROR_SUCCESS Then
TextBox1.Text = "サブキーのオープンに失敗しました。" & ret
Else
TextBox1.Text = "成功!"
End IfEnd SubEnd Class
回答
-
Hongliangさんの指摘の通りですが、コード自体の問題点としては
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
(ByVal hKey As Integer, ByVal lpSubKey As String,
ByVal ulOptions As Integer, ByVal samDesired As Integer, phkResult As Integer) As IntegerVB6.0以前とVB.NET以降とでは既定の引き渡しの方法が変更されています。ByVal、ByRefどちらも指定しない場合、VB6.0ではByRefとして動作しますが、VB.NET以降ではByValとして動作します。参考にされたのはVB6.0コードでしょうか、引数phkResultの指定が不正になっています。正しくはByRefを指定する必要があります。
その他の問題点として、Alias "RegOpenKeyExA"を指定するのであれば併せてAnsiも指定すべきです。もしくはAliasの指定を削除してもかまいません。また引数hKeyとphkResultの型はネイティブではHKEYですのでVB.NETではIntegerではなくIntPtrです。
- 回答としてマーク ノラネコ 2017年10月6日 6:37
すべての返信
-
Hongliangさんの指摘の通りですが、コード自体の問題点としては
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" _
(ByVal hKey As Integer, ByVal lpSubKey As String,
ByVal ulOptions As Integer, ByVal samDesired As Integer, phkResult As Integer) As IntegerVB6.0以前とVB.NET以降とでは既定の引き渡しの方法が変更されています。ByVal、ByRefどちらも指定しない場合、VB6.0ではByRefとして動作しますが、VB.NET以降ではByValとして動作します。参考にされたのはVB6.0コードでしょうか、引数phkResultの指定が不正になっています。正しくはByRefを指定する必要があります。
その他の問題点として、Alias "RegOpenKeyExA"を指定するのであれば併せてAnsiも指定すべきです。もしくはAliasの指定を削除してもかまいません。また引数hKeyとphkResultの型はネイティブではHKEYですのでVB.NETではIntegerではなくIntPtrです。
- 回答としてマーク ノラネコ 2017年10月6日 6:37