Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.06.2012, 01:24   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию Ошибка при создании процесса

Приветствую! Проблема при создании процесса (в коде отмечено красным).

Среда: Visual C++ 2008 Express Edition

Код воспроизведён на си из примера --> http://wasm.ru/article.php?article=1001021

При установленной опции проекта "Использовать многобайтовую кодировку" срабатывает условие, где проверяется создался ли процесс. GetLastError возвращает:

Цитата:
ERROR_RESOURCE_DATA_NOT_FOUND

1812 (0x714)

The specified image file did not contain a resource section.
Если использовать опцию проекта "Использовать Юникод кодировку", то в режиме отладки появляется сообщение при вызове функции CreateProcess:



main.c
Код:
#include <windows.h>
#include <tchar.h>

#define IDR_MAINMENU 101
#define IDM_ASSEMBLE 40001

LRESULT CALLBACK WindowProc( HWND hwnd,
                             UINT uMsg,
                             WPARAM wParam,
                             LPARAM lParam
                           );

HINSTANCE hInstance;

LPCTSTR ClassName = _T("PipeWinClass");
LPCTSTR AppName = _T("One-way Pipe Example");

int WINAPI _tWinMain( HINSTANCE hInst,
                      HINSTANCE hPrevInstance,
                      LPTSTR lpCmdLine,
                      int nCmdShow
                    )
{
    WNDCLASSEX wc;
    MSG msg;
    HWND hwnd;

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    hInstance = hInst;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon((HINSTANCE) NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE);
    wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
    wc.lpszClassName = ClassName;
    wc.hIconSm = 0;

    if (RegisterClassEx(&wc) == 0) {
        MessageBox(NULL, _T("Cannot regiser window class"), _T("Error"), MB_ICONERROR);
        return FALSE;
    }

    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                          ClassName,
                          AppName,
                          WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                          CW_USEDEFAULT,
                          CW_USEDEFAULT,
                          400,
                          200,
                          (HWND) NULL,
                          (HMENU) NULL,
                          hInstance,
                          NULL);

    if (hwnd == NULL) {
        MessageBox(NULL, _T("Cannot create window"), _T("Error"), MB_ICONERROR);
        return FALSE;
    }

    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

    while(GetMessage(&msg, NULL, 0, 0) != 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

#define BSIZE 1024

LPCTSTR EditClass = _T("EDIT");
LPCTSTR CreatePipeError = _T("Error during pipe creation");
LPCTSTR CreateProcessError = _T("Error during process creation");
LPCTSTR CommandLine = _T("ml /c /coff /Cp test.asm");

LRESULT CALLBACK WindowProc( HWND hWnd,
                             UINT uMsg,
                             WPARAM wParam,
                             LPARAM lParam
                           )
{
    static HWND hwndEdit;
    HANDLE hRead;
    HANDLE hWrite;
    STARTUPINFO startupinfo;
    PROCESS_INFORMATION pinfo;
    TCHAR buffer[BSIZE];
    DWORD bytesRead;
    BOOL isCreated;

    int num_error;

    switch(uMsg) {
    case WM_CREATE:
        hwndEdit = CreateWindowEx((DWORD) NULL,
                                  EditClass,
                                  NULL,
                                  WS_CHILD | WS_VISIBLE | ES_READONLY |
                                  ES_MULTILINE | ES_AUTOHSCROLL,
                                  20, 20,
                                  300, 25,
                                  hWnd,
                                  (HMENU) NULL,
                                  hInstance,
                                  NULL);
        break;
    case WM_SIZE:
        MoveWindow(hwndEdit, 0, 0, LOWORD(lParam), HIWORD(lParam), FALSE);
        break;
Продолжение main.c в следующем сообщении.
8Observer8 вне форума Ответить с цитированием
Старый 03.06.2012, 01:25   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

main.c (продолжение)
Код:
    case WM_COMMAND:
        if (lParam == 0) {
            if (LOWORD(wParam) == IDM_ASSEMBLE) {
                if (CreatePipe(&hRead, &hWrite, NULL, 0) == 0) {
                    MessageBox(hWnd, CreatePipeError, AppName, MB_ICONERROR | MB_OK);
                }
                else {
                    startupinfo.cb = sizeof (STARTUPINFO);
                    GetStartupInfo(&startupinfo);
                    startupinfo.hStdOutput = hWrite;
                    startupinfo.hStdError = hWrite;
                    startupinfo.dwFlags |= STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
                    startupinfo.wShowWindow = SW_HIDE;
                    isCreated = CreateProcess(NULL, CommandLine, NULL, NULL, TRUE, NULL,
                                              NULL, NULL, &startupinfo, &pinfo);
                    num_error = GetLastError();
                    if (isCreated) {
                        MessageBox(hWnd, CreateProcessError, AppName, MB_ICONERROR | MB_OK);
                    }
                    else {
                        CloseHandle(hWrite);
                        while (TRUE) {
                            RtlZeroMemory(buffer, BSIZE);
                            if (ReadFile(hRead, buffer, BSIZE-1, &bytesRead, NULL) == 0) {
                                break;
                            }
                            else {
                                SendMessage(hwndEdit, EM_SETSEL, -1, 0);
                                SendMessage(hwndEdit, EM_REPLACESEL, (WPARAM) FALSE, (LPARAM) buffer);
                            }
                        }
                    }
                }
            }
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    return 0;
}
pipe.rc
Код:
#define IDR_MAINMENU 101
#define IDM_ASSEMBLE 40001

IDR_MAINMENU MENU DISCARDABLE 
BEGIN
    POPUP "&Action"
    BEGIN
        MENUITEM "&Assemble", IDM_ASSEMBLE
    END
END
8Observer8 вне форума Ответить с цитированием
Старый 03.06.2012, 03:09   #3
rlib
Форумчанин
 
Аватар для rlib
 
Регистрация: 22.05.2012
Сообщений: 352
По умолчанию

Обявите CommandLine как буффер:
TCHAR CommandLine[MAX_PATH];


lpCommandLine [in, out, optional]

The command line to be executed. The maximum length of this string is 32,768 characters, including the Unicode terminating null character. If lpApplicationName is NULL, the module name portion of lpCommandLine is limited to MAX_PATH characters.

The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.


http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
rlib вне форума Ответить с цитированием
Старый 03.06.2012, 09:17   #4
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

rlib, большое спасибо!

Теперь другая проблема. В буфер копируется только первый символ:

Код:
_tccpy(CommandLine, _T("ml /c /coff /Cp TEST.asm"));
8Observer8 вне форума Ответить с цитированием
Старый 03.06.2012, 10:37   #5
StIX-S
Пользователь
 
Регистрация: 24.06.2011
Сообщений: 69
По умолчанию

Всё верно, функция _tccpy копирует 1 символ.
Цитата:
The _mbccpy function copies one multibyte character from src to dest.
Для копирования строки нужна _tcscpy
StIX-S вне форума Ответить с цитированием
Старый 03.06.2012, 11:07   #6
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

StIX-S, благодарю! Эта проблема решена!

Ещё мой недочёт. CreateProcess возвращает ненулевое значение в случае успеха.

Поэтому вместо:
Код:
if (isCreated) {
}
нужно:
Код:
if (isCreated == 0) {
}
Но появилась другая проблема. Теперь GetLastError опять возвращает (после вызова CreateProcess):

Цитата:
ERROR_RESOURCE_DATA_NOT_FOUND

1812 (0x714)

The specified image file did not contain a resource section.
Но сама функция CreateProcess возвратила единицу.

После вызова ReadFile, GetLastError вернула:
Цитата:
ERROR_BROKEN_PIPE

109 (0x6D)

The pipe has been ended.
В следствии - сама ReadFile возвращает ноль.

Хотя после вызова CreatePipe никаких ошибок нет.
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при создании БД alt5000 PHP 12 26.11.2011 18:46
Ошибка при создании домена JustPunk Помощь студентам 2 18.05.2011 19:48
Ошибка при создании таблицы ProgDel БД в Delphi 5 07.11.2010 11:31
Страшная ошибка при создании процесса nazavrik Общие вопросы C/C++ 3 03.10.2009 01:17
ошибка при создании TImage Juffin Общие вопросы Delphi 9 22.04.2009 17:49