RegQueryValueExwでエラー

このQ&Aのポイント
  • RegQueryValueExwでエラーが発生しています。
  • RegQueryValueExw関数を使用する際、2バイト文字が含まれている場合にエラーが生じます。
  • VB 6.0では問題なく動作していましたが、現在の環境ではエラーが発生します。
回答を見る
  • ベストアンサー

RegQueryValueExwでエラー

お世話になります。 Declare Function RegQueryValueExString Lib "advapi32.dll" Alias _ "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByVal lpData As String, ByRef lpcbData As Integer) As Integer RegQueryValueExString(hKey, ValueName, 0, intType, strValue, intSize) この時、ValueNameに2バイト文字が含まれているとエラーになります。 VB 6.0の時は問題なく動いていました。 ご存知の方ご教示お願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

>RegQueryValueExwでエラー >Declare Function >ValueNameに2バイト文字 これは文字コードの関係で発生しているだけだと思います。 パラメータに文字コードを指定すると、そのまま利用可能かもしれません。 いっその事、VB6をそのまま利用せず、ちょっと宣言に改造を加えましょう。 さらに、おまけで「RegQueryValueExAとRegQueryValueExWを意識させない作り」にしちゃいましょう。 これは「System.Runtime.InteropServices」を利用することにより、宣言の改造で実現できます。 RegQueryValueExは前後の関係もあるので、、、 VB6の元ネタ http://okwave.jp/kotaeru.php3?q=1253134 をコンバートして張っておきます。(Class:API_Win32) さらに、せっかくの.NETなので、Frameworkを利用したバージョンも載せておきます。(Class:API_NET_Framework) http://www.microsoft.com/japan/msdn/net/general/win32map.asp ※構成 WindowsApplicationXX.vbproj └Module1.vb Main()から開始する構成です。 Module1.vbにクラス部分も含め、下のコードをそのまま全部張ってください。 >Dim objClass As New API_Win32() >Dim objClass As New API_NET_Framework() のどちらかをのコメントを解除してください。 --------------------------------------------------------------------------------------------------------------------------- Option Compare Binary Option Strict On Option Explicit On Imports System.Runtime.InteropServices Module Module1   'アンインストールルート   Public Const DEFSTR_UNINSTALL_REG_SUBKEY_PARENT As String = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"   'アンインストール表示名称取得用キー   Public Const DEFSTR_UNINSTALL_REG_NAME_DISPLAYNAME As String = "DisplayName"   Sub Main()     '-----------------------------     '使いたい方を、コメント解除して使う     'Dim objClass As New API_Win32()     'Dim objClass As New API_NET_Framework()     '-----------------------------     Dim colWk As Collection     Dim i As Integer     If Not objClass.Test(colWk) Then       MsgBox("失敗")     End If     For i = 1 To colWk.Count       Console.WriteLine(colWk(i))     Next i   End Sub End Module 'WIN32 APIバージョン Public Class API_Win32   Private Structure FILETIME     Dim dwLowDateTime As Integer     Dim dwHighDateTime As Integer   End Structure   Private Const HKEY_CLASSES_ROOT As Integer = &H80000000   Private Const HKEY_CURRENT_USER As Integer = &H80000001   Private Const HKEY_LOCAL_MACHINE As Integer = &H80000002   Private Const HKEY_USERS As Integer = &H80000003   Private Const HKEY_PERFORMANCE_DATA As Integer = &H80000004   Private Const HKEY_CURRENT_CONFIG As Integer = &H80000005   Private Const HKEY_DYN_DATA As Integer = &H80000006   Private Const MAX_LEN As Integer = 2048   Private Const KEY_QUERY_VALUE As Integer = &H1   Private Const KEY_ENUMERATE_SUB_KEYS As Integer = &H8   Private Const KEY_NOTIFY As Integer = &H10   Private Const SYNCHRONIZE As Integer = &H100000   Private Const STANDARD_RIGHTS_READ As Integer = &H20000   Private Const KEY_READ As Integer = ((STANDARD_RIGHTS_READ Or _          KEY_QUERY_VALUE Or _          KEY_ENUMERATE_SUB_KEYS Or _          KEY_NOTIFY) And (Not SYNCHRONIZE))   Private Const ERROR_SUCCESS As Integer = 0&   <DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _   Private Shared Function RegOpenKeyEx( _       ByVal hKey As Integer, _       <MarshalAs(UnmanagedType.LPTStr)> ByVal lpSubKey As String, _       ByVal ulOptions As Integer, _       ByVal samDesired As Integer, _       ByRef phkResult As IntPtr _   ) As Integer   End Function   <DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _   Private Shared Function RegCloseKey( _       ByVal hKey As IntPtr _   ) As Integer   End Function   <DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _   Private Shared Function RegEnumKeyEx( _       ByVal hKey As IntPtr, _       ByVal dwIndex As Integer, _       <MarshalAs(UnmanagedType.LPTStr)> ByVal lpName As String, _       ByRef lpcbName As Integer, _       ByVal lpReserved As Integer, _       <MarshalAs(UnmanagedType.LPTStr)> ByVal lpClass As String, _       ByRef lpcbClass As Integer, _       <MarshalAs(UnmanagedType.Struct)> ByRef lpftLastWriteTime As FILETIME _   ) As Integer   End Function   <DllImport("advapi32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _   Private Shared Function RegQueryValueEx( _       ByVal hKey As IntPtr, _        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpValueName As String, _       ByVal lpReserved As Integer, _       ByRef lpType As Integer, _       <MarshalAs(UnmanagedType.LPTStr)> ByVal lpData As String, _       ByRef lpcbData As Integer _   ) As Integer   End Function   Public Function Test( _     Optional ByRef p_coRet As Collection = Nothing _   ) As Boolean     p_coRet = New Collection()     If Not GetAppUnInstDisplay(p_coRet) Then       Return False     End If     Return True   End Function   'アンインストール情報表示名の取得   Private Function GetAppUnInstDisplay( _       Optional ByRef otCol As Collection = Nothing _   ) As Boolean     Dim intRet As Integer     Dim hReg As IntPtr     Dim intIndex As Integer     Dim strBuffSubKey As String     Dim FT As FILETIME     Dim strSubKey As String     Dim strDspName As String     '返りコレクション初期化     otCol = New Collection()     'キーオープン     If Not (ERROR_SUCCESS = RegOpenKeyEx(HKEY_LOCAL_MACHINE, DEFSTR_UNINSTALL_REG_SUBKEY_PARENT, 0, KEY_READ, hReg)) Then       'キーオープン失敗なので、強制抜け       Exit Function     End If     'インデックス初期化     intIndex = 0     Do       'intIndex個目のサブキーを取得       strBuffSubKey = New String(CChar(vbNullChar), MAX_LEN)       intRet = RegEnumKeyEx(hReg, intIndex, strBuffSubKey, MAX_LEN, 0, vbNullString, 0, FT)       If intRet = ERROR_SUCCESS Then         '値を取得するサブキーの整理         strSubKey = DEFSTR_UNINSTALL_REG_SUBKEY_PARENT & "\" & BuffArrangement(strBuffSubKey)         'アンインストール表示名称の取得         If GetRegValue(HKEY_LOCAL_MACHINE, strSubKey, DEFSTR_UNINSTALL_REG_NAME_DISPLAYNAME, strDspName) Then           '取得できたなら、コレクションに追加           otCol.Add(strDspName)         End If         'インデックスを進める         intIndex = intIndex + 1       End If     Loop While intRet = 0     GetAppUnInstDisplay = True PGMEND:     'キークローズ     Call RegCloseKey(hReg)   End Function   'レジストリ値取得(文字列)   Private Function GetRegValue( _       ByVal inKey As Integer, _       ByVal inSubKey As String, _       ByVal inName As String, _       Optional ByRef otValue As String = Nothing _   ) As Boolean     Dim hReg As IntPtr     Dim strBuffValue As String     Dim intLen As Integer     Dim intType As Integer     'キーオープン     If Not (ERROR_SUCCESS = RegOpenKeyEx(inKey, inSubKey, 0, KEY_QUERY_VALUE, hReg)) Then       Exit Function     End If     'レジストリ値取得メイン     strBuffValue = New String(CChar(vbNullChar), MAX_LEN)     If (ERROR_SUCCESS = RegQueryValueEx(hReg, inName, 0, intType, strBuffValue, MAX_LEN)) Then       otValue = BuffArrangement(strBuffValue)       GetRegValue = (otValue <> "")     End If     'キークローズ     Call RegCloseKey(hReg)   End Function   'API独特のバッファNULL文字の消去   Private Function BuffArrangement(ByVal inBuff As String) As String     On Error Resume Next     BuffArrangement = Left$(inBuff, InStr(1, inBuff, vbNullChar) - 1)   End Function End Class '.NET Framework API バージョン Public Class API_NET_Framework   Public Function Test( _     Optional ByRef p_coRet As Collection = Nothing _   ) As Boolean     p_coRet = New Collection()     If Not GetAppUnInstDisplay(p_coRet) Then       Return False     End If     Return True   End Function   'アンインストール情報表示名の取得   Private Function GetAppUnInstDisplay( _       Optional ByRef otCol As Collection = Nothing _   ) As Boolean     Dim l_strBuffSubKey As String     Dim l_strSubKey As String     'レジストリ/アンインストール情報のルート取得     Dim l_regUnInst_Root As Microsoft.Win32.RegistryKey     Dim l_regUnInst_Sub As Microsoft.Win32.RegistryKey     '返りコレクション初期化     otCol = New Collection()     'レジストリ/アンインストール情報のルート取得     l_regUnInst_Root = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(DEFSTR_UNINSTALL_REG_SUBKEY_PARENT)     If (l_regUnInst_Root Is Nothing) Then       '取得失敗       Exit Function     End If     Dim objWk As Object     'ルート内部のサブキーでループ     For Each l_strBuffSubKey In l_regUnInst_Root.GetSubKeyNames()       ''値を取得するサブキーの整理       l_strSubKey = DEFSTR_UNINSTALL_REG_SUBKEY_PARENT & "\" & l_strBuffSubKey       l_regUnInst_Sub = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(l_strSubKey)       'アンインストール表示名称の取得       objWk = l_regUnInst_Sub.GetValue(DEFSTR_UNINSTALL_REG_NAME_DISPLAYNAME)       If Not (objWk Is Nothing) Then         '取得できたなら、コレクションに追加         otCol.Add(objWk.ToString)       End If     Next     l_regUnInst_Root.Close()     GetAppUnInstDisplay = True   End Function End Class

chibita_papa
質問者

お礼

1050YENさん、有難うございました。 サンプルを参考に .NET Framework API バージョン で作成してみました。 ゴチャゴチャしたコードがすっきり見やすくなりました。 今後ともよろしくお願いいたします。

関連するQ&A

  • VB2003で レジストリを格納する

    レジストリを格納するために、以下のように宣言し、 Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" (ByVal hKey As Integer, ByVal lpSubKey As String, ByVal Reserved As Integer, ByVal lpClass As String, ByVal dwOptions As Integer, ByVal samDesired As Integer, ByRef lpSecurityAttributes As SECURITY_ATTRIBUTES, ByRef phkResult As Integer, ByRef lpdwDisposition As Integer) As Integer Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Integer, ByVal lpValueName As String, ByVal Reserved As Integer, ByVal dwType As Integer, ByRef lpData As String, ByVal cbData As Integer) As Integer Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Integer) As Integer 以下のようなコードで、ユーザーエージェントをmozillaからoperaへ(またはoperaからmozilla)書き換えようとしていますが、うまくいきません。 問題点1.同じuser agentの下に”(既定)”が2つできてしまう 問題点2.データが正しく(operaと)書き込まれず、文字化けしたものが書き込まれている。 C言語用のサンプルやVB6.0のサンプルは見ますが、VB2003ではどのように指定するのか、わかりませんでした。 Dim ret As Long Dim hKey As Long, lngDisposition As Long Dim udt As SECURITY_ATTRIBUTES Dim myroot_key As String, mysub_key_user_agent As String, myName As String,StrValue As String myroot_key = &H80000002 '"HKEY_LOCAL_MACHINE" を指定している mysub_key_user_agent ="Software\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent" myName = "(既定)" strValue="Opera" ret = RegCreateKeyEx(myroot_key, mysub_key_user_agent, 0&, vbNullString, _ 0, &H4 Or &H2, udt, hKey, lngDisposition) If ret = 0 Then ret = RegSetValueEx(hKey, myName, 0, 1, strValue, Len(strValue) + 1) RegCloseKey(hKey)

  • APIって

    VBで簡単なプログラムを作成しています。 APIも便利なのでサンプルを見ながら使っていますが ふと疑問に思ったので教えて下さい。 以下の"advapi32.dll"と"ADVAPI32"の違いは何なのでしょうか。 大文字、小文字の違いだけで同じなのですか? dllを省略すると引数に&をつけるつけないの違いが出るのでしょうか? 'レジストリの値を取得する Public Declare Function RegQueryValueExstr Lib "ADVAPI32" Alias "RegQueryValueExA" (ByVal hKey&, ByVal lpValueName$, ByVal lpReserved&, ByVal lpType&, ByVal lpData$, lpcbData&) As Long 'レジストリの値を設定する Public Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpData As Any, ByVal cbData As Long) As Long ネット上にたくさんサンプルはあるので、やりたいことの方法を調べてできればOKといったやり方です。 きちんと勉強したい気持ちもありますので、参考書籍等紹介して頂いてもうれしいです。

  • VBAでDLLが見つからないエラー

    CADのVBA(6.0)ですが、DLLが見つからないエラーが出ます ' こっちはエラーが出ない Public Declare Function SearchVBApath Lib _ "C:\Program Files\AppliTool\VB\DDDD.dll" (ByVal env As String, ByVal s As String) As Integer 'こっちだとエラーが出る Public Declare Function SearchVBApath Lib "DDDD.dll" (ByVal env As String, ByVal s As String)    As Integer VBAプロジェクトファイルとDLLは同じフォルダにおいてあります 上記のようにフルパスだとエラーが出ないのですがDLL名だけだとこの関数のところでエラーがでます このDLL関数宣言行の前の方には他のDLL関数も同じようにパス省略で記述しているのですがそちらにはエラーが出ません どなたかヒント下さい、よろしくお願いします。

  • アニメーションカーソルへの変更

    VB2005,WindowsXPproの環境で開発を行っております。 ある特定の操作を行った場合にカーソルをアニメーションカーソルに 変更したいのですが、うまくいっていません。 .net frameworkのcursorクラスはアニメーションカーソルを サポートしてないとのことなので、Win32APIを利用しています。 Declare Function LoadCursorFromFile Lib "user32.dll" Alias "LoadCursorFromFileA" (ByVal lpFileName As String) As Integer Declare Function SetSystemCursor Lib "user32.dll" (ByVal hCursor As Integer, ByVal uId As Integer) As Integer Const IDC_ARROW As Integer = 32512 hCursor = LoadCursorFromFile("アニメーションカーソルファイル") SetSystemCursor(hCursor, IDC_ARROW) 上記のコードでアニメーションカーソルへの変更は できたのですが、元に戻すことができません。 どなたか、お知恵を拝借ください。 よろしくお願いします。

  • Access Win32 API使用 検索方法

    32bit版で開発したAcceessを64bit版で開いたところ、Win32 APIのソースコードでエラーが発生しました。 ネットで検索したところ、対処法はすぐHITしました。 「#If~#Else~#End If」の条件付きコンパイルを使うそうです。 例) #If VBA7 And Win64 Then '64ビット版 Declare PtrSafe Function GetFileTitle Lib "comdlg32.dll" Alias "GetFileTitleA" (ByVal lpszFile As String, ByVal lpszTitle As String, ByVal cbBuf As Integer) As Integer #Else '32ビット版 Declare Function GetFileTitle Lib "comdlg32.dll" Alias "GetFileTitleA" (ByVal lpszFile As String, ByVal lpszTitle As String, ByVal cbBuf As Integer) As Integer #End If ここで質問ですが、改修するにあたり、APIのソースコードを使用しているところって どう検索をすればいいでしょうか?

  • ユーザー名の取得で

    ユーザー名の取得がうまくいきません。 どなたか教えて下さい。 環境はVB.net 2003です。 '宣言部 Declare Ansi Function GetUserNameByDeclare Lib "advapi32.dll" _ Alias "GetUserNameA" (ByVal lpBuffer As String, ByRef nSize As Integer) As Integer 'ソース内   Const UNLEN As Integer = 256   Dim tusr As String   Dim ln As Integer   tusr = Space(UNLEN)   ln = Len(tusr)   GetUserNameByDeclare(tusr, ln)   strdir = "C:\Documents and Settings\" & tusr & "\My Documents" 上記、ユーザー名(tusr)は取得できるんですが、strdirのtusr以下の部分 "\My Documents" が削られてしまいます。 どこが悪いんでしょう? よろしくお願いします。

  • VB6のAdressOfをVB.NETに変換したい

    以下のソースをVB.NETに変換したいのですが... XOpenDLL関数の AddressOfのあたりがエラーになって変換できません。 (Microsoft Visual Basic .NET 2003の変換機能) Private Declare Function XOpenDLL Lib _ "Maser.dll" _ Alias "OpenDLL" _ (ByVal nModel As Long, _ ByVal nLens As Long, _ ByVal nLensMfr As Long, _ ByVal nGSpeed As Long, _ ByVal nSocketPort As Long, _ ByVal nRS232Port As Long, _ ByVal pCallbackFn As Long) _ As Boolean Private Declare Function XSendCommand Lib _ "Maser.dll" _ Alias "SendCommandVB" _ (ByVal OpCode As Long, _ ByVal PropCode As Long, _ ByVal InputString As String, _ ByRef Output As String) _ As Integer Private Declare Sub XCloseDLL Lib _ "Maser.dll" _ Alias "CloseDLL" () Then to use these functions: ‘ Open the DLL bInstance = XOpenDLL(nModel, nLens, nLensMfr, nGSpeed, nSocketPort, nRS232Port, AddressOf MyCallbackFn) ‘ Send a command nRet = XSendCommand(nOpCode, nPropCode, szInputData, szOutput) ‘ Close the interface Call XCloseDLL お教えください。

  • API FtpPutFileの戻り値

    お世話になっております。 API FtpPutFileを使用しているのですが 確実にFalseになります。一日悩みましたが原因が わかりません。 If FtpPutFile(lngConnect, _ "***.txt", _ "***.txt", _ FTP_TRANSFER_TYPE_ASCII, _ 0&) <> False Then です。必要なものを付け加えておきます。 Private Declare Function FtpPutFile Lib "wininet.dll" _ Alias "FtpPutFileA" _ (ByVal hFtpSession As Long, _ ByRef lpszLocalFile As String, _ ByRef lpszNewRemoteFile As String, _ ByVal dwFlags As Long, _ ByVal dwContext As Long) As Long Private Const FTP_TRANSFER_TYPE_ASCII = &H1& です。環境はWinXP,VB6+SP5 よろしくお願い致します。

  • SendMessageによるチェックボックスの状態取得

    はじめまして、VB.NET2005でチェックボックスの状態の取得、設定をうまく設定できません。OSはxpです。 Public Class Form1 Private Declare Function FindWindow Lib "user32" Alias "FindWindowA"  (ByVal lpClassName As String, _ ByVal lpWindowName As String) As Integer Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, _ ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, _ ByVal wMsg As Integer, ByVal wParam As Integer, ByVal iParam As String) As Integer Private Declare Function SendMessageint Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, _ ByVal wMsg As Integer, ByVal wParam As Integer, ByVal iParam As Integer) As Integer Const BM_GETCHECK = &HF0 Const BM_GETSTATE = &HF2 Const BM_SETCHECK = &HF1 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim hWindows As Integer Dim ipEDIT As Integer Dim i As Integer hWindows = FindWindow(vbNullString, "Form1") '198458 ipEDIT = FindWindowEx(hWindows, 0, vbNullString, "CheckBox1") MessageBox.Show(ipEDIT) i = SendMessageint(ipEDIT, BM_GETCHECK, 0, 0) 'SendMessageint(ipEDIT, BM_SETCHECK, 1, 0) MessageBox.Show(i) End Sub End Class のようなコードなのですが、 ハンドルは取得できているのですが、 SendMessageの戻り値は0になります。 勿論、コメントのチェックをセットも出来ません。 ご教授のほど宜しくお願いします。

  • EXCELVBA フォルダ検索API

    エクセルからVBAでフォルダを選択させるコマンドを、APIを使ってフォルダ検索ダイアログボックスを出すまでは見よう見真似でできるのですが、このとき「あたらしいフォルダ」のボタンは必要ないので出したくないのですが、どこかに定数を指定すればよろしいかご存知でしたら教えてください。 (使用OS: Windows2000,Excel:2003) ちなみにコピペした宣言部分は以下のものです。 *************** Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _ (ByVal pidl As Long, ByVal pszPath As String) As Long Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As Long Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long) Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Public Const WM_USER = &H400 Public Const BFFM_SETSELECTIONA = (WM_USER + 102) Public Const BFFM_INITIALIZED = 1 ********************

専門家に質問してみよう