2012-09-24 9 views
5

Witam Próbuję sprawdzić porty COM na komputerze użytkownika, a następnie wstawić je do listbox poprzez niestandardową akcję w C++. Chociaż nie jest to wyświetlanie informacji i kiedy debugowania wszystko to mówi jest „Funkcja nie wykonały” To jest mój kod Wix dla pola listy:Wix: Dodaj do Listbox z C++ Custom Action

 <Control Id="ListBoxID" Type="ListBox" Property="COMPORT" Width="80" Height="40" X="80" Y="165" Indirect="no"> 
     <ListBox Property="COMPORT"> 
     </ListBox> 
     <Condition Action="hide">(DEVICETYPE = "1")</Condition> 
     <Condition Action="show">(DEVICETYPE = "2")</Condition> 
     <Condition Action="show">(DEVICETYPE = "3")</Condition> 
     <Condition Action="hide">(DEVICETYPE = "4")</Condition> 
    </Control> 

A to moja akcja niestandardowa:

extern "C" UINT __stdcall GetDatascanPort(MSIHANDLE hInstall) 
{ 

HRESULT hr = S_OK; 
UINT er = ERROR_SUCCESS; 
HKEY keyHandle; 
DWORD i,openStatus,cb_value_buffer,cb_buffer,dwType; 
char value_buffer[100],buffer[10]; 
MSIHANDLE hTable = NULL; 
MSIHANDLE hColumns = NULL; 
MSIDBERROR insertError = MSIDBERROR_NOERROR; 

hr = WcaInitialize(hInstall, "GetDatascanPort"); 
ExitOnFailure(hr, "Failed to initialize"); 

WcaLog(LOGMSG_STANDARD, "Initialized."); 


if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, 
        "HARDWARE\\DEVICEMAP\\SERIALCOMM", 
        0, 
        "", 
        REG_OPTION_NON_VOLATILE, 
        KEY_QUERY_VALUE, 
        default_sa(), 
        &keyHandle, 
        &openStatus) == ERROR_SUCCESS) 
{ 
    for (i=0;;i++) 
    { 
     cb_value_buffer = sizeof(value_buffer); 
     cb_buffer = sizeof(buffer); 

     if (RegEnumValue(keyHandle, 
         i, 
         value_buffer, 
         &cb_value_buffer, 
         NULL, 
         &dwType, 
         (unsigned char *) buffer, 
         &cb_buffer) != ERROR_SUCCESS) 
         break; 

     if (dwType != REG_SZ || strlen(buffer) > 6) 
      continue; 

     hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", 1, 0, buffer); 
     ExitOnFailure(hr, "failed to set COMPORT"); 


    } 

    RegCloseKey(keyHandle); 

    if (hTable) 
     MsiCloseHandle(hTable); 
    if (hColumns) 
     MsiCloseHandle(hColumns); 
    return WcaFinalize(hr); 

} 

LExit: 
er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; 
return WcaFinalize(er); 
} 

Czy ktoś może mi pomóc? Dzięki

EDYCJA: Mam aktualizacji mojej listy, ale nie jest czytelny, dziwne symbole. Zmieniłem mój znak na CString, więc wydaje się, że działa to niezależnie od niepoprawnego wyświetlania.

CString ComPort; 
    ComPort = buffer; 

hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", 1, ComPort, ComPort); 
ExitOnFailure(hr, "failed to set COMPORT"); 

Również komputer docelowy może mieć porty szeregowe, jaka jest najlepsza metoda, aby wszystkie zostały wymienione z moją funkcją wewnątrz pętli for?

Dzięki

+0

Jak próbujesz wykonać niestandardową akcję? Czy sprawdziłeś (używając Dependency Walker) czy faktycznie jest on eksportowany z twojej biblioteki DLL? – snowdude

+0

Niestandardowa akcja jest wywoływana w Wix, ponieważ udało mi się ją przełamać, więc to nie jest problem. Dzięki .. :) –

+0

A więc, skąd się bierze, że funkcja nie wykonała błędu? Czy uruchomiłeś: 'msiexec/l * vx'? – snowdude

Odpowiedz

0

Gotowy do pracy. Jest to kod I wprowadza okrywać może pomóc innym:

 MultiByteToWideChar(CP_ACP,0,buffer,-1,ComPort,strlen(buffer)); 
     ComPort[strlen(buffer)]=0; 

     hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", value++, ComPort, ComPort); 
     ExitOnFailure(hr, "failed to set COMPORT"); 

Dzięki @snowdude Wiedziałem, że muszę do konwersji char Wide Char.

1

Myślę, że przekazujesz zbyt wiele argumentów do funkcji. Ponieważ sygnatura WcaAddTempRecord używa zmiennej listy argumentów, nie będzie sprawdzać poprawności typu.

Zamiast:

hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", 1, 0, buffer); 

try:

hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", nIndex, buffer); 

Gdzie nIndex jest wskaźnik na bazie 1 elementu jesteś wkładania. Również nie jestem pewien, czy możesz użyć char, może być konieczne użycie wchar_t.

Wypróbuj szybki test używania bufora wchar_t zamiast bufora znaków i sprawdź, czy to działa. Usuń cały inny kod i po prostu dodaj pojedynczy wpis:

hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", 1, L"TestPort"); 
+0

Nie miałem zbyt wielu argumentów w funkcji, ponieważ tabela listbox ma cztery, więc moja funkcja potrzebuje 4. Zarządzam, aby działało z użyciem pojedynczego wpisu, teraz wypróbuj go z moją zmienną .. :) –