Search code examples
c++winapiwindows-installer

Launching *.msi thanks to Windows API


I've have been trying to launch other programs with admin account in C++ with Windows API. It works well for *.exe files but not with *.msi files. I tried using msiexec.exe which works well in PowerShell, but not from cmd and not from my program. Is there a way to fix this? I'm on Windows 10, compiling with MinGW 64bits, and here is my code:

#include <windows.h>
#include <iostream>

int main()
{
    wchar_t s[] = L" /i \"path/my_installer.msi\"";

    STARTUPINFOW su_info;
    ZeroMemory(&su_info, sizeof(STARTUPINFOW));
    su_info.cb = sizeof(STARTUPINFO);

    PROCESS_INFORMATION pi;
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    BOOL b = CreateProcessWithLogonW(L"user", L"localhost", L"password", 0, L"msiexec.exe", s,
                                     0, nullptr, nullptr, &su_info, &pi);

    if(!b)
        std::cout << "An error occured" << std::endl;

    return 0;
}

Thanks in advance for you help.


Solution

  • I can reproduce this with the argument L" /i \"path/my_installer.msi\"". The arguments after "/i" option should not contains /.

    The following path sample work for me.

    #include <windows.h>
    #include <iostream>
    
    int main()
    {
        wchar_t s[] = L" /i \"C:\\Users\\username\\...\\my_installer.msi\"";
    
        STARTUPINFOW su_info;
        ZeroMemory(&su_info, sizeof(STARTUPINFOW));
        su_info.cb = sizeof(STARTUPINFO);
    
        PROCESS_INFORMATION pi;
        ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
        BOOL b = CreateProcessWithLogonW(L"user", L"domain", L"password", 0, L"msiexec.exe", s,
            0, nullptr, nullptr, &su_info, &pi);
    
        if (!b)
            std::cout << "An error occured" << std::endl;
    
        return 0;
    }