3

「パスに不正な文字があります」という例外が発生していますが、文字列に不正な文字は含まれていないようです。

この問題を解決するにはどうすればよいですか?:

Private Sub Button_Send_Click(sender As Object, e As EventArgs) Handles Button_Send.Click

    For Each item As ListViewItem In ListView1.Items

        Clipboard.SetText(item.SubItems(0).Text)
        ' First I copy the text to the clipboard to ensure in Explorer.exe if all is ok and also ifthe file exists... and yes, it exists.
        ' The example text is this:
        ' C:\Electro\Nueva carpeta\Aggresivnes - Dance Or Die.mp3
        ' (without any quotes)


        ' ...But this throws an "not exists":
        If IO.File.Exists(item.SubItems(0).Text) Then MsgBox("exists") Else MsgBox("not exists")


        ' And here throws an exception of "*Illegal characters in path*" :
        Dim File As New IO.FileInfo(item.SubItems(0).Text)

    Next

End Su

更新 2

私は自分のコードで間違いを犯しました。問題がない場合は true を返し、問題が存在する場合は false を返すことに気づいていないので、古い更新を削除してこれを編集することにしました:

@ Jim Mischelの回答指示に従って、ファイル名の変換または文字列変数の何かに無効な文字が含まれているかどうかを(再度)確認する機能を実行しました。

#Region " Validate Windows FileName "

    ' [ Validate Windows FileName Function ]
    '
    ' By Elektro H@cker
    '
    ' Examples :
    ' MsgBox(Validate_Windows_FileName("C:\Test.txt"))  ' Result: True
    ' MsgBox(Validate_Windows_FileName("C:\Te|st.txt")) ' Result: False

    Private Function Validate_Windows_FileName(ByRef FileName As String)
        Dim Directory As String = Nothing
        Dim File As String = Nothing

        Try
            Directory = FileName.Substring(0, FileName.LastIndexOf("\")) & "\"
            File = FileName.Split("\").Last
        Catch
            If Directory Is Nothing Then File = FileName
        End Try

        If Directory Is Nothing AndAlso File Is Nothing Then Return False

        If Not Directory Is Nothing Then
            For Each InvalidCharacter As Char In IO.Path.GetInvalidPathChars
                If Directory.Contains(InvalidCharacter) Then
                    ' MsgBox(InvalidCharacter)
                    Return False
                End If
            Next
        End If

        If Not File Is Nothing Then
            For Each InvalidCharacter As Char In IO.Path.GetInvalidFileNameChars
                If File.Contains(InvalidCharacter) Then
                    ' MsgBox(InvalidCharacter)
                    Return False
                End If
            Next
        End If

        Return True ' FileName is valid
    End Function

#End Region

さて...今度は関数を使用して、フルパス/ファイル名と結果が「false」であることを再度確認します。これは、文字列に無効な文字が含まれていることを意味し、その文字は「スペース」のようなものです。

 MsgBox(Validate_Windows_FileName(item.SubItems(0).Text))

これを解決する方法がわかりません。

全クラス見たい方はこちら

Public Class Main

    Dim WinAmpTitle As String = String.Empty
    Dim WinAmpFile As String = String.Empty

    Dim Sendto_Path As String

    Dim WithEvents WinAmp_Timer As New Timer With {.Interval = 25, .Enabled = True}

    Private Sub Main_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Nothing to do here at the momento...
    End Sub

    Private Sub WinAmp_Timer_Tick(sender As Object, e As EventArgs) Handles WinAmp_Timer.Tick

        WinAmpTitle = WinAmpInfo.Title
        WinAmpFile = WinAmpInfo.FileName

        If Not TextBox_Title.Text = WinAmpTitle Then TextBox_Title.Text = WinAmpTitle

        If Not TextBox_Filename.Text = WinAmpFile Then TextBox_Filename.Text = WinAmpFile

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button_Copy.Click
        Dim item = ListView1.Items.Add(WinAmpFile)
        item.SubItems.Add(ComboBox_Sendto.Text)

    End Sub

    Private Sub Button_Send_Click(sender As Object, e As EventArgs) Handles Button_Send.Click

        For Each item As ListViewItem In ListView1.Items


            Clipboard.SetText(item.SubItems(0).Text)
            ' First I copy the text to the clipboard to ensure in Explorer.exe if the file exists... and yes, it exists.
            ' The example text is this:
            ' C:\Electro\Nueva carpeta\Aggresivnes - Dance Or Die.mp3
            ' (without any quotes)


            ' ...But this throws an "not exists":
            If IO.File.Exists(item.SubItems(0).Text) Then MsgBox("exists") Else MsgBox("not exists")

            MsgBox(Validate_Windows_FileName(item.SubItems(0).Text)) ' Result: False (any invalid character)


            ' Here, an exception: "Illegal characters in path" :
            Dim File As New IO.FileInfo(item.SubItems(0).Text)

            ' If item.SubItems(1).Text.ToLower = "electro" Then Sendto_Path = "C:\Electro"
            ' If item.SubItems(1).Text.ToLower = "techno" Then Sendto_Path = "C:\Techno"
            ' If item.SubItems(1).Text.ToLower = "trance" Then Sendto_Path = "C:\Trance"

            'IO.File.Copy(File.FullName, IO.Path.Combine(Sendto_Path, File.Name))

        Next

    End Sub


#Region " Validate Windows FileName "

    ' [ Validate Windows FileName Function ]
    '
    ' By Elektro H@cker
    '
    ' Examples :
    ' MsgBox(Validate_Windows_FileName("C:\Test.txt"))  ' Result: True
    ' MsgBox(Validate_Windows_FileName("C:\Te|st.txt")) ' Result: False

    Private Function Validate_Windows_FileName(ByRef FileName As String)
        Dim Directory As String = Nothing
        Dim File As String = Nothing

        Try
            Directory = FileName.Substring(0, FileName.LastIndexOf("\")) & "\"
            File = FileName.Split("\").Last
        Catch
            If Directory Is Nothing Then File = FileName
        End Try

        If Directory Is Nothing AndAlso File Is Nothing Then Return False

        If Not Directory Is Nothing Then
            For Each InvalidCharacter As Char In IO.Path.GetInvalidPathChars
                If Directory.Contains(InvalidCharacter) Then
                    ' MsgBox(InvalidCharacter)
                    Return False
                End If
            Next
        End If

        If Not File Is Nothing Then
            For Each InvalidCharacter As Char In IO.Path.GetInvalidFileNameChars
                If File.Contains(InvalidCharacter) Then
                    ' MsgBox(InvalidCharacter)
                    Return False
                End If
            Next
        End If

        Return True ' FileName is valid
    End Function

#End Region

End Class

...パート2(あまり重要ではないと思います):

#Region " WinAmp Info "

' [ WinAmp Info Functions ]
'
' // By Elektro H@cker
'
' Examples:
' MsgBox(WinAmpInfo.Title)    ' Result: Artist - Title
' MsgBox(WinAmpInfo.FileName) ' Result: C:\Title.ext

Public Class WinAmpInfo

    Private Const WinampClassName As String = "Winamp v1.x"

    Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    Private Declare Auto Function GetWindowText Lib "user32" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As Integer) As Integer
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, ByRef lpdwProcessId As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Long, ByRef lpBuffer As Byte, ByVal nSize As Long, ByRef lpNumberOfBytesRead As Long) As Long
    Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

    Public Shared Function Title() As String

        Dim hwnd As IntPtr = FindWindow(WinampClassName, vbNullString)

        Dim lpText As String = String.Empty
        Dim strTitle As String = String.Empty

        Dim intLength As Integer = 0
        Dim intName As Integer = 0
        Dim intLeft As Integer = 0
        Dim intRight As Integer = 0
        Dim intDot As Integer = 0

        If hwnd.Equals(IntPtr.Zero) Then Return "WinAmp is not running"

        lpText = New String(Chr(0), 100)
        intLength = GetWindowText(hwnd, lpText, lpText.Length)

        If (intLength <= 0) _
        OrElse (intLength > lpText.Length) _
        Then Return "Unknown"

        strTitle = lpText.Substring(0, intLength)
        intName = strTitle.IndexOf(" - Winamp")
        intLeft = strTitle.IndexOf("[")
        intRight = strTitle.IndexOf("]")

        If (intName >= 0) _
        AndAlso (intLeft >= 0) _
        AndAlso (intName < intLeft) _
        AndAlso (intRight >= 0) _
        AndAlso (intLeft + 1 < intRight) _
        Then Return strTitle.Substring(intLeft + 1, intRight - intLeft - 1)

        If (strTitle.EndsWith(" - Winamp")) _
        AndAlso (strTitle.Length > " - Winamp".Length) _
        Then strTitle = strTitle.Substring(0, strTitle.Length - " - Winamp".Length)

        intDot = strTitle.IndexOf(".")

        If (intDot > 0) _
        AndAlso (IsNumeric(strTitle.Substring(0, intDot))) _
        Then strTitle = strTitle.Remove(0, intDot + 1)

        Return strTitle.Trim

    End Function

    Public Shared Function FileName() As String

        Dim lp As Long, lpWinamp As Long, iIndex As Long, PID As Long, bRet As Long, dwRead As Long
        Dim Buffer(260) As Byte

        Dim hWndWinamp As IntPtr = FindWindow(WinampClassName, vbNullString)
        If hWndWinamp = 0 Then Return Nothing

        iIndex = SendMessage(hWndWinamp, &H400, 0, 125)

        lp = SendMessage(hWndWinamp, &H400, iIndex, 211)
        If lp = 0 Then Return Nothing

        Call GetWindowThreadProcessId(hWndWinamp, PID)

        lpWinamp = OpenProcess(&H10, 0, PID)
        If lpWinamp = 0 Then Return Nothing

        bRet = ReadProcessMemory(lpWinamp, lp, Buffer(0), 260, dwRead)

        Call CloseHandle(lpWinamp)

        Return System.Text.UnicodeEncoding.Default.GetString(Buffer)

    End Function

End Class

#End Region

更新 3:

私の新しい試み...すべてが説明されました。無効な文字が表示され、理由がわかりません...

Private Sub Button_Send_Click(sender As Object, e As EventArgs) Handles Button_Send.Click

    For Each item As ListViewItem In ListView1.Items

        Dim filenameee As String = item.SubItems(0).Text.Trim ' The trim is...fuck, is just 'cause I don't know what more try to get a valid path...)

        Clipboard.SetText(filenameee) ' result: "C:\Test.mp3" (Without any double quote of course)

        ' ...but this launchs an "not exists" msgbox with the filename "C:\Test.mp3":
        If IO.File.Exists(filenameee) Then MsgBox("exists") Else MsgBox("not exists")

        MsgBox(filenameee) ' this showns "C:\Test.mp3" /without double quotes)
        MsgBox("filename is vlaid?:" & Validate_Windows_FileName(filenameee)) ' Result: False (path is invalid) (REALLY!!!!??? WTF)


        ' Here, an exception: "Illegal characters in path" :
        Dim File As New IO.FileInfo(item.SubItems(0).Text) ' (REALLY!!!!???)

    Next

End Sub

更新 4:

写真:

アプリケーション自体:

ここに画像の説明を入力

(C:\Test.mp3 は filenameee 変数テキストです)

Io.file.exists コンプロベーション:

ここに画像の説明を入力

filenameee 変数の内容を表示する:

ここに画像の説明を入力

ファイル名が有効かどうかを確認しています:

ここに画像の説明を入力

filenameee に想定される不正な文字を表示する:

ここに画像の説明を入力

(空間?)

例外 :

ここに画像の説明を入力

更新 5

UPDATE Nº 2 に投稿したwinampクラスの「filename()」関数に、本当の問題があると思います。

Return System.Text.UnicodeEncoding.Default.GetString(Buffer)

画像でわかるように有効な文字列を返すように見えますが、「Autos」では大きな文字列のように見えるためです。

ここに画像の説明を入力

誰かがこれを修正するのを手伝ってくれるならお願いします...

ありがとう。

更新 6:

これは機能しています。For ループの使用を回避するために、これを改善する方法または何かが存在するかどうかを知りたいです。

Dim i As Int32 = 0
For Each by In System.Text.Encoding.Default.GetString(Buffer)
    If by = Nothing Then Exit For 'MsgBox(i)
    i += 1
Next

Return System.Text.Encoding.Default.GetString(Buffer, 0, i)
4

3 に答える 3

3

編集 あなたのコメントとファイルパスについて私が見ることができるものから(スクリーンショットを拡大する必要があったため)、スペースがあります。

'I've left the trim here.
 Dim filenameee As String = item.SubItems(0).Text.Trim
'To remove remainding whitespace.
 filenamee = filenamee.Replace(" ", "")

'File.Exists(file_path) - item.subitem(0).text needs to show a valid path file.

  If IO.File.Exists(filenameee) Then MsgBox("exists") 

  Dim File As New IO.FileInfo(item.SubItems(0).Text)

Else MsgBox("not exists")

ファイル パス MSDN :

http://msdn.microsoft.com/en-us/library/783hax6d(v=VS.80).aspx

はい、フル パスが返されない場合は、バッファを設定し、必要な最小バイト数を受け入れるように読み取る必要があります。これは他の回答ですでに対処されているため、繰り返したくありませんが、リンクを提供しました。

IO ストリーム読み取り MSDN:

http://msdn.microsoft.com/en-US/library/system.io.stream.read(v=VS.80).aspx

于 2013-06-27T17:47:12.627 に答える