Форум программистов, компьютерный форум CyberForum.ru

CreateProcess рекурсия. - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
ignisdivine
4 / 4 / 0
Регистрация: 27.03.2011
Сообщений: 38
04.09.2011, 15:43     CreateProcess рекурсия. #1
Пробую запустить процесс сам из себя, используя CreateProcess(). Путем проверки, кол-ва парам-ров командной строки, (когда создаю дочерний процесс отправляю через ком. строку "child"), т.к. argv[0] содержит путь к файлу, а след. по индексу идет параметр, что по идее должен отражать argc. Но наверное, я не прав в чем-то. Не знаю, как проверить. Т.к. в процессе отладки виден ход только самого первого процесса. А проблема в том, что процессов не 2 (дочерний и родительский), а много больше и время выводится(в дочернем) совсем не туда.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "windows.h"
#include "time.h"
#include <iostream>
#include <conio.h>
#include <string.h>
 
using namespace std;
 
void main(int argc, char* argv[])
{
    COORD pos = {1,1};
    if (argc == 1)
    {
        wchar_t com_line[] = L"child";
 
        STARTUPINFO si = { sizeof(STARTUPINFO) };
        PROCESS_INFORMATION pi = {0};
        BOOL bSuccess;              
        bSuccess = CreateProcess ( L"C:\\Documents and Settings\\Ignis\\Мои документы\\Visual Studio 2008\\Projects\\system_po1\\Debug\\system_po1.exe", com_line ,
            NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
                             NULL, NULL, &si, &pi );
    }
 
    if (argc == 2)
    {
        pos.X = 22;
        pos.Y = 22;
    }
 
    HANDLE hStdout;
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
    char tmpBuf[9], lastBuf[9]="";
    errno_t err;
    
 
    while(1)
    {
        err = _strtime_s( tmpBuf, 9 );
        if (strcmp(lastBuf,tmpBuf) != 0)
        {
            bool b = SetConsoleCursorPosition(hStdout,pos);
            strcpy(lastBuf,tmpBuf);
            if (err)
            {
              printf("_strdate_s failed due to an invalid argument.");
              exit(1);
            }
            printf("%s", tmpBuf );
        }
    }
}
Добавлено через 14 часов 43 минуты
Исправил проверку на то, какой это вызов дочерний или родительский путем создания файла. Теперь создается 2 процесса, однако вывод не соответствует желаемому, т.к. выводится 4 времени (по два в каждой точке). А нужно по одному (точки 1,1 и 22, 22).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include "windows.h"
#include "time.h"
#include <iostream>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
 
 
 
using namespace std;
 
wchar_t lockFileName[] = L"ProcessSpawner_LockFile";
 
void main(int argc, char* argv[])
{
    // Creating lock-file to indicate that process was run 1 time.
    HANDLE fd;
    fd = CreateFile( lockFileName, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
    // COORD struct containes cursor position of console (x,y).
    COORD pos = {1,1};
    // standart output handler
    HANDLE hStdout;
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
 
    // tmpBuf contains current time, lastBuf - previous time to check
    char tmpBuf[9], lastBuf[9]="";
    errno_t err;
 
    if( fd != INVALID_HANDLE_VALUE )
    {
        // first run, 
        wchar_t com_line[] = L"child";
 
        STARTUPINFO si = { sizeof(STARTUPINFO) };
        PROCESS_INFORMATION pi = {0};
        BOOL bSuccess;              
        bSuccess = CreateProcess ( L"C:\\Documents and Settings\\Ignis\\Мои документы\\Visual Studio 2008\\Projects\\system_po1\\Debug\\system_po1.exe", com_line ,
            NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
                             NULL, NULL, &si, &pi );
        while(1)
        {
            err = _strtime_s( tmpBuf, 9 );
            if (strcmp(lastBuf,tmpBuf) != 0)
            {
                bool b = SetConsoleCursorPosition(hStdout,pos);
                strcpy(lastBuf,tmpBuf);
                if (err)
                {
                  printf("_strdate_s failed due to an invalid argument.");
                  exit(1);
                }
                printf("%s", tmpBuf );
            }
        }
    }
    else
    {
        // changing COORDE pos to display time in other place of console
        pos.X = 22;
        pos.Y = 22;
        while(1)
        {
            err = _strtime_s( tmpBuf, 9 );
            if (strcmp(lastBuf,tmpBuf) != 0)
            {
                bool b = SetConsoleCursorPosition(hStdout,pos);
                strcpy(lastBuf,tmpBuf);
                if (err)
                {
                  printf("_strdate_s failed due to an invalid argument.");
                  exit(1);
                }
                printf("%s", tmpBuf );
            }
        }
    }
    CloseHandle(fd);
    DeleteFile(lockFileName);
    
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.09.2011, 15:43     CreateProcess рекурсия.
Посмотрите здесь:

функция CreateProcess C++
C++ CreateProcess передача параметров процессу
C++ g++: error: CreateProcess: No such file or directory
C++ CreateProcess
WinAPI: CreateProcess и DOS-приложение C++
C++ Как запустить консольное приложение через CreateProcess и спрятать его окно?
C++ CreateProcess WaitForMultipleObjects...
C++ Исполнение .cmd через вызов CreateProcess()
кроссплатформенный аналог WinApi функций (CreateProcess) C++
CreateProcess C++
Запустить файл с помощью CreateProcess C++
Не работает CreateProcess C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Somebody
2775 / 1588 / 142
Регистрация: 03.12.2007
Сообщений: 4,162
Завершенные тесты: 1
04.09.2011, 18:18     CreateProcess рекурсия. #2
Если не ошибаюсь, com_line непосредственно передаётся в качестве командной строки процессу, тут выходит, что "child" - это argv[0], а не [1]. То есть путь надо тоже включать в командную строку.
ignisdivine
4 / 4 / 0
Регистрация: 27.03.2011
Сообщений: 38
04.09.2011, 19:58  [ТС]     CreateProcess рекурсия. #3
Спасибо, этот вопрос решен, неправильный вывод был из-за перегрузки процессора, т.к. 2 процесса съедали 100% ЦП. Помог Sleep(). Все работает. Однако непонятно, как выполнить обработку выхода нажатием клавиши, к примеру ESC, в одном из процессов. Думаю, может сделать считывание в бесконечном цикле getch(), пока не встретится ESC, в момент пока Sleep(), приостанавливает работу. Но как это реализовать не знаю. Может кто-то подскажет? 3й процесс для обработки не подходит, т.к. задание ограничено условиями (2 процесса).

Сейчас код выглядит так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "windows.h"
#include "time.h"
#include <iostream>
#include <conio.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
 
 
 
using namespace std;
 
wchar_t lockFileName[] = L"ProcessSpawner_LockFile";
 
void main(int argc, char* argv[])
{
    // Creating lock-file to indicate that process was run 1 time.
    HANDLE fd;
    fd = CreateFile( lockFileName, GENERIC_WRITE, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
    // COORD struct containes cursor position of console (x,y).
    COORD pos = {0,0};
    // standart output handler
    HANDLE hStdout;
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
 
    // tmpBuf contains current time, lastBuf - previous time to check
    char tmpBuf[9], lastBuf[9]="";
    errno_t err;
 
    if( fd != INVALID_HANDLE_VALUE )
    {
        // first run, 
        wchar_t com_line[] = L"head_file";
 
        STARTUPINFO si = { sizeof(STARTUPINFO) };
        PROCESS_INFORMATION pi = {0};
        BOOL bSuccess;              
        bSuccess = CreateProcess ( L"C:\\Documents and Settings\\Ignis\\Мои документы\\Visual Studio 2008\\Projects\\system_po1\\Debug\\system_po1.exe", NULL,
            NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS,
                             NULL, NULL, &si, &pi );
        
        while(1)
        {
            err = _strtime_s( tmpBuf, 9 );
            if (strcmp(lastBuf,tmpBuf) != 0)
            {
                bool b = SetConsoleCursorPosition(hStdout,pos);
                strcpy(lastBuf,tmpBuf);
                if (err)
                {
                  printf("_strdate_s failed due to an invalid argument.");
                  exit(1);
                }
                printf("%s", tmpBuf );
                Sleep(999);
            }
        }
    }
    else
    {
        // changing COORDE pos to display time in other place of console
        pos.X = 20;
        pos.Y = 20;
        while(1)
        {
            err = _strtime_s( tmpBuf, 9 );
            if (strcmp(lastBuf,tmpBuf) != 0)
            {
                bool b = SetConsoleCursorPosition(hStdout,pos);
                strcpy(lastBuf,tmpBuf);
                if (err)
                {
                  printf("_strdate_s failed due to an invalid argument.");
                  exit(1);
                }
                printf("%s", tmpBuf );
                Sleep(999);
            }
        }
    }
    CloseHandle(fd);
    DeleteFile(lockFileName);
    
}
Somebody
2775 / 1588 / 142
Регистрация: 03.12.2007
Сообщений: 4,162
Завершенные тесты: 1
05.09.2011, 11:16     CreateProcess рекурсия. #4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <windows.h>
 
int main()
{
    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    SetConsoleMode(hStdIn, 0);
    for (bool stop = false; !stop; )
    {
        WaitForSingleObject(hStdIn, INFINITE);
        INPUT_RECORD ir[10];
        DWORD n;
        do
        {
            ReadConsoleInput(hStdIn, ir, sizeof(ir) / sizeof(ir[0]), &n);
            for (unsigned i = 0; i < n; i++)
                if (ir[i].EventType == KEY_EVENT &&
                    ir[i].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
                    stop = true;
            GetNumberOfConsoleInputEvents(hStdIn, &n);
        } while (n > 0);
    }
}
Yandex
Объявления
05.09.2011, 11:16     CreateProcess рекурсия.
Ответ Создать тему
Опции темы

Текущее время: 08:26. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru