Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 内核32 VirtualAllocEx间歇性返回IntPtr.Zero_C#_Interop_Tooltip_Intptr - Fatal编程技术网

C# 内核32 VirtualAllocEx间歇性返回IntPtr.Zero

C# 内核32 VirtualAllocEx间歇性返回IntPtr.Zero,c#,interop,tooltip,intptr,C#,Interop,Tooltip,Intptr,我们正在尝试从系统托盘图标中读取工具提示,代码正在工作,但是对于下面调用Kernel32.VirtualAllocEx的方法,它会间歇性地返回零 IntPtr ipRemoteBuffer = Kernel32.VirtualAllocEx( hProcess, IntPtr.Zero, new UIntPtr(BUFFER_SIZE), MemAllocationType.COMMIT, MemoryProtection.PAGE_READWRI

我们正在尝试从系统托盘图标中读取工具提示,代码正在工作,但是对于下面调用Kernel32.VirtualAllocEx的方法,它会间歇性地返回零

    IntPtr ipRemoteBuffer = Kernel32.VirtualAllocEx(
    hProcess,
    IntPtr.Zero,
    new UIntPtr(BUFFER_SIZE),
    MemAllocationType.COMMIT,
    MemoryProtection.PAGE_READWRITE);

  if (ipRemoteBuffer == IntPtr.Zero)
    return String.Empty;
它似乎工作得非常好,然后突然停止工作并始终返回IntPtr.Zero。检查Marshal.GetLastWin32Error()时,返回8(内存不足)。以下是完整代码:

public static string GetTooltip(string search)
{
  IntPtr _ToolbarWindowHandle = GetSystemTrayHandle();

  UInt32 count = User32.SendMessage(_ToolbarWindowHandle, TB.BUTTONCOUNT, 0, 0);

  List<string> tooltips = new List<string>();

  for (int i = 0; i < count; i++)
  {
    TBBUTTON tbButton = new TBBUTTON();
    string text = String.Empty;
    IntPtr ipWindowHandle = IntPtr.Zero;

    text = GetTBButtonText(_ToolbarWindowHandle, i, ref tbButton, ref text, ref ipWindowHandle);

    if (!String.IsNullOrWhiteSpace(text) && text.ToLowerInvariant().Contains(search.ToLowerInvariant()))
      return text;
  }

  return String.Empty;
}

static unsafe string GetTBButtonText(IntPtr hToolbar, int i, ref TBBUTTON tbButton, ref string text, ref IntPtr ipWindowHandle)
{
  const int BUFFER_SIZE = 0x1000;

  byte[] localBuffer = new byte[BUFFER_SIZE];

  UInt32 processId = 0;
  UInt32 threadId = User32.GetWindowThreadProcessId(hToolbar, out processId);

  IntPtr hProcess = Kernel32.OpenProcess(ProcessRights.ALL_ACCESS, false, processId);
  if (hProcess == IntPtr.Zero)
    return String.Empty;

  IntPtr ipRemoteBuffer = Kernel32.VirtualAllocEx(
    hProcess,
    IntPtr.Zero,
    new UIntPtr(BUFFER_SIZE),
    MemAllocationType.COMMIT,
    MemoryProtection.PAGE_READWRITE);

  if (ipRemoteBuffer == IntPtr.Zero)
  {
    var error = Marshal.GetLastWin32Error();
    return String.Empty;
  }

  // TBButton
  fixed (TBBUTTON* pTBButton = &tbButton)
  {
    IntPtr ipTBButton = new IntPtr(pTBButton);

    int b = (int)User32.SendMessage(hToolbar, TB.GETBUTTON, (IntPtr)i, ipRemoteBuffer);
    if (b == 0)
      return String.Empty;

    // this is fixed
    Int32 dwBytesRead = 0;
    IntPtr ipBytesRead = new IntPtr(&dwBytesRead);

    bool b2 = Kernel32.ReadProcessMemory(
      hProcess,
      ipRemoteBuffer,
      ipTBButton,
      new UIntPtr((uint)sizeof(TBBUTTON)),
      ipBytesRead);

    if (!b2)
      return String.Empty;
  }

  // button text
  fixed (byte* pLocalBuffer = localBuffer)
  {
    IntPtr ipLocalBuffer = new IntPtr(pLocalBuffer);

    int chars = (int)User32.SendMessage(hToolbar, TB.GETBUTTONTEXTW, (IntPtr)tbButton.idCommand, ipRemoteBuffer);
    if (chars == -1) { Debug.Assert(false); return ""; }

    // this is fixed
    Int32 dwBytesRead = 0;
    IntPtr ipBytesRead = new IntPtr(&dwBytesRead);

    bool b4 = Kernel32.ReadProcessMemory(
      hProcess,
      ipRemoteBuffer,
      ipLocalBuffer,
      new UIntPtr(BUFFER_SIZE),
      ipBytesRead);

    if (!b4)
      return String.Empty;

    text = Marshal.PtrToStringUni(ipLocalBuffer, chars);

    return text;
  }
}
publicstaticstringgettooltip(字符串搜索)
{
IntPtr_ToolbarWindowHandle=GetSystemTrayHandle();
UInt32 count=User32.SendMessage(_ToolbarWindowHandle,TB.BUTTONCOUNT,0,0);
列表工具提示=新建列表();
for(int i=0;i
如果我打电话释放内存,那么问题就解决了

    const uint MEM_RELEASE = 0x8000;

    UIntPtr uintPtr = UIntPtr.Zero;
    var successfullyReleased = Kernel32.VirtualFreeEx(hProcess, ipRemoteBuffer, uintPtr, MEM_RELEASE);
    if (!successfullyReleased)
    {

    }

调用
Marshal.GetLastError
以在任何P/Invoke失败时获取错误代码。它返回8,这似乎是错误\u内存不足\u内存8(0x8)没有足够的存储空间来处理此命令。无论如何,我没有记错,所以我必须对此做一些研究。谢谢你的回复。没有评论的否决投票?是的,这是标准做法。否决票不需要评论。他们也没有投票权。同样,你也不应该在否决票后留下评论。我想这对我来说没有意义,要么有人知道我在问什么,在这种情况下,他们指出我哪里出了问题,或者我怎么完全没有抓住要点/是个白痴,要么他们什么都不知道,在这种情况下,他们不发表评论,继续前进。哦,好吧。。。。希望有更多互操作经验的人仍能提供帮助。对粗鲁和辱骂的人投反对票是的,但不是因为不知道什么:S