Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wix: Add to Listbox from C++ Custom Action

Hi i'm trying to check the COM Ports on a users machine and then insert them into a listbox via a custom action in c++. Although it is not displaying the information and when I debug all it is saying is "Function Failed To Execute" This is my Wix code for the listbox:

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

And this is my Custom Action:

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

Can anyone help me please? Thanks

EDIT: I have it updating my Listbox but it is not legible, strange symbols. I changed my char to a CString like so and this seems to work apart from displaying it incorrectly.

CString ComPort;
    ComPort = buffer;

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

Also the target computer may have serial ports what is the best method to have them all listed with my function inside the for loop?

Thanks

like image 396
Natalie Carr Avatar asked Sep 24 '12 09:09

Natalie Carr


1 Answers

I think you're passing too many arguments to the function. Because the WcaAddTempRecord signature uses variable argument list it won't validate type.

Instead of:

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

Where nIndex is the 1 based index of item you're inserting. Also I'm not sure if you can use char, you might need to use wchar_t.

Try a quick test of using a wchar_t buffer instead of your char buffer and see if that works. Remove all the other code and just add a single entry:

hr = WcaAddTempRecord(&hTable, &hColumns, L"ListBox",&insertError, 0, 4, L"COMPORT", 1,  L"TestPort");
like image 116
snowdude Avatar answered Sep 20 '22 13:09

snowdude