P/Invoking CreateToolhelp32Snapshot failing in Compact Framework

让人想犯罪 __ 提交于 2019-11-28 11:41:26

问题


Hey, im doing a little app for my smart phone, using Windows Mobile 6. I'm trying to get all currently running processec, but method CreateToolhelp32Snapshot always returns -1. So now im stuck. I tried to get error with invoking GetLastError() method, but that method returns 0 value. Here is a snippet of my code.

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);

回答1:


  • First, your handle check is wrong. It's common for the high bit to be on in a handle, causing it to look like a negative number when cast to a signed int. You should be checking that is isn't NULL (0) or INVALID_HANDLE_VALUE (-1 / 0xffffffff).
  • You shouldn't be "invoking GetLastError" but calling Marshal.GetLastWin32Error()
  • You've not set the SetLastError attribute in the P/Invoke declaration. In C# it defaults to false, in VB it defaults to true.
  • Where's your PROCESS32 implementation? The docs clearly state that the dwLength member must be set before the call and it's not clear here if that's happening.

As a side note, the Smart Device Framework's OpenNETCF.ToolHelp namespace has all of this implemented and working (in case you'd rather not reinvent the wheel).




回答2:


Instead of

CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

use

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

By default CreateToolhelp32Snapshot will try to snapshot the heaps and that can cause an out of memory error.

Found this at https://social.msdn.microsoft.com/Forums/en-US/e91d845d-d51e-45ad-8acf-737e832c20d0/createtoolhelp32snapshot-windows-mobile-5?forum=vssmartdevicesnative and it solved my problem.




回答3:


If you're not seeing valid "last error" information, perhaps you might need to add the "SetLastError" attribute on the API's DllImport attribute (MSDN reference with code examples). According to the documentation of this attribute, you should set SetLastError to...

...true to indicate that the callee will call SetLastError; otherwise, false. The default is false.

The runtime marshaler calls GetLastError and caches the value returned to prevent it from being overwritten by other API calls. You can retrieve the error code by calling GetLastWin32Error

As for the API failure you're seeing, I don't spot anything obvious offhand; the code you have seems very similar to the sample code here.



来源:https://stackoverflow.com/questions/393881/p-invoking-createtoolhelp32snapshot-failing-in-compact-framework

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!