- PR -

漢字のフォルダパスとファイルパスがつながらない。

投稿者投稿内容
えんぴつ
常連さん
会議室デビュー日: 2006/12/27
投稿数: 23
投稿日時: 2007-01-29 10:43
こんにちわ。よろしくおねがいします。
windows XP Professional
SP2
VS2005 VBを使用して、漢字の入ったフォルダパスをIniファイルより取得後にファイル名とつなげたいのですがうまくいきません。Iniファイルから取得はできています。

iniファイル内に入っているフォルダパス
C:\\\\図ファイル\\\\
iniファイル内から取得したフォルダパスの変数
dim strTiffFileFolder as string
ファイル名の変数
filename
連結後のパスの変数
path
として、
path = strTiffFileFolder & filename
でもpath 内は"C:\\\\図ファイル\\\\" となってしまい、連結されていません。
Dim data As String() = {strTiffFileFolder, filename}
path = String.Join(Nothing, data)
としても、
path = System.IO.Path.Combine(strTiffFileFolder, filename)
としても無理でした。
そのまま処理すると、エラーメッセージとして
「パスに無効な文字が含まれています」と表示されます。
しかし、
path = "C:\\\\図ファイル" & filename
とした場合はエラーは出ずに正常に動作します。
ちなみの、
path =filename & strTiffFileFolder
とすると、二つのパスはつながります。

なにかよい方法はないのでしょうか?おねがいします。
Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2007-01-29 10:54
問題は連結部分ではなく、INIファイルの読込部分にありそうな気がします。
INIファイルの文字列取得部分のコードを載せてもらえませんでしょうか?
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-01-29 11:06
普通に考えるとありえないような気がするのですが…
デバッガでの確認はお済みですか?

path = strTiffFileFolder & filename

この文を実行する直前で止めてみて、
変数「strTiffFileFolder」に「C:\\\\図ファイル\\\\」
変数「filename」に正しいファイル名が
それぞれ格納されていることを確認した上で、
上記の文を実行後にpathに
「C:\\\\図ファイル\\\\」と代入されてしまうのでしょうか?

また、strTiffFileFolder, filename, pathの変数は全て
String型で間違いないですか?
えんぴつ
常連さん
会議室デビュー日: 2006/12/27
投稿数: 23
投稿日時: 2007-01-29 11:24
Blueさん返信ありがとうざいます。
コードは、

・Iniファイル<inifile.ini> の内容
[SYSTEM]
ServerDataDir=C:\\\\\\\\図ファイル\\\\\\\\
-----------------------------
・コード
'API関数
Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" (ByVal IpApplicationName As String, ByVal IpKeyName As String, ByVal IpDefault As String, ByVal IpReturnedString As String, ByVal nSize As Integer, ByVal IpFileName As String) As Integer

Public Function GetIniData() As Boolean
Dim intLength As Integer
Dim strReturnValue As String = Space(100)

intLength = GetPrivateProfileString("SYSTEM", "ServerDataDir",nothing, _
strReturnValue, strReturnValue.Length, "inifile.ini")
rctIni.strSysSeverDir = strReturnValue.Substring(0, intLength)
Dim strTiffFileFolder As String = strServerDataDir.ToString
End Function

です。実のところ、Ini取得関数として先輩からコピペで教えてもらい使っているものなので、API関数の部分はよく意味を理解していません。すみません。

えんぴつ
常連さん
会議室デビュー日: 2006/12/27
投稿数: 23
投稿日時: 2007-01-29 11:34
KIさん、返信ありがとうございます。行き違いで確認前に返信してしまいました。すみません。


引用:
デバッガでの確認はお済みですか?


はい。
path = strTiffFileFolder & filename
の直前でstrTiffFileFolder 、filename ともに正しい値が入っています。
その後のpathにはstrTiffFileFolder のみが入っている状態です。

引用:
また、strTiffFileFolder, filename, pathの変数は全て
String型で間違いないですか?


String型で間違いありません。

Blue
大ベテラン
会議室デビュー日: 2005/09/12
投稿数: 230
お住まい・勤務地: 知っている人は知っている
投稿日時: 2007-01-29 11:38
おそらく
>rctIni.strSysSeverDir = strReturnValue.Substring(0, intLength)
が不味そうです。

GetPrivateProfileStringAは文字数ではなくCP932(Shift_JISコード)でのバイト数を返します。
ところが、VB側でString型で受け取ると、(String型のデフォルトである)Unicodeに変換されます。
なので、全角文字を含む場合 Unicodeでの文字数とCP932でのバイト数が一致しないので
終端文字である"\0"を含んだ文字列になってしまっているのでしょう。
(半角文字(ASCII)であれば Unicode文字数=CP932バイト数なので問題なかった)

ですので、
>rctIni.strSysSeverDir = strReturnValue.Substring(0, intLength)
を再考(VB6のときはvbNullCharを探して文字列を分割したけど)するか、
>GetPrivateProfileStringA
をUnicodeでやり取りする GetPrivateProfileStringW にして
引数の指定には Marshal.〜 を指定して、Unicodeでやり取りするように変更するかどちらかでしょう。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-01-29 11:50
VBなのに 円マーク をエスケープしているから


System.IO.Path.Combine
_________________
KI
大ベテラン
会議室デビュー日: 2007/01/10
投稿数: 239
投稿日時: 2007-01-29 11:57
直接の原因かわかりませんが、
その関数にいろいろと変な所があるように見えます。

(1) 戻り値のBooleanって、どこでも設定していないように見えます。(常に既定値を返す?)

(2) 最後のローカル変数への代入文はいらない(どこでも使われないので)と思います。

(3) APIの関数に文字列のバッファを渡すときはStringではなく、StringBuilderを使う必要があります。

未確認コードですが、こんな感じに直してみたらどうなりますか?
コード:


Public Declare Function GetPrivateProfileString Lib "kernel32" Alias "GetPrivateProfileStringA" _
(ByVal IpApplicationName As String, ByVal IpKeyName As String, ByVal IpDefault As String, _
ByVal IpReturnedString As StringBuilder, ByVal nSize As Integer, ByVal IpFileName As String) As Integer

Public Sub GetIniData()
Dim strReturnValue As New StringBuilder(100) '100で足りるのか?という問題は別にあります

GetPrivateProfileString("SYSTEM", "ServerDataDir", Nothing, _
strReturnValue, strReturnValue.Capacity, "inifile.ini")
rctIni.strSysSeverDir = strReturnValue.ToString()
End Sub



【追記】
よく考えたら抜粋だったのでしょうかね?
でしたら(1), (2)は気にしないでください。

[ メッセージ編集済み 編集者: KI 編集日時 2007-01-29 12:03 ]

スキルアップ/キャリアアップ(JOB@IT)