Получить путь и имя процесса по ProcessID - противоречивые результаты (VB6, VBA) - PullRequest
2 голосов
/ 13 июня 2011

Я использую код ниже, чтобы получить путь к файлу и имя для данного процесса.Я просто передаю ProcessID функции ExePathFromProcID, и она должна возвращать полный путь.Он перечисляет жесткие диски как устройства вместо использования букв дисков, но это не моя жалоба.Посмотрите на мой код, а затем посмотрите мою жалобу ниже.

Public Declare Function OpenProcess Lib "kernel32" ( _
    ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long

Public Declare Function GetProcessImageFileName Lib "psapi.dll" Alias "GetProcessImageFileNameA" _
    (ByVal hProcess As Long, _
    ByVal lpImageFileName As String, _
    ByVal nSize As Long) As Long

Public Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long     

Private Function ExePathFromProcID(idProc As Long) As String
    Const MAX_PATH = 260
    Const PROCESS_QUERY_INFORMATION = &H400
    Const PROCESS_VM_READ = &H10

    Dim sBuf As String
    Dim sChar As Long, l As Long, hProcess As Long
    sBuf = String$(MAX_PATH, Chr$(0))
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, idProc)
    If hProcess Then
        sChar = GetProcessImageFileName(hProcess, sBuf, MAX_PATH)
        If sChar Then
            sBuf = Left$(sBuf, sChar)
            ExePathFromProcID = sBuf
            Debug.Print sBuf
        End If
        CloseHandle hProcess
    End If
End Function

Моя жалоба состоит в том, что части более длинного пути процесса все равно будут отображаться при возврате более короткого пути, пока получен более длинный путьпервый.Вот пример:

Первый вызов (правильные результаты):
\ Device \ HarddiskVolume2 \ Программные файлы \ Portable Apps \ Notepad ++ Portable \ App \ Notepad ++ \ notepad ++. Exe

Второй вызов (неожиданные результаты):
\ Device \ HarddiskVolume2 \ Program Files \ Microsoft Office \ Office12 \ MSACCESS.EXE tepad ++ \ notepad ++. Exe

Обратите внимание на "tepad ++"\ notepad ++. exe "в конце результатов для второго вызова?Не обманывайтесь тем фактом, что он попадает на вторую строку.Все это часть одной и той же строки и все возвращается при втором вызове этой функции.

Есть идеи, почему моя функция возвращает это?Может показаться, что проблема глобальной строковой переменной не очищается, но я использую код почти так же, как я его опубликовал.Нет глобальных переменных.

Ответы [ 3 ]

1 голос
/ 13 июня 2011

Если вы посмотрите на возвращенный буфер, правильный путь фактически завершается нулем, например, если я передаю PID моего ultramon.exe:

\  D  e  v  i  c  e  \  H  a  r  d  d  i  s  k  V  o  l  u  m  e  1  \  P  r  o  g  r  a  m     F  i  l  e  s  \  U  l  t  r  a  M  o  n  \  U  l  t  r  a  M  o  n  .  e  x  e     x  .  e  x  e     3  9     3  8     5  C     5  6     4  2     3  6     2  E     4  5     5  8     4  5     0     6  1     7  2     4  E     6  F     7  4     6  9     6  
5C 44 65 76 69 63 65 5C 48 61 72 64 64 69 73 6B 56 6F 6C 75 6D 65 31 5C 50 72 6F 67 72 61 6D 20 46 69 6C 65 73 5C 55 6C 74 72 61 4D 6F 6E 5C 55 6C 74 72 61 4D 6F 6E 2E 65 78 65 0 78 2E 65 78 65 0 33 39 20 33 38 20 35 43 20 35 36 20 34 32 20 33 36 20 32 45 20 34 35 20 35 38 20 34 35 20 30 20 36 31 20 37 32 20 34 45 20 36 46 20 37 34 20 36 39 20 36 

В документах явно не говорится, что возвращаемое значение - это длина пути, а только длина скопированного буфера, который, кажется, не одно и то же; Если функция завершается успешно, возвращаемое значение указывает длину строки, скопированной в буфер .

Это означает, что вам нужно:

sBuf = Left$(sBuf, InStr(1, sBuf, ChrW$(0)))
1 голос
/ 13 июня 2011

Я думаю, что замена GetProcessImageFileName на QueryFullProcessImageName решит первую проблему.

Второй проблемой является просто GetProcessImageFileName, записывающая строку с нулевым символом в конце поверх другой.Я не эксперт по VB, но вы можете либо очистить буфер перед передачей его в GetProcessImageFileName, либо установить правильную длину после его возврата.

0 голосов
/ 13 июня 2011

Существует комментарий к документам относительно возвращаемого значения: http://msdn.microsoft.com/en-us/library/ms683217(v=vs.85).aspx#3

есть. возвращаемое значение не является длиной пути. Поэтому вы должны использовать какую-то функцию strlen.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...