tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルINI ファイルへの書き込み及び読み込み
記事No1030
投稿日: 2004/08/16(Mon) 16:05
投稿者ADV
[OSのVer]:Windows    [VBのVer]:VB.NET  
Tips の「INI ファイルへの書き込み及び読み込み」
をやってみたのですが、どうもうまくできません


同フォルダにCU.iniをおいても何も書かれません
どうしたらよいのでしょうか

[ツリー表示へ]
タイトルRe: INI ファイルへの書き込み及び読み込み
記事No1031
投稿日: 2004/08/16(Mon) 18:40
投稿者花ちゃん
>     Private IniFileName As String = "CU.ini"   'INIファイルのパス
> 同フォルダにCU.iniをおいても何も書かれません

上記パスは同フォルダではありません。
ドライブ名 フォルダー名をキチンと指定して下さい。

"CU.ini" = Windows フォルダ内に書かれるようです。
CU.ini をエクスプローラで検索して見てください。


"c:CU.ini" = カレントフォルダー(但し C ドライブの場合)
Application.StartupPath & "\CU.ini"
のようにドライブ名 フォルダー名をキチンと指定して下さい。
  

[ツリー表示へ]
タイトルRe^2: INI ファイルへの書き込み及び読み込み
記事No1032
投稿日: 2004/08/16(Mon) 21:30
投稿者ADV
> ドライブ名 フォルダー名をキチンと指定して下さい。
え!?知りませんでした!
はい。WINNTフォルダにあります!
これは.NETだからでしょうか?
前(VB5)は同フォルダに指定されていたので・・・

カレントフォルダの指定は
Application.StartupPathと
System.IO.Directory.GetCurrentDirectory
ではちがいがありますか?

わかりやすい回答をどうもありがとうございました!

[ツリー表示へ]
タイトルRe^3: INI ファイルへの書き込み及び読み込み
記事No1033
投稿日: 2004/08/16(Mon) 21:56
投稿者花ちゃん
> カレントフォルダの指定は
> Application.StartupPathと
> System.IO.Directory.GetCurrentDirectory
> ではちがいがありますか?

下記を実行すれば解ります。
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles Button1.Click
        System.IO.Directory.SetCurrentDirectory("c:\")

        Debug.WriteLine(Application.StartupPath)
        Debug.WriteLine(System.IO.Directory.GetCurrentDirectory)
    End Sub

[ツリー表示へ]
タイトルRe^4: INI ファイルへの書き込み及び読み込み
記事No1034
投稿日: 2004/08/16(Mon) 22:22
投稿者ADV
つまり、System・・・のほうは変更がきくということですね?

しかし、
INI読み書き共通部で
Public IniFileName As String = "C\CU.ini"
ときじゅつしたさいはだいじょうぶなのですが
Public IniFileName As String = Application.StartupPath & "\CU.ini"
とすると".ini"の部分が文字化けしてしまいます

としてみたところわかったのですが、どうもWritePrivateProfileStringでIniFileNameが変わってしま
うみた
いなのです。
実行すると
[Form1Text]
Text=Form1
とかかれたCU.iniと

[Form1Point]
Xpos=176
Ypos=176
[Form1Size]
Width=418
Height=338
とかかれた拡張子なしCU

が出力されてしまいます

[ツリー表示へ]
タイトルRe^5: INI ファイルへの書き込み及び読み込み
記事No1035
投稿日: 2004/08/16(Mon) 23:10
投稿者花ちゃん
> Public IniFileName As String = Application.StartupPath & "\CU.ini"
> とすると".ini"の部分が文字化けしてしまいます

では、Debug.WriteLine(IniFileName) を入れてどの時点で変わっているのか
調べて見て下さい。
たとへば下記のように起動直後に調べても文字化けしているのですか?

    Public IniFileName As String = Application.StartupPath & "\CU.ini"
    Private Sub Form1_Load(ByVal sender As System.Object, _
            ByVal e As System.EventArgs) Handles MyBase.Load
        Debug.WriteLine(IniFileName)
    End Sub

ファイル名が違ったファイル名になっているから2種類のファイルができるのです。

[ツリー表示へ]
タイトルRe^5: INI ファイルへの書き込み及び読み込み
記事No1036
投稿日: 2004/08/16(Mon) 23:26
投稿者よろずや
> としてみたところわかったのですが、どうもWritePrivateProfileStringでIniFileNameが変わって
> しまうみたいなのです。

VB.NET で API 呼び出しは、大分変わったようですね。
こちらが参考になると思います。
hhttp://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet28/vb6tonet28_03.html

[ツリー表示へ]
タイトルRe^5: INI ファイルへの書き込み及び読み込み
記事No1037
投稿日: 2004/08/17(Tue) 00:14
投稿者花ちゃん
書込み部分の下記のところを修正しておいて下さい。
誤り Ret = WritePrivateProfileString("Form1Text", "Text", Me.Text, IniFileName)
正解 Ret = WritePrivateProfileString("Form1Text", "Text", Me.Text.ToString, IniFileName)

今回の問題と関係ないかもしれませんが。

尚、 文字化けする OS は何をご使用ですか?
   フォルダー名等に漢字等の全角文字をご使用ですか?
   どこでファイル名が変わっていましたか?

今回の原因とAPIの宣言方法とは直接関係ないと思われますのでまず、どこでファイル名が
 変わっているのかを確認して報告して下さい。

 多分、パスが長いか(256バイト以上)パスに漢字が混じっているからだと思うのですが?

[ツリー表示へ]
タイトルRe^5: INI ファイルへの読み書き
記事No1039
投稿日: 2004/08/18(Wed) 13:17
投稿者よねKEN
参照先http://www5b.biglobe.ne.jp/~yone-ken/
> としてみたところわかったのですが、どうもWritePrivateProfileStringでIniFileNameが変わって


> うみた
> いなのです。
> 実行すると
> [Form1Text]
> Text=Form1
> とかかれたCU.iniと
>
> [Form1Point]
> Xpos=176
> Ypos=176
> [Form1Size]
> Width=418
> Height=338
> とかかれた拡張子なしCU
>
> が出力されてしまいます

IniFileNameに指定されているパスに全角が含まれていませんか?
(CU.ini→CUと変化している点から見ると全角が4文字含まれているような気がします)
APIでString型を扱う場合、本来のC言語での定義に従ったAPI宣言をしないと
引数に渡したデータが破壊されてしまうようです。1回目のWritePrivateProfileString関数の
呼び出しで変数IniFileNameの中身が破壊され、2回目に指定するパスは異なったものになります。
#過去に別所で同様の問題があがっていたので実験したことがあります。

手前味噌ですが、下記にAPIの宣言方法とGetPrivateProfileString関数で日本語パスを扱った
場合の問題に対する実験をした情報を載せています。(WritePrivateProfileStringでも考え方は同じ)

[特集6] GetPrivateProfileStringにみるAPIの使用方法
hhttp://www5b.biglobe.ne.jp/~yone-ken/VBNET/special/sp06_GetPrivateProfileString.html
[Ref2] GetPrivateProfileString関数の様々な宣言法によるWin2000、Win98での実行結果の成否
hhttp://www5b.biglobe.ne.jp/~yone-ken/VBNET/Reference/ref2_GetPrivateProfileString.html

[ツリー表示へ]
タイトルRe^6: INI ファイルへの読み書き
記事No1041
投稿日: 2004/08/18(Wed) 14:58
投稿者花ちゃん
> 引数に渡したデータが破壊されてしまうようです。1回目のWritePrivateProfileString関数の
> 呼び出しで変数IniFileNameの中身が破壊され、2回目に指定するパスは異なったものになります。
> #過去に別所で同様の問題があがっていたので実験したことがあります。

フォローありがとうございます。
テストして見たら上記現象が確認できました。
私も理解不足なのですが、今回の事は、通常のAPI関数でも同様の現象はおきるのでしょうか?

取り敢えず、下記のように宣言を変えて試して見たら正常に読み書きができました。
UPしてあるのも修正しておきます。

  Imports System.Runtime.InteropServices

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

    <DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
    Public Shared Function WritePrivateProfileString _
        (ByVal lpApplicationName As String, _
         ByVal lpKeyName As String, _
         ByVal lpString As String, _
         ByVal lpFileName As String) As Integer
    End Function

    <DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
    Public Shared Function GetPrivateProfileInt _
        (ByVal lpApplicationName As String, _
         ByVal lpKeyName As String, _
         ByVal nDefault As Integer, _
         ByVal lpFileName As String) As Integer
    End Function

[ツリー表示へ]
タイトルRe^7: INI ファイルへの読み書き
記事No1042
投稿日: 2004/08/18(Wed) 16:49
投稿者ADV
質問しておいて、返信が遅れてしまって申し訳ありません。
私には難しすぎて何を仰っているのかほとんどチンプンカンプンなのですが・・・(笑)、
無事、うまく動作できました。
花ちゃん様、よねKEN様、よろずや様
どうもありがとうございました!


IniFileNameは半角でしたが、よねKEN様、花ちゃん様の言うとおり、
パスに4文字2バイト文字が入っていました(管理者名の部に)

[ツリー表示へ]
タイトルRe^7: APIの宣言方法
記事No1043
投稿日: 2004/08/18(Wed) 20:01
投稿者よねKEN
参照先http://www5b.biglobe.ne.jp/~yone-ken/
> > 引数に渡したデータが破壊されてしまうようです。1回目のWritePrivateProfileString関数の
> > 呼び出しで変数IniFileNameの中身が破壊され、2回目に指定するパスは異なったものになり
ます。
> > #過去に別所で同様の問題があがっていたので実験したことがあります。
>
> フォローありがとうございます。
> テストして見たら上記現象が確認できました。
> 私も理解不足なのですが、今回の事は、通常のAPI関数でも同様の現象はおきるのでしょうか?

以下、私の個人的な予想で、確証はまったくないです。

他のAPI関数でも同様の現象は起きると予想してます。
例えば、GetPrivateProfileString関数の第四引数lpReturnedStringは結果の文字列を
受け取る必要があり、そのためにはStringBuilderで受けないといけませんが、
VBではString型で受けられるようになっています。
.NET FrameworkのString型の仕様からこれはあり得ない動作ですので、
VBが過去のAPI呼び出しとの互換性のためにString型で受けても大丈夫なように
何か細工をしていると考えられます。

で、おそらく関数に渡した文字列を再び引き取るような動作になっていて、
このときのUNICODE←→ANSIの変換あたりで、文字切れが発生しているのかな?
と想像しています。ま、あくまで想像ですけど。

[ツリー表示へ]
タイトルRe^8: APIの宣言方法
記事No1044
投稿日: 2004/08/18(Wed) 21:42
投稿者花ちゃん
レスありがとうございます。
今まで色々試してはいたのですが、特に問題が見受けらなかったのとMSDNの方の資料等にも
hhttp://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vbcon/html/vbconupgraderecommendationadjustdatatypesforwin32apis.asp
特にその辺の事は書いてないようなので、使い慣れた方法で宣言していたのですが、問題が
起きる可能性があるなら、MarshalAs属性を使用した方法なりに変更するようにします。

又、お気づきの点等ありましたら、ご指導の程お願いします。
ありがとうございました。

[ツリー表示へ]
タイトルRe^9: APIの宣言方法
記事No1053
投稿日: 2004/08/24(Tue) 15:51
投稿者ken
参照先http://www.atmarkit.co.jp/fdotnet/dotnettips/039inifile/inifile.html
ここにそのまんま載ってました。(^^)

[ツリー表示へ]
タイトルRe^10: APIの宣言方法
記事No1385
投稿日: 2005/02/10(Thu) 14:02
投稿者てんま
すっごい遅レスですが参考までに。

Ret = WritePrivateProfileString("Form1Text", "Text", Me.Text.ToString, In
iFileName)

Ret = WritePrivateProfileString("Form1Text", "Text", Me.Text.ToString, (I
niFileName))
にすることで、変数が書き換わるのを防げます。

[ツリー表示へ]