1

我试图重用代码(http://msdn.microsoft.com/en-us/library/windows/desktop/ff625913(v=vs.85).aspx#FindByName),但我想把它包装在一个简单的类。当我运行此代码时,它落在:

hr = g_pAutomation->CreatePropertyCondition(UIA_ClassNamePropertyId, varProp, &pCondition); 

0xc0000005。

我知道,这是因为指针为空或损坏。但是,当我在没有任何类(来自main())的情况下运行此代码时,它运行良好。

我应该阅读什么以及从哪里了解它为什么会发生?

#pragma once

#include <UIAutomation.h>

class Automator
{
protected:
     IUIAutomation* g_pAutomation;
     IUIAutomationElement* pRoot;
     IUIAutomationElementArray* pArrFound;
     IUIAutomationElement* pFound;
public:
     Automator(void);
    ~Automator(void);
     void ClearResources(void);
     void FindAllWindows(void);
};


#include "Automator.h"

Automator::Automator(void)
{
     pRoot = NULL;
     pArrFound = NULL;
     pFound = NULL;
     g_pAutomation = NULL;

     CoInitialize(NULL);
     HRESULT hr;
     hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,
          __uuidof(IUIAutomation), (void**)&g_pAutomation);
     if(FAILED(hr))
          ClearResources();
     else
     {
          hr = g_pAutomation->GetRootElement(&pRoot);
          if (FAILED(hr) || pRoot == NULL)
            ClearResources();
     }

}

Automator::~Automator(void)
{
    ClearResources();
}

//
//Doesn't work
//
void Automator::FindAllWindows(void)
{
    VARIANT varProp;
    varProp.vt = VT_BSTR;
    varProp.bstrVal = L"";

    IUIAutomationCondition* pCondition;
    HRESULT hr = NULL;
    if (g_pAutomation != NULL)
    {
         hr = g_pAutomation->CreatePropertyCondition(UIA_ClassNamePropertyId, varProp,     &pCondition);
         if(FAILED(hr))
         {
              if (pCondition != NULL)
                  pCondition->Release();
              ClearResources();
         }
         else
         {
              pRoot->FindAll(TreeScope_Subtree, pCondition, &pArrFound);
         }
    }

    if(pCondition != NULL)
         pCondition->Release();
}

void Automator::ClearResources(void)
{
     if (pRoot != NULL)
         pRoot->Release();

     if (pArrFound != NULL)
         pArrFound->Release();

     if (pFound != NULL)
         pFound->Release();

     if (g_pAutomation != NULL)
         g_pAutomation->Release();

     CoUninitialize();
}
4

1 回答 1

0

我看到几个问题:

  1. 不要从类的构造函数/析构函数中调用 CoInitialize/CoUninitialize;在您的main(或线程入口点)内执行此操作。大量代码在main()被调用之前运行(例如静态类初始化程序)并且在外部运行main()可能会导致问题。
  2. 你还没有展示你的main()- 你在哪里创建你的Automator对象?我怀疑你实际上并没有创建一个Automator,这就是它崩溃的原因。

如果我要写你的main,它看起来像这样:

_wmain(int argc, wchar_t **argv)
{
    CoInitialize();
    {
        Automator automator;
        automator.FindAllWindows();
    }
    CoUninitialize();
}

额外的范围括号是为了确保 Automator 析构函数在 CoUninitialize() 之前运行。

于 2013-10-14T01:25:17.457 回答