Сбой P / Invoking CreateToolhelp32Snapshot в Compact Framework - PullRequest
1 голос
/ 26 декабря 2008

Эй, я делаю небольшое приложение для моего смартфона, используя Windows Mobile 6. Я пытаюсь получить все запущенные в настоящее время процессы, но метод CreateToolhelp32Snapshot всегда возвращает -1. Так что теперь я застрял. Я пытался получить ошибку при вызове метода GetLastError (), но этот метод возвращает значение 0. Вот фрагмент моего кода.

private const int TH32CS_SNAPPROCESS = 0x00000002;
[DllImport("toolhelp.dll")]
public static extern IntPtr CreateToolhelp32Snapshot(uint flags, 
                                                     uint processid);

public static Process[] GetProcesses()
    {
        ArrayList procList = new ArrayList();
        IntPtr handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

        if ((int)handle > 0)
        {
            try
            {
                PROCESSENTRY32 peCurr;
                PROCESSENTRY32 pe32 = new PROCESSENTRY32();

                // get byte array to pass to API call
                byte[] peBytes = pe32.ToByteArray();
                // get the first process
                int retval = Process32First(handle, peBytes);

Ответы [ 3 ]

3 голосов
/ 26 декабря 2008
  • Во-первых, проверка вашего дескриптора неверна. Обычно старший бит включен в дескриптор, поэтому при приведении к целому числу со знаком он выглядит как отрицательное число. Вы должны проверить, что это не NULL (0) или INVALID_HANDLE_VALUE (-1 / 0xffffffff).
  • Вы не должны вызывать GetLastError, а должны вызывать Marshal.GetLastWin32Error ()
  • Вы не установили атрибут SetLastError в объявлении P / Invoke. В C # по умолчанию используется значение false, в VB по умолчанию используется значение true.
  • Где ваша реализация PROCESS32? В документах четко указано , что элемент dwLength должен быть установлен до вызова, и здесь неясно, происходит ли это.

В качестве дополнительного примечания, Smart Device Framework OpenNETCF.ToolHelp Пространство имен имеет все это реализовано и работает (на случай, если вы не хотите изобретать велосипед).

1 голос
/ 22 сентября 2015

вместо

CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

использование

private const int TH32CS_SNAPNOHEAPS = 0x40000000;
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0);

По умолчанию CreateToolhelp32Snapshot пытается сделать снимок кучи, что может привести к ошибке нехватки памяти.

Нашел это в https://social.msdn.microsoft.com/Forums/en-US/e91d845d-d51e-45ad-8acf-737e832c20d0/createtoolhelp32snapshot-windows-mobile-5?forum=vssmartdevicesnative, и это решило мою проблему.

0 голосов
/ 26 декабря 2008

Если вы не видите действительной информации о «последней ошибке», возможно, вам может потребоваться добавить атрибут «SetLastError» в атрибут API DllImport ( ссылка на MSDN с примерами кода ). Согласно документации этого атрибута, вы должны установить SetLastError равным ...

... true, чтобы указать, что вызываемый будет call SetLastError; иначе ложно. По умолчанию установлено значение false.

Маршалерские вызовы времени выполнения GetLastError и кэширует значение вернулся, чтобы предотвратить его перезаписывается другими вызовами API. Вы можно получить код ошибки, позвонив GetLastWin32Error

Что касается сбоя API, который вы видите, я не вижу ничего очевидного; код, который у вас есть, очень похож на пример кода здесь .

...