2013-10-11 70 views
1

我試圖重新使用代碼(http://msdn.microsoft.com/en-us/library/windows/desktop/ff625913(v=vs.85).aspx#FindByName),但我想把它包裝在一個簡單的類。當我運行這個代碼時,它落在:UI自動化CreatePropertyCondition 0xc0000005

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

回答

0

我看到一對夫婦的問題:

  1. 不要從類的構造函數/析構函數調用CoInitialize/CoUninitialize;在main(或線程入口點)內執行。在調用main()之前運行相當數量的代碼(靜態類初始化程序爲一),並且在main()之外運行會導致問題。
  2. 您尚未顯示您的main() - 您在哪裏創建您的Automator對象?我懷疑你實際上並沒有創建一個Automator,這就是它崩潰的原因。

如果我打算寫你main,它應該是這樣的:

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

額外的範圍支架存在,以確保CoUninitialize之前的Automator的析構函數運行()。