2016-09-28 4 views
0

Я пытаюсь установить Windows Service (Build с CBuilder 6) с помощью ShellExecuteExShellExecuteEx не работает Стабильная

Вот моя установка функции.

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

Но функция ShellExecuteEx не работает стабильно.

Иногда бросает исключение EAccessViolation.

Как я могу устранить проблему? Где моя ошибка?

Спасибо.

+0

Вы инициализировали COM перед вызовом ShellExecuteExW? – Asesh

+2

API Windows не выбрасывает исключения C++. Используете ли вы какие-либо расширения компилятора, которые позволяют вам исключить стандартный синтаксис C++ для исключений SEH? Независимо от этого, поскольку вам все равно не нужна поддержка оболочки, почему бы вам просто не использовать «CreateProcess» вместо игры в русскую рулетку? – IInspectable

+0

@IInspectable Я не использую расширение компилятора. –

ответ

2

Здесь с 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; 
    } 
} 
+0

Соглашение OP о представлении логического значения с значениями 'int'' 0' и '-1' на самом деле не стоит повторять, ИМХО. То же самое для соглашения об именах. Я бы написал для него обертку, но для основной функции использовал бы обычный 'bool'. –

+1

Второй аргумент должен быть модифицируемым, и вы предоставляете const –

+1

Я исправляю его сейчас. –

 Смежные вопросы

  • Нет связанных вопросов^_^