c++winapiaccess-violationc++builder-6

ShellExecuteEx Does Not Work Stable


I'm trying to install windows service (Build with CBuilder 6) using ShellExecuteEx

Here is my install function.

int WinServiceInstall(WideString ServicePath)
{
 int result = 0;
 LPCWSTR filename = L"MyService.exe";
 LPCWSTR params = L"/install /silent";
 LPCWSTR dir = ServicePath;

 WideString fullPath = ServicePath+"\\"+filename;
 if (!PathFileExistsW(fullPath.c_bstr())) return -1;

 SHELLEXECUTEINFOW *lpExecInfo = new SHELLEXECUTEINFOW();
 try
 {
     lpExecInfo->cbSize = sizeof(SHELLEXECUTEINFOW);
     lpExecInfo->hwnd = 0;
     lpExecInfo->lpVerb = NULL;
     lpExecInfo->lpFile = filename;
     lpExecInfo->lpDirectory = dir;
     lpExecInfo->lpParameters = params;
     lpExecInfo->nShow = SW_HIDE;
     lpExecInfo->hInstApp = NULL;
     BOOL bResult = ShellExecuteExW(lpExecInfo);
     WaitForSingleObject(lpExecInfo->hProcess,INFINITE);
     if (!bResult)
     {
       int ErrorCode = GetLastError();
       WideString message = GetLastErrorMessage(ErrorCode);
       message +="\n"+IntToStr(ErrorCode);
       MessageBoxW(0,message,L"GetLastError",0);
       PrintError(ErrorCode);
       result = -1;
     }
 }
 catch(Exception &e)
 {
   printf("Hata: %s",e.Message);
   result = -1;

   WideString message = e.Message;
   MessageBoxW(0,message,L"Exception",0);
 }
 delete lpExecInfo;
 return result;
}

But ShellExecuteEx function don't work stable.

Sometimes throwing EAccessViolation exception.

How can I do debug problem ? Where's my mistake ?

Thanks.


Solution

  • Here is with CreateProcess.

    bool WinServiceInstall(WideString ServicePath)
    {
        STARTUPINFO si = { sizeof(si) };
        PROCESS_INFORMATION pi = {};
    
        WideString lpCommandLine=L"\""+ServicePath+"\\MyService.exe"+"\" /install /silent";
    
        if(CreateProcessW(NULL,
            lpCommandLine,
            NULL,
            NULL,
            FALSE,
            0,
            NULL,
            NULL,
            &si,
            &pi )
        )
        {
            WaitForSingleObject( pi.hProcess, INFINITE );
            CloseHandle( pi.hProcess );
            CloseHandle( pi.hThread );
            return true;
        }
        else
        {
            wchar_t buf[256];
            long errorCode = GetLastError();
            FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errorCode,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, 256, NULL);
            MessageBoxW(0,buf,L"Error",0);
            return false;
        }
    }