Member 14623989 Ответов: 3

Marshal.ptrtostringansi возвращает 1 символ


Я пытаюсь получить имя пользователя от sessionid.

Я скопировал vb.net подписи от pinvoke.net: WTSQuerySessionInformation (wtsapi32)[^] и pinvoke.net: WTSInfoClass (перечисления)[^]

Затем я использовал код C# для Как получить имя Пользователя по идентификатору сеанса со страницы WTSQuerySessionInformation в качестве ссылки, чтобы записать его в vb.net и придумали эту функцию:
Private Shared Function GetUserName(sessionID As Integer)
    Dim Buffer As IntPtr
    Dim Count As Integer
    Dim UserName As String
    WTSQuerySessionInformation(IntPtr.Zero, sessionID, WTS_INFO_CLASS.WTSUserName, Buffer, Count)
    UserName = Marshal.PtrToStringAnsi(Buffer)

    WTSFreeMemory(Buffer)
    Return UserName
End Function


Когда я запускаю его с идентификатором сеанса -1, Я получаю только первую букву имени пользователя. Если я изменю эту строку с Имя Пользователя = Маршал.PtrToStringAnsi(Буфер) к Имя Пользователя = Маршал.PtrToStringAuto(Буфер) тогда это работает. Что дает и как это исправить, чтобы использовать Marshal.PtrToStringAnsi?

Что я уже пробовал:

Код C# из pinvoke.net: WTSQuerySessionInformation (wtsapi32)[^] работать отлично.

3 Ответов

Рейтинг:
2

OriginalGriff

Ваш VB-код не похож на код, на который вы ссылаетесь.
Попробовать это:

Public Shared Function GetUsernameBySessionId(ByVal sessionId As Integer) As String
    Dim buffer As IntPtr
    Dim strLen As Integer
    Dim username = "SYSTEM"

    If WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, buffer, strLen) AndAlso strLen > 1 Then
        username = Marshal.PtrToStringAnsi(buffer)
        WTSFreeMemory(buffer)

        If WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSDomainName, buffer, strLen) AndAlso strLen > 1 Then
            username = Marshal.PtrToStringAnsi(buffer) & "\" & username
            WTSFreeMemory(buffer)
        End If
    End If

    Return username
End Function
Обратите внимание на вложенность If который выполняет вторую выборку из домена и заданное значение для username


Рейтинг:
14

JudyL_MD

Вы пробовали использовать Маршалла?Птртострингуни? Я не могу сказать, вызываете ли вы WTSQuerySessionInformationA или WTSQuerySessionInformationW. Посмотрите на память, на которую указывает этот IntPtr в вашем отладчике, чтобы увидеть, что вы на самом деле получаете обратно от вызова API.


Member 14623989

Похоже, тот, что был в статье, был для WTSQuerySessionInformationW. Используя Маршалла.Однако птртострингуни сработал. Я попытался посмотреть на память, на которую указывает этот IntPtr, но не вижу причины, почему. Я начал использовать VS только в этом месяце. Спасибо!

JudyL_MD

По крайней мере, для английского языка unicode будет отображаться в области памяти как узнаваемый символ ascii, за которым следует байт 0, затем еще один символ и еще один 0. Unicode-это 2-байтовая кодировка, и для тех языков, которые не нуждаются в верхнем байте, 2-й байт всегда равен 0. Это довольно своеобразно выглядит в памяти ... char 00 char 00 char 00

Рейтинг:
0

Member 14623989

@OriginalGriff - Извините, я слишком упростил его в своем коде выше. С кодом, который вы предоставили, я получаю то же самое. Я получаю 1 символ для доменного имени и 1 символ для своего имени пользователя. Я просто не понимаю, почему.