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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 21.05.2016, 16:50   #1
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию Нужна помощь с консольной программой

Привет народ. Пишу программу которая при определенных обстоятельствах удаляет сама себя. Пишу на делфи, си незнаю. Для того чтобы было такое возможно, хочу попросить вас написать маленькую консольную утилиту в которую в качестве параметра будет передано имя файла. Утилита должна подождать пока программа закроется и удалить его. Я код этой утилиты хочу встроить в код своей программы и при необходимости распаковать и запустить. Самому мешает сделать такое размер файла написанного на делфи. Либо если есть готовое решение подскажите.
Давлю тараканов

Последний раз редактировалось casus; 21.05.2016 в 16:59. Причина: дополнение.
casus вне форума Ответить с цитированием
Старый 21.05.2016, 17:41   #2
wowks
 
Аватар для wowks
 
Регистрация: 20.05.2016
Сообщений: 8
По умолчанию

вот программа. Она получает в качестве аргумента путь к файлу
принцип работы такой.
функция IsProcessRunning может получить в качестве аргумента либо имя процесса либо путь/имя. Если даёшь ей путь/имя, то проверяется ещё и путь запущенного процесса, чтоб не было путаницы, тк могут быть одинаковые имена процесса но разные пути к их экзешникам.
Если процесс активен, то запускаем ожидание через WaitForSingleObject и как только процесс убьётся удаляем файл.
Код выхода программы при ошибке EXIT_FAILURE (= 1) или EXIT_SUCCESS (= 0), если всё отработало правильно.
Программа написана на C++. Я тоже раньше сидел на Делфи, но при этом мог читать сишный код, потому как языки разные а суть одна (я только предварительно почитал синтаксис на википедии и немнго про функции стандартной библиотеки си типа swprintf, wcslen, wcscpy, ...)
Ты тоже, думаю, разберёшься
вот исходник:

Код:
#include <iostream>
#include <windows.h>

bool GetProcessDir(DWORD ProcessID, wchar_t * Dir) {
    bool res = false;
    HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessID);
    if (hProcess != NULL) {
        wchar_t * proc_buff = (wchar_t *) calloc(MAX_PATH, sizeof(wchar_t));
        if (proc_buff != NULL) {
            if (::GetProcessImageFileNameW(hProcess, proc_buff, MAX_PATH)) {
                wchar_t * device_buff = (wchar_t *) calloc(MAX_PATH, sizeof(wchar_t));
                if (device_buff != NULL) {
                    DWORD Drives = ::GetLogicalDrives();
                    if (Drives != 0) {
                        wchar_t DriveLetter[3] = {L'A', L':', L'\0'};
                        do {
                            if (Drives & 0x00000001) {
                                if (::QueryDosDeviceW(DriveLetter, device_buff, MAX_PATH)) { // QueryDosDeviceW возвращает неправильную длину, поэтому сравнить строки
                                    const size_t device_len = wcslen(device_buff);
                                    if (wcsnicmp(proc_buff, device_buff, device_len) == 0) {
                                        swprintf(Dir, L"%ls%ls", DriveLetter, &proc_buff[device_len]);
                                        res = true;
                                    }
                                }
                            }
                            DriveLetter[0]++;
                            Drives >>= 1;
                        }
                        while (Drives != 0);
                    }
                    free(device_buff);
                }
            }
            free(proc_buff);
        }
        ::CloseHandle(hProcess);
    }
    return res;
}

#define PATH_SEPARATOR_TYPE_1 L'\\'
#define PATH_SEPARATOR_TYPE_2 L'/'

#define ___is_path_separator(path_char) \
    ((path_char == PATH_SEPARATOR_TYPE_1) || (path_char == PATH_SEPARATOR_TYPE_2)) \

wchar_t * ExtractFilePath(const wchar_t * Path, wchar_t * FilePath = NULL) {
    register size_t x = wcslen(Path);
    while (x > 0) {
        x--;
        if (___is_path_separator(Path[x])) {
            break;
        }
    }
    if (FilePath == NULL) {
        FilePath = (wchar_t *) calloc(x + 1, sizeof(wchar_t));
        if (FilePath == NULL) {
            goto finish;
        }
    }
    wcsncpy(FilePath, Path, x);
    FilePath[x] = L'\0';
finish:
    return FilePath;
}

wchar_t * ExtractFileName(const wchar_t * Path, wchar_t * FileName = NULL) {
    register const size_t PathLen = wcslen(Path);
    register size_t x = PathLen;
    while (x > 0) {
        x--;
        if (___is_path_separator(Path[x])) {
            x++;
            break;
        }
    }
    if (FileName == NULL) {
        FileName = (wchar_t *) calloc(PathLen - x, sizeof(wchar_t));
        if (FileName == NULL) {
            goto finish;
        }
    }
    wcsncpy(FileName, &Path[x], PathLen - x);
    FileName[PathLen - x] = L'\0';
finish:
    return FileName;
}

bool IsProcessRunning(const wchar_t * ProcessName, DWORD * ProcessID = NULL) {
    bool found = false;
    PROCESSENTRY32W * pe = (PROCESSENTRY32W *) malloc(sizeof(PROCESSENTRY32W));
    if (pe != NULL) {
        HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (hSnapshot != INVALID_HANDLE_VALUE) {
            pe->dwSize = sizeof(PROCESSENTRY32W);
            wchar_t * FilePath = ExtractFilePath(ProcessName);
            wchar_t * FileName = ExtractFileName(ProcessName);
        #define ___empty_str(str) (wcscmp(str, L"") == 0)
            if ((FilePath != NULL) && (FileName != NULL) && ( ! ___empty_str(FileName))) {
                if (::Process32FirstW(hSnapshot, pe)) {
                    do {
                        if (wcsicmp(FileName, pe->szExeFile) == 0) {
                            if ( ! ___empty_str(FilePath)) {
                                wchar_t * buff = (wchar_t *) calloc(MAX_PATH, sizeof(wchar_t));
                                if (buff != NULL) {
                                    if (GetProcessDir(pe->th32ProcessID, buff)) {
                                        if (wcsicmp(ProcessName, buff) == 0) {
                                            found = true;
                                        }
                                    }
                                    free(buff);
                                }
                            } else {
                                found = true;
                            }
                        }
                        if (found) {
                            if (ProcessID != NULL) {
                                *ProcessID = pe->th32ProcessID;
                            }
                            break;
                        }
                    } while (::Process32NextW(hSnapshot, pe));
                }
            }
            if (FilePath != NULL) {
                free(FilePath);
            }
            if (FileName != NULL) {
                free(FileName);
            }
            ::CloseHandle(hSnapshot);
        }
        free(pe);
    }
    return found;
}

/* тоже вариант (вызывать в цикле ::GetExitCodeProcess в купе со ::Sleep(1), чтоб не загружать по максимуму ядро) вместо ::WaitForSingleObject 
bool IsProcessAlive(const DWORD ProcessID) {
    bool res = false;
    HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessID);
    if (hProcess != NULL) {
        DWORD ExitCode;
        res = ((::GetExitCodeProcess(hProcess, &ExitCode)) &&
               (ExitCode == STILL_ACTIVE));
        ::CloseHandle(hProcess);
    }
    return res;
}
*/


bool GetCommandLineArg(wchar_t * Arg) {
    bool res = false;
    wchar_t ** ArgList;
    int NumArgs;
    ArgList = ::CommandLineToArgvW(::GetCommandLineW(), &NumArgs);
    if (ArgList != NULL) {
        if (NumArgs > 1) {
            wcscpy(Arg, ArgList[1]);
            res = true;
        }
        ::LocalFree(ArgList);
    }
    return res;
}


int main() {
    int res = EXIT_FAILURE;

    wchar_t FileName[MAX_PATH];
    DWORD ProcessID;
    if (GetCommandLineArg(FileName) && IsProcessRunning(FileName, &ProcessID)) {

        HANDLE hProcess = ::OpenProcess(SYNCHRONIZE, FALSE, ProcessID);
        if (hProcess != NULL) {
run_wait_again:
            switch (::WaitForSingleObject(hProcess, INFINITE)) {
                case WAIT_OBJECT_0: {
                    if (::DeleteFileW(FileName)) {
                        res = EXIT_SUCCESS;
                    }
                } break;

                case WAIT_TIMEOUT: {
                    goto run_wait_again;
                }

                default:
                    // например WAIT_FAILED
                    break;
            }

            ::CloseHandle(hProcess);
        }
    }

    return res;
}

Последний раз редактировалось wowks; 21.05.2016 в 18:05.
wowks вне форума Ответить с цитированием
Старый 21.05.2016, 18:12   #3
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию

Спасибо, буду пробовать. Думаю что работать обязана.
Можно даже Sleep 100. За это время пользователь ничего сделать не успеет.
Программа будет ждать секунду после ввода пароля, и соответственно запускаться в ед. экземпляре чтобы исключить брутфорс потоком.
Остальное ломать бесполезно так как приложение клиент-серверное.
Откомпилишь? Чтобы из-за кусочка кода не качать/ставить компилятор.
Давлю тараканов

Последний раз редактировалось casus; 21.05.2016 в 18:20.
casus вне форума Ответить с цитированием
Старый 21.05.2016, 18:40   #4
wowks
 
Аватар для wowks
 
Регистрация: 20.05.2016
Сообщений: 8
По умолчанию

casus
вот архив. Там скомпилировано для x86 и x64 + исходник + пример в .cmd файле
https://mega.nz/#!lkgU0KDQ!XLhfk0_hJ...9ux4H6S4wBsOjI

Последний раз редактировалось wowks; 21.05.2016 в 18:43.
wowks вне форума Ответить с цитированием
Старый 21.05.2016, 18:46   #5
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию

Спасибо огромное! Если чего неполучится то допилю.
Уже год пытаюсь забыть паскаль и начать программировать.
Давлю тараканов

Последний раз редактировалось casus; 21.05.2016 в 18:49.
casus вне форума Ответить с цитированием
Старый 21.05.2016, 19:18   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,656
По умолчанию

не понимаю, а удалять-то зачем? как это поможет?
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 21.05.2016, 19:49   #7
casus
Пользователь
 
Аватар для casus
 
Регистрация: 12.03.2013
Сообщений: 28
По умолчанию

Причин несколько, издевательство над пользователем при его неправельном ответе на вопрос программы, например Uninstall, примитивный антидебаг, антибрутфорс.
Вот представь как бы хорошо жилось людям, если бы например играя в танки у пользователя удалялся акк и игра при проиграшах 30 раз подряд. Да и для психики пользователя это бы пошло на пользу))
Давлю тараканов
casus вне форума Ответить с цитированием
Старый 21.05.2016, 20:07   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,656
По умолчанию

Цитата:
Вот представь как бы хорошо жилось людям, если бы например играя в танки у пользователя удалялся акк и игра при проиграшах 30 раз подряд. Да и для психики пользователя это бы пошло на пользу))
да, да! конечно хорошо бы жилось людям. конечно на пользу пошло бы!


а удаление аккаунта в ВоТ - супер бонус для правообладателей, ога.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 21.05.2016, 21:46   #9
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,964
По умолчанию

Провокатор, мать, мать , мать!
Изображения
Тип файла: jpg 66366843_esli-papa-programmist.jpg (64.6 Кб, 45 просмотров)
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder
Smitt&Wesson вне форума Ответить с цитированием
Старый 21.05.2016, 22:02   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,656
По умолчанию

если папа - лох, будет нумерация, как на этом демотиваторе.
программисты нумеруют с нуля!
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Нужна помощь с программой Ддмитрий Фриланс 1 28.11.2009 16:27
Нужна помощь с программой... Joker_35815 Фриланс 14 16.11.2009 14:48
Нужна помощь с программой... Joker_35815 Фриланс 1 12.11.2009 10:54
Нужна помощь с программой ООП на С++ Vofka Фриланс 3 30.11.2007 16:52