1 Востаннє редагувалося Rolana (27.04.2014 12:45:58)

Тема: Процеси

Написати дві програми:

1) Програма TASK1, яка зчитує з файлу TASK.TXT назви процесів і запускає їх з відповідними параметрами (вже виставлені). Після запуску відповідного процесу його Pid записується у файл PROCCES.TXT. Після запуску всіх процесів запускається TASK2. Вміст файлу TASK дивитися відповідно до варіанту (вже все записано).

2) Програма TASK2 зчитує PROCCES.TXT, виводить на екран його вміст, запитує Pid і знищує відповідний процес.

TASK1

#include "stdafx.h"
#include <windows.h>
#include "string.h"

int main(int argc, char* argv[])

{
STARTUPINFO si[4];
PROCESS_INFORMATION pi[4];
TCHAR path[256] = _T("c:\\abc\\\0"), startpath[256] = _T("c:\\abc\\\0");
    TCHAR procname[10][14];
    FILE *f;
    TCHAR buf[14];
    int i = 0, n, pid[3];

    //--------Вичитуємо з файлу назви процесів------------
    fopen_s(&f, "c:\\abc\\TASK.TXT", "rt");
    while (!feof(f))
    {
        _fgetts(procname[i], 14, f);
        _fgetts(buf, 14, f);
        i++;
    }
    fclose(f);
    fopen_s(&f, "c:\\abc\\PROCESS.TXT", "wt");
    for (int j = 0; j < i; j++)
    {
        _tcscat_s(path, procname[j]);
        ZeroMemory( &si[j], sizeof(si[j]));
        si[j].cb = sizeof(si[j]);
        ZeroMemory( &pi[j], sizeof(pi[j]));
        if( !CreateProcess( NULL, path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[j], &pi[j]))
        return 0;
        pid[j]=GetProcessId(pi[j].hProcess);
        //_ftprintf(f,L"%d\n",&pid);
        fprintf(f,"%d\n",pid[j]);
        // Close process and thread handles.
        CloseHandle( pi[j].hProcess );
        CloseHandle( pi[j].hThread );
        for (int k=0; k<14; k++)
        path[k]=startpath[k];

    }
        fclose(f);
            TCHAR pTASK2[] = _T("c:\\abc\\TASK2.exe");
        ZeroMemory( &si[3], sizeof(si[3]));
        si[3].cb = sizeof(si[3]);
        ZeroMemory( &pi[3], sizeof(pi[3]));
        
        if( !CreateProcess( NULL, pTASK2, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[3], &pi[3])) return 0;
                    puts("\n");
            //        WaitForMultipleObjects(4,&pi[4].hProcess,TRUE,INFINITE);
CloseHandle( pi[4].hProcess );
CloseHandle( pi[4].hThread );

return 0;

} 

TASK2

// TASK2.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <windows.h> 
FILE *f;
int _tmain(int argc, _TCHAR* argv[])
{
    DWORD excode;
    HANDLE hPr;
    int pid[100], i=0, processID;
    bool flag=false;
    fopen_s(&f,"c:\\abc\\PROCESS.txt","rt");
    while (!feof(f))
    {
        fscanf_s(f,"%d\n",&pid[i]);
        printf("%d\n",pid[i]);
        i++;
    }
    while (flag==false)
    {
        printf("Enter the process ID to destroy ");
        scanf_s("%d",&processID);
        for (int j=0; j<i; j++)
            if (pid[j]==processID) flag=true;        
        if (flag==false) printf("Bad pid. Try again\n");
    }
    hPr = OpenProcess(PROCESS_TERMINATE,TRUE,processID);
    if(hPr != NULL)
    {
        GetExitCodeProcess(hPr, &excode);
    TerminateProcess(hPr,excode);
//    CloseHandle(hPr);
    }
    return 0;
}

Така проблемка... Ніби все працює, але коли TASK1 викликає TASK2, то не виходить завершити процес по його ідентифікатору. В той же час сама програмка TASK2 завершує процес, якщо її просто запустити (не через TASK1).
Допоможіть, будь ласка.

Post's attachments

abc.rar 585.08 kb, 374 downloads since 2014-04-27 

2

Re: Процеси

Я не перечитував надто уважно але не зміг зрозуміти суть цього

while (!feof(f))
    {
        _fgetts(procname[i], 14, f);
        _fgetts(buf, 14, f);
        i++;
    }

Навіщо зчитувати щось в buf?
і ще в рядку 10 в вас забагато слешів

"c:\\abc\\\0"

приберіть один

3 Востаннє редагувалося Rolana (27.04.2014 14:18:15)

Re: Процеси

_fgetts(buf, 14, f);

- без цього запису у мене в

procname[i]

після кожного зчитаного запису з файлу записується ще один порожній рядок. По суті мені buf взагалі не потрібен.

c:\\abc\\\0

- якщо Ви про це "\0", то це я додавала символ закінчення рядка до запису каталогу. Формування шляху до процесу працює як з ним, так і без нього.

Це не впливає на те, що мене цікавить.

4 Востаннє редагувалося koala (27.04.2014 15:33:12)

Re: Процеси

Текст трохи важко читати, якщо чесно. Є суттєві помилки.

    if(hPr != NULL)
    {
        GetExitCodeProcess(hPr, &excode);
      TerminateProcess(hPr,excode);
//    CloseHandle(hPr);
    }

GetExitCodeProcess повертає STILL_ACTIVE до виклику і виконання TerminateProcess, так що цей блок робить тільки одну дію (викликає TerminateProcess). І ви ніяк не відображаєте результати виконання цих операцій - а це б вам дуже допомогло в цій ситуації.

По суті ж, як я розумію, проблема в тому, що ви робите

CreateProcess( NULL, pTASK2, NULL, NULL...

Дивимося в довідку - третій і четвертий параметр - це

  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,

і вони у вас пусті, тобто параметри безпеки типові. Якщо ж ви почитаєте, знову ж таки, довідку, то дізнаєтеся, що типове значення не дозволяє викликати TerminateProcess, вам потрібно виставити флаг PROCESS_TERMINATE.

І маленькі поради:

bool processExists = false; //називайте булеві змінні по суті, а не флагами, і проголошуйте змінні безпосередньо перед використанням
while ( !processExists ) //==false еквівалентно запереченню(!), але складніше сприймається
{
  printf( "Enter the process ID to destroy:" );//ставте якусь позначку при запрошенні щось ввести - :, =, >...
  scanf_s( "%d", &processID );
  for ( int j = 0; ( j < i ) && !processExists; j++ ) //немає сенсу продовжувати пошук, якщо знайдено потрібний процес
  {
    if ( pid[ j ] == processID) 
      processExists = true;//ставте дію в окремий рядок після перевірки, тоді легше буде знаходити помилки
  }
  if ( !processExists )
    printf( "Bad pid. Try again\n" );
}

Дуже раджу, як матимете вільний час, почитати Настанови зі стилю програмування C++

Подякували: Rolana1

5 Востаннє редагувалося koala (27.04.2014 15:30:45)

Re: Процеси

На зауваження drWoZD: так, нулі явно зайві (вони і так додаються після рядка), і замість читати в буфер, краще робити

fseek ( f , 14 , SEEK_CUR );
Подякували: Rolana1

6 Востаннє редагувалося Rolana (27.04.2014 15:52:33)

Re: Процеси

koala написав:

По суті ж, як я розумію, проблема в тому, що ви робите

CreateProcess( NULL, pTASK2, NULL, NULL...

Дивимося в довідку - третій і четвертий параметр - це

  _In_opt_     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_     LPSECURITY_ATTRIBUTES lpThreadAttributes,

і вони у вас пусті, тобто параметри безпеки типові. Якщо ж ви почитаєте, знову ж таки, довідку, то дізнаєтеся, що типове значення не дозволяє викликати TerminateProcess, вам потрібно виставити флаг PROCESS_TERMINATE.

А де саме виставити флаг PROCESS_TERMINATE? Замість 3-го і 4-го параметрів? Бо программа підкреслює, якщо його там поставити. Я вже пробувала і змінну оголушувати типу LPSECURITY_ATTRIBUTES attrib; і надавати їй значень:

    
attrib->bInheritHandle = TRUE;
attrib->nLength = sizeof(SECURITY_ATTRIBUTES);
attrib->lpSecurityDescriptor = PROCESS_TERMINATE;

Але знову ж таки програмі це не подобається...

7 Востаннє редагувалося koala (27.04.2014 16:03:26)

Re: Процеси

Ви довідку читали?
LP на початку типу означає "long pointer", тобто вказівник (не буду розписувати, чому long), це угорська нотація. Тобто вам не LPSECURITY_ATTRIBUTES треба створити, а SECURITY_ATTRIBUTES і передати посилання на нього. А lpSecurityDescriptor у ньому, відповідно, є посиланням на структуру SECURITY_DESCRIPTOR. Але її треба не прямо створювати, а отримувати відповідною функцією.
Коротше - читайте довідку, там все є, навіть із прикладом.

8 Востаннє редагувалося Rolana (27.04.2014 17:25:48)

Re: Процеси

Щось таке?

    #include "stdafx.h"
#include <windows.h>
#include "string.h"

int main(int argc, char* argv[])

{
STARTUPINFO si[4];
PROCESS_INFORMATION pi[4];
TCHAR path[256] = _T("c:\\abc\\"), startpath[256] = _T("c:\\abc\\");
    TCHAR procname[10][14];
    FILE *f;
    TCHAR buf[14];
    int i = 0, n, pid[3];

    //--------Вичитуємо з файлу назви процесів------------
    fopen_s(&f, "c:\\abc\\TASK.TXT", "rt");
    while (!feof(f))
    {
        _fgetts(procname[i], 14, f);
        _fgetts(buf, 14, f);
        i++;
    }
    fclose(f);
    fopen_s(&f, "c:\\abc\\PROCESS.TXT", "wt");
    SECURITY_ATTRIBUTES sa;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
        pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, 
                             SECURITY_DESCRIPTOR_MIN_LENGTH);
    InitializeSecurityDescriptor(pSD,
            SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(pSD, 
            TRUE,     // bDaclPresent flag   
            pACL, 
            FALSE);
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;
    for (int j = 0; j < i; j++)
    {
        _tcscat_s(path, procname[j]);
        ZeroMemory( &si[j], sizeof(si[j]));
        si[j].cb = sizeof(si[j]);
        ZeroMemory( &pi[j], sizeof(pi[j]));
        if( !CreateProcess( NULL, path, &sa, &sa, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[j], &pi[j]))
        return 0;
        pid[j]=GetProcessId(pi[j].hProcess);
        fprintf(f,"%d\n",pid[j]);
        // Close process and thread handles.
        CloseHandle( pi[j].hProcess );
        CloseHandle( pi[j].hThread );
        for (int k=0; k<14; k++)
        path[k]=startpath[k];

    }
        fclose(f);
            TCHAR pTASK2[] = _T("c:\\abc\\TASK2.exe");
        ZeroMemory( &si[3], sizeof(si[3]));
        si[3].cb = sizeof(si[3]);
        ZeroMemory( &pi[3], sizeof(pi[3]));
        
        if( !CreateProcess( NULL, pTASK2, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[3], &pi[3])) return 0;
                    puts("\n");
            //        WaitForMultipleObjects(4,&pi[4].hProcess,TRUE,INFINITE);
CloseHandle( pi[4].hProcess );
CloseHandle( pi[4].hThread );

return 0;

} 

Я потім ще відредагую зовнішній вигляд програми і fseek поставлю. Просто спочатку хочеться розібратися з головним.

9

Re: Процеси

Rolana написав:

Щось таке?

Не знаю, це вже ви самі дивіться. Якщо вас влаштовує - то мене тим більше.

10

Re: Процеси

В тім то й річ, що результату ніякого)

11

Re: Процеси

Rolana написав:

В тім то й річ, що результату ніякого)

Будь ласка, відписуйте в майбутньому це одразу, а не чекайте, доки перепитають.

Хм... я неуважно читав довідку. Бо

The handle returned by the CreateProcess function has PROCESS_ALL_ACCESS access to the process object.

Тобто проблема, боюся, не в цьому (хоча не певен). Ви не могли б додати до TASK2 перевірку, як завершується процес, і вивід інформації про помилки?

Подякували: Rolana1

12

Re: Процеси

АААааааа! Я не знаю, що я зробила, але запрацювало!!!

TASK1

#include "stdafx.h"
#include <windows.h>
#include "string.h"

int main(int argc, char* argv[])

{
STARTUPINFO si[4];
PROCESS_INFORMATION pi[4];
TCHAR path[256] = _T("c:\\abc\\"), startpath[256] = _T("c:\\abc\\");
    TCHAR procname[10][14];
    FILE *f;
    TCHAR buf[14];
    int i = 0, n, pid[3];

    //--------Вичитуємо з файлу назви процесів------------
    fopen_s(&f, "c:\\abc\\TASK.TXT", "rt");
    while (!feof(f))
    {
        _fgetts(procname[i], 14, f);
        _fgetts(buf, 14, f);
        i++;
    }
    fclose(f);
    fopen_s(&f, "c:\\abc\\PROCESS.TXT", "wt");
    for (int j = 0; j < i; j++)
    {
        _tcscat_s(path, procname[j]);
        ZeroMemory( &si[j], sizeof(si[j]));
        si[j].cb = sizeof(si[j]);
        ZeroMemory( &pi[j], sizeof(pi[j]));
        if( !CreateProcess( NULL, path, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[j], &pi[j]))
        return 0;
        pid[j]=GetProcessId(pi[j].hProcess);
        fprintf(f,"%d\n",pid[j]);
        // Close process and thread handles.
        CloseHandle( pi[j].hProcess );
        CloseHandle( pi[j].hThread );
        for (int k=0; k<14; k++)
        path[k]=startpath[k];

    }
        fclose(f);
            TCHAR pTASK2[] = _T("c:\\abc\\TASK2.exe");
        ZeroMemory( &si[3], sizeof(si[3]));
        si[3].cb = sizeof(si[3]);
        ZeroMemory( &pi[3], sizeof(pi[3]));
        
        if( !CreateProcess( NULL, pTASK2, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | NORMAL_PRIORITY_CLASS, NULL, NULL, &si[3], &pi[3])) return 0;
                    puts("\n");
            //        WaitForMultipleObjects(4,&pi[4].hProcess,TRUE,INFINITE);
CloseHandle( pi[4].hProcess );
CloseHandle( pi[4].hThread );

return 0;

} 

TASK2

#include "stdafx.h"
#include <windows.h> 
#include <strsafe.h>
FILE *f;

void ErrorExit1(LPTSTR lpszFunction) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}

void ErrorExit2(LPTSTR lpszFunction, HANDLE hPr) 
{ 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw =     GetExitCodeProcess(hPr, &dw);; 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK); 

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
    ExitProcess(dw); 
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hPr;
    int pid[100], i=0, processID;
    bool flag=false;
    fopen_s(&f,"c:\\abc\\PROCESS.txt","rt");
    while (!feof(f))
    {
        fscanf_s(f,"%d\n",&pid[i]);
        printf("%d\n",pid[i]);
        i++;
    }
    while (flag==false)
    {
        printf("Enter the process ID to destroy --> ");
        scanf_s("%d",&processID);
        for (int j=0; j<i; j++)
            if (pid[j]==processID) flag=true;        
        if (flag==false) printf("Bad pid. Try again\n");
    }
    hPr = OpenProcess(PROCESS_TERMINATE,TRUE,processID);
    if(hPr != NULL)
    {
        TerminateProcess(hPr,0);
        ErrorExit1(TEXT("TerminateProcess"));
        //ErrorExit2(TEXT("TerminateProcess"), hPr);
    }
    return 0;
}

13

Re: Процеси

Дуже-дуже-дуже дякую! *YAHOO*  *YAHOO*  *YAHOO*