1

此 VB6 代码的目的是返回 WinAmp 的当前播放文件名(不是标题)。

这是我需要转换为 VBNET 的行:

Temp = StrConv(Buffer, vbUnicode)
strFileName = Left$(Temp, InStr(Temp, Chr$(0)) - 1)

Buffer 是 Byte 类型, temp 和 strFileName 是字符串类型。

也在这里:

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

...我已将“ByRef lpBuffer As Any”更改为“ByRef lpBuffer As Byte”(我认为我在那里做了正确的更改)

这是完整的代码:

Public Class Form1

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpszClassName As String, ByVal lpszWindowName As String) As Long
    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

    Private Const PROCESS_VM_READ As Long = &H10
    Private Const WM_USER As Long = &H400
    Private Const IPC_GETPLAYLISTFILE As Long = 211
    Private Const IPC_GETLISTPOS As Long = 125
    Private Const MAX_PATH As Long = 260
    Private hWndWinamp As Long

    Private Function GetWinampWindow() As Long
        GetWinampWindow = FindWindow("Winamp v1.x", vbNullString)
    End Function

    Public Function GetPlayingFileName() As String
        Dim strFileName As String
        Dim lp As Long, lpWinamp As Long
        Dim iIndex As Long
        Dim PID As Long
        Dim bRet As Long
        Dim dwRead As Long
        Dim Buffer(MAX_PATH) As Byte
        Dim Temp As String

        hWndWinamp = GetWinampWindow

        If hWndWinamp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

        iIndex = SendMessage(hWndWinamp, WM_USER, 0, IPC_GETLISTPOS)

        lp = SendMessage(hWndWinamp, WM_USER, iIndex, IPC_GETPLAYLISTFILE)

        If lp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

        Call GetWindowThreadProcessId(hWndWinamp, PID)

        lpWinamp = OpenProcess(PROCESS_VM_READ, 0, PID)

        If lpWinamp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

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

        Call CloseHandle(lpWinamp)

        Temp = StrConv(Buffer, vbUnicode)

        strFileName = Left$(Temp, InStr(Temp, Chr$(0)) - 1)

        GetPlayingFileName = strFileName

    End Function

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        MsgBox(GetPlayingFileName())
    End Sub

End Class

更新

这是遵循建议的更新代码,但在 try/catch 行中失败并出现错误:STARTINDEX CANNOT BE LESS THAN ZERO

Public Class Form1

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpszClassName As String, ByVal lpszWindowName As String) As Long
    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

    Private Const PROCESS_VM_READ As Long = &H10
    Private Const WM_USER As Long = &H400
    Private Const IPC_GETPLAYLISTFILE As Long = 211
    Private Const IPC_GETLISTPOS As Long = 125
    Private Const MAX_PATH As Long = 260
    Private hWndWinamp As Long

    Private Function GetWinampWindow() As Long
        GetWinampWindow = FindWindow("Winamp v1.x", vbNullString)
    End Function

    Public Function GetPlayingFileName() As String
        Dim strFileName As String
        Dim lp As Long, lpWinamp As Long
        Dim iIndex As Long
        Dim PID As Long
        Dim bRet As Long
        Dim dwRead As Long
        Dim Buffer(MAX_PATH) As Byte
        Dim Temp As String

        hWndWinamp = GetWinampWindow()

        If hWndWinamp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

        iIndex = SendMessage(hWndWinamp, WM_USER, 0, IPC_GETLISTPOS)

        lp = SendMessage(hWndWinamp, WM_USER, iIndex, IPC_GETPLAYLISTFILE)

        If lp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

        Call GetWindowThreadProcessId(hWndWinamp, PID)

        lpWinamp = OpenProcess(PROCESS_VM_READ, 0, PID)

        If lpWinamp = 0 Then
            GetPlayingFileName = ""
            Exit Function
        End If

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

        Call CloseHandle(lpWinamp)

        ' Original VB6 code
        'Temp = StrConv(Buffer, vbUnicode)
        'strFileName = Left$(Temp, InStr(Temp, Chr$(0)) - 1)

        Temp = System.Text.UnicodeEncoding.Unicode.GetString(Buffer)

        Try
            strFileName = Temp.Substring(Temp.IndexOf(CChar("0")) - 1)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

        GetPlayingFileName = strFileName

    End Function

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        MsgBox(GetPlayingFileName())
    End Sub

End Class
4

2 回答 2

4

在 VB.NET 中转换为 unicode 的等价物StrConv()Encoding.Convert

等价于String.Substring和toLeft()String.IndexOfInstr()

添加了对错误消息的回答,InStr() 从 1 开始索引,而不是 0 (VB.NET)。您需要对这些值进行调整。

于 2013-06-22T17:43:49.600 回答
1

记得导入 system.text

dim aux as UnicodeEncoding = new UnicodeEncoding
temp = aux.GetString(buffer)
strfilename = temp.substring(temp.indexof(cchar("0"))-1)
于 2013-06-22T17:49:55.900 回答