tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルパスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3173
投稿日: 2006/02/24(Fri) 07:28
投稿者とみぃだ
[OSのVer]:WindowsXPPRO    [VBのVer]:VB.NET2003  
[Access2002]
おはようございます。早速質問します。
iniファイルからmdbのパスワードを持ってきてVBからAccessへのデータの読み込みや更新を
しようとしています。

まずソースですが、
'指定のINIファイルから文字列を取得する
    <DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
    Public Shared Function GetPrivateProfileString( _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpAppName As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpKeyName As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpDefault As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpReturnedString As String, _
        ByVal nSize As Integer, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal iniFilename As String) As Integer
    End Function

    '指定のINIファイルの指定のキーの文字列を変更する
    <DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
    Public Shared Function WritePrivateProfileString( _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpApplicationName As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpKeyName As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpString As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpFileName As String) As Integer
    End Function

    '指定のINIファイルから整数値を取得する
    <DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
    Public Shared Function GetPrivateProfileInt( _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpApplicationName As String, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpKeyName As String, _
        ByVal nDefault As Integer, _
        <MarshalAs(UnmanagedType.LPTStr)> ByVal lpFileName As String) As Integer
    End Function

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
        Dim oleCn = New OleDb.OleDbConnection
        Dim oleCmd As OleDb.OleDbCommand
        Dim oleReader As OleDb.OleDbDataReader
        Dim sql As String
        Dim a As Integer
        Dim b As String = "XXXXX"
        Dim c As String
        Dim iniFileName As String

        Dim DBPath As String
        Dim strBuffer As String = New String(CChar(" "), 256)
        Dim CnAccess As String


        iniFileName = "Setting.ini"
        'INI ファイルをプログラムと同じフォルダに置く場合
        'ルートディレクトリーかの判断
        Dim MyPath As String = Application.StartupPath
        If MyPath.EndsWith("\") = False Then
            MyPath &= "\"
        End If
        iniFileName = MyPath & iniFileName

        DBPath = Path.Combine(Application.StartupPath, "new.mdb")
        c = GetPrivateProfileString("database", "pass", "", _
                                         strBuffer, 256, iniFileName)
        c = strBuffer

        'コネクション文字列設定
        CnAccess = "Provider=Microsoft.Jet.OLEDB.4.0;"
        CnAccess &= "Data Source=" & DBPath & ";"

        'オプション
        CnAccess &= "Persist Security Info=True;"

        'データベースのパスワード
        '↓T 'System.ArgumentException' のハンドルされていない例外が system.data.dll で発
生しました。
        '追加情報 : 初期化文字列の形式が仕様に適合しません。インデックス 150 で始まっていま
す。

        CnAccess &= "Jet OLEDB:Database Password=" & CStr(c) & "
;"

        '  CnAccess &= "Jet OLEDB:Database Password=" & b & ";&q
uot; ・・・Uこちらはうまくいく

        Dim Cn As OleDbConnection
        Cn = New OleDbConnection(CnAccess)
        'コネクションのオープン・クローズ
        Try
            Cn.Open()
            sql = "SELECT * FROM Member"

            'レコード選択SQL文を作成してレコードを取得する
            oleCmd = New OleDb.OleDbCommand(sql, Cn)
            oleReader = oleCmd.ExecuteReader()

            'フィールドの数
            a = oleReader.FieldCount
            Cn.Close()
        Catch ex As Exception
            MsgBox(ex.Message)
            Exit Sub
        End Try
        MsgBox(CStr(a))
    End Sub

exeと同じところにnew.mdb、setting.iniがあるんですけど、
Iをコメントを外すして起動後、ボタン1を押すと、
'System.ArgumentException' のハンドルされていない例外が system.data.dll で発生しました。
'追加情報 : 初期化文字列の形式が仕様に適合しません。インデックス 150 で始まっています。

とでます。
TをコメントアウトしてUをコメントを外すとうまくいきますが・・・

'追加情報 : 初期化文字列の形式が仕様に適合しません。インデックス 150 で始まっています。
の対策方法をどなたか教えてください。

[ツリー表示へ]
タイトルRe: パスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3174
投稿日: 2006/02/24(Fri) 08:31
投稿者YAS
とみぃださん,こんにちは。

><DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
>Public Shared Function GetPrivateProfileString( _
>    <MarshalAs(UnmanagedType.LPTStr)> ByVal lpAppName As String, _
>    <MarshalAs(UnmanagedType.LPTStr)> ByVal lpKeyName As String, _
>    <MarshalAs(UnmanagedType.LPTStr)> ByVal lpDefault As String, _
>    <MarshalAs(UnmanagedType.LPTStr)> ByVal lpReturnedString As String, _
>    ByVal nSize As Integer, _
>    <MarshalAs(UnmanagedType.LPTStr)> ByVal iniFilename As String) As Integer
>End Function

の宣言ですが,値が返されるlpReturnedStringはString型よりもStringBuilder型の方が
よいと思います。String型はある意味定数で,値の変更を許しません。String型の
変数の内容を変える場合,確か内部的には新しいString型の変数が作成され,結果が
そこにコピーされて戻されるはずです。一方StringBuffer型は内容を変更できます。
バッファを用意してそこの内容を書き換えさせる場合にはStringBuffer型の方がふさわしい
といえます。
最後にlpReturnedString.ToStringとすればよいはずです。

それでもエラーになるようでしたらDebug.WriteLine(String.Format ""{0}"",""{1}""",b,c)
を仕込んでどんな文字列が渡されているか確かめたらよいと思います。そこでエラーが
出る以上,b と c の中身が異なっていることは間違いないと思います。

文字列が同じだとしたらエンコードが違うかもしれません。もしかしてパスワードに2バイト
文字とか使えたりするんですか?(調べないで書いてます。すみません。)

[ツリー表示へ]
タイトルRe^2: パスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3182
投稿日: 2006/02/24(Fri) 23:23
投稿者とみぃだ
朝早くからありがとうございます。
仕事が遅くなってしまって返事が遅れました。

> 値が返されるlpReturnedStringはString型よりもStringBuilder型の方が
> よいと思います。String型はある意味定数で,値の変更を許しません。String型の
> 変数の内容を変える場合,確か内部的には新しいString型の変数が作成され,結果が
> そこにコピーされて戻されるはずです。一方StringBuffer型は内容を変更できます。
> バッファを用意してそこの内容を書き換えさせる場合にはStringBuffer型の方がふさわしい
> といえます。
> 最後にlpReturnedString.ToStringとすればよいはずです。

<MarshalAs(UnmanagedType.LPTStr)> ByVal lpReturnedString As String, _
を <MarshalAs(UnmanagedType.LPTStr)> ByVal lpReturnedString.tostring As String, _とか
<MarshalAs(UnmanagedType.LPTStr)> ByVal lpReturnedString As StringBuffer, _とか
してもだめですね。

>
> それでもエラーになるようでしたらDebug.WriteLine(String.Format ""{0}""
;,""{1}""",b,c)
> を仕込んでどんな文字列が渡されているか確かめたらよいと思います。そこでエラーが
> 出る以上,b と c の中身が異なっていることは間違いないと思います。

ソースを埋め込んだら青色破線がでましたが・・・。

> 文字列が同じだとしたらエンコードが違うかもしれません。もしかしてパスワードに2バイト
> 文字とか使えたりするんですか?(調べないで書いてます。すみません。)

パスワードは半角英文字だけの予定です。

よろしければもう一度おしえてください。

[ツリー表示へ]
タイトルRe: パスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3175
投稿日: 2006/02/24(Fri) 09:40
投稿者GOD
[OSのVer]:Windows    [VBのVer]:VB.NET  
>         Dim strBuffer As String = New String(CChar(" "), 256)
> 省略
>         c = strBuffer
> 省略
>         'データベースのパスワード
>         CnAccess &= "Jet OLEDB:Database Password=" & CStr(c) & &quot;
> ;"
cが256byte分の領域を持っているからじゃないですか?(CStr しても Chr(0) 以降の文字列も返
していそう)
デバッグしても気づきにくいのは Chr(0) が文字列中に含まれているとそこまでしか表示してくれ
ないみたい。

ちょっと実験:
        Dim a As String
        Dim b As String
        a = "123" & Chr(0) & "   "
        Debug.Print(a)
        b = CStr(a) & "hoge"
        Debug.Print(b)

Debug.Print(b)としてもイミディエイトウィンドウに "hoge" が表示されない。
#文字列代入後、bをウォッチしてみると分かると思いますが、"の後ろ側がないはずです。
(文字列は通常""で囲まれている。)

[ツリー表示へ]
タイトルRe^2: パスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3184
投稿日: 2006/02/24(Fri) 23:32
投稿者とみぃだ
朝早くありがとうございます。

Debug.Print(b)だとエラーだったので、
    Dim a As String
        Dim b As String
        a = "123" & Chr(0) & " "
        Debug.WriteLine(a)
        b = CStr(a) & "hoge"
        Debug.WriteLine(b)
でやりましたが
123123でしたね・・・。

[ツリー表示へ]
タイトルRe: パスワードがかかったAccessにiniファイルからのデータを持ってくるとエラー
記事No3194
投稿日: 2006/02/25(Sat) 15:42
投稿者とみぃだ
iniファイルで無く、テキストボックスを読み込むやり方で代替しました。
YASさん GODさん アドバイス真にありがとうございました。

[ツリー表示へ]