2012-09-24 21 views
5

Hola, estoy tratando de verificar los puertos COM en un equipo de usuarios y luego insertarlos en un cuadro de lista a través de una acción personalizada en C++. Aunque no se muestra la información y cuando puedo depurar todo lo que está diciendo es "Función no se pudo ejecutar" Este es mi código Wix para el cuadro de lista:Wix: Agregar al Listbox desde C++ Acción personalizada

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

Y esta es mi acción personalizada:

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

¿Alguien me puede ayudar, por favor? Gracias

EDITAR: Lo tengo actualizando mi Listbox pero no es legible, símbolos extraños. Cambié mi char a CString como tal y esto parece funcionar aparte de mostrarlo incorrectamente.

CString ComPort; 
    ComPort = buffer; 

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

También la computadora de destino puede tener puertos serie ¿cuál es el mejor método para tenerlos todos listados con mi función dentro del ciclo for?

Gracias

+0

¿Cómo está intentando ejecutar su acción personalizada? ¿Ha comprobado (utilizando Dependency Walker) que en realidad se está exportando desde su DLL? – snowdude

+0

La acción personalizada se está llamando en Wix ya que pude hacer un punto de interrupción en ella, así que ese no es el problema. Gracias ... :) –

+0

Entonces, ¿dónde está obteniendo el error de función fallida para ejecutar? ¿Has ejecutado: 'msiexec/l * vx'? – snowdude

Respuesta

0

Lo tengo trabajando. Este es el código I modificado en caso que puede ayudar a los demás:

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

Gracias a @snowdude Yo sabía que tenía que convertir el carbón en Gran angular Char.

1

creo que estás pasando demasiados argumentos para la función. Como la firma WcaAddTempRecord usa la lista de argumentos variables, no validará el tipo.

En lugar de:

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

intento:

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

Dónde nIndex es el índice de base 1 del elemento que está insertando. Además, no estoy seguro si puede usar char, puede necesitar usar wchar_t.

Pruebe una prueba rápida de usar un búfer wchar_t en lugar de su búfer de caracteres y vea si eso funciona. Quite todo el otro código y simplemente agregue una sola entrada:

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

No tenía demasiados argumentos en la función, ya que la tabla del cuadro de lista tiene cuatro, por lo tanto, mi función necesita 4. Administré para que funcionase usando una sola entrada, ahora para probarla con mi variable ... :) –

Cuestiones relacionadas