Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4]      все
 Re: CreateProcess-аналог AllocConsole  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
чччД__,

Посмотрим
8 июн 18, 08:07    [21477872]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
SOFT FOR YOU,

- Если что - то работает, это не значит, что оно работает - именно так, как ты хочешь (С)

ошибка происходит на строке
t := Cardinal(nil^);


потому в консольном приложение eax будет пустым, и не от куда будет взять нижнюю ступень - AV

проверяй
+
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

var
  t: Cardinal;

begin
  try
    t := Cardinal(nil^);
    Writeln(t);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

  Readln;

end.
8 июн 18, 09:18    [21478000]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
руки дошли сделать поиск в кодах среды.
8 июн 18, 09:50    [21478096]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
руки дошли сделать поиск в кодах среды.

К сообщению приложен файл. Размер - 57Kb
8 июн 18, 09:51    [21478098]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
kloun02
Member

Откуда:
Сообщений: 7132
Кукареку,

var параметр, учи матчасть.
8 июн 18, 10:18    [21478186]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
kloun02,

Спасибо КЭП! Куда мы без тебя. Весь мир пойдет по трантарары


речь шла о том, что "SOFT FOR YOU" делал такую дичь
t := Cardinal(nil^);



Что же ты ему не кинулся ошибку ЕГО то показывать? за то решил показать свой тугенький ум на мне )))
8 июн 18, 10:59    [21478351]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
kloun02
Member

Откуда:
Сообщений: 7132
Кукареку
kloun02,

Спасибо КЭП! Куда мы без тебя. Весь мир пойдет по трантарары


речь шла о том, что "SOFT FOR YOU" делал такую дичь
t := Cardinal(nil^);




Что же ты ему не кинулся ошибку ЕГО то показывать? за то решил показать свой тугенький ум на мне )))
Нет, эту дичь делал ты, исключительно. В коде мегаотца все было в пределах нормы.
8 июн 18, 11:23    [21478422]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 7218
чччД__
CreateProcess function

Как бы толстый намёк
The calling thread can use the WaitForInputIdle function to wait until the new process has finished its initialization and is waiting for user input with no input pending. This can be useful for synchronization between parent and child processes, because CreateProcess returns without waiting for the new process to finish its initialization. For example, the creating process would use WaitForInputIdle before trying to find a window associated with the new process.

Только учти, что WaitForInputIdle применительно к cmd.exe приложения тебе не поможет:
Ибо
...If this process is a console application or does not have a message queue, WaitForInputIdle returns immediately...

Ибо приложение cmd.exe не использует очередь сообщений.

Для console application мы же вполне может ридерект StdInput, StdOutput использовать.
Нельзя ли как-то к ним привязаться? Например, cmd.exe ждет ввода в StdInput, значит проинициализировалась.

Но вообще, задача топикстартера выглядит как-то диковато. Лично я, в свое время, наоборот рисовал свое окошко и направлял туда вывод консольных приложений, что бы выглядело более-менее "прилично" и вывод внешнего приложения не выпадал из дизайна.

Алоцировать консоль, что бы туда что-то выводить.... Мне не очень понятно. А особенно, с такими мучениями и "кривостями" как воровство чужой консоли (((
8 июн 18, 11:38    [21478503]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
kloun02
Нет, эту дичь делал ты, исключительно. В коде мегаотца все было в пределах нормы.


Ты просто слепой - как котенок, который появился только что на свет. Защищаешь его, думая что он властелин кода - говно кода

Вот его сообщения, где он делал эту дичь
+
SOFT FOR YOU
Стал тестировать на Windows иногда (при некоторых стартах) возникает ошибка System Error. Code 6. Неверный дескриптор
Может на Windows X тоже бывает ошибка, но повторить не успел

Ошибка возникает здесь:
Win32Check(WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), AText, ATextLength,  DWORD(nil^) , nil));


Причём в обоих случаях, как в рабочем случае, так и в нерабочем, GetStdHandle(STD_OUTPUT_HANDLE) возвращает 7
У кого какие идеи, как это можно исправить?

Возникает ощущение, что STD_OUTPUT_HANDLE не успевает приаттачиться к консоли
С другой стороны все функции типа GetConsoleScreenBufferInfo/SetConsoleCursorPosition/GetLargestConsoleWindowSize - отрабатывают корректно


SOFT FOR YOU
Удивительно

Вот такой обрабатывается нормально:
    while (not AttachConsole(ProcInfo.dwProcessId)) do
      Sleep(10);

    Buffer[0] := #0;
    while (not WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), @Buffer, 1,  Cardinal(nil^) , 0)) do
    begin
      Inc(COUNTER);
      Sleep(50);
    end;
    COUNTER := COUNTER;


А если сделать Sleep(1) - то второй цикл становится бесконечным
Ну и как это решить?
Увеличить Sleep не предлагать. Должно быть какое-то здоровое решение


и если после этого ты продолжишь гнуть свою палку, то ты просто его попа лиз
8 июн 18, 11:49    [21478559]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
Я бы такого работника SOFT FOR YOU , сразу уволил после такого кода

К сообщению приложен файл. Размер - 31Kb
8 июн 18, 11:54    [21478572]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
kloun02
Member

Откуда:
Сообщений: 7132
Кукареку
Вот его сообщения, где он делал эту дичь

Слушай, что я тебе скажу, птичка..(с)
Я видел весь код этого топика, и указал тебе твои пробелы в знаниях 21478186

Тебе бы вместо разбрасывания соплей по форуму, взять бы да попробовать скомпилить его код.
8 июн 18, 11:56    [21478584]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
И вот, что бы сразу все вопросы отпали. Типа - мол есть какая то проверка на nil указатель (от куда бы ему взяться ? И все равно бы не помогло)

К сообщению приложен файл. Размер - 31Kb
8 июн 18, 11:57    [21478591]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Кукареку
Guest
kloun02,

Все. Ты его попа лиз. Официально заявлено и подтверждено!
8 июн 18, 11:58    [21478599]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
kloun02
Member

Откуда:
Сообщений: 7132
Кукареку
kloun02,

Все. Ты его попа лиз. Официально заявлено и подтверждено!
Болезный на вот тебе
procedure Test(var i: Cardinal);
begin
  if @i <> nil then
    i := 3465;
end;
8 июн 18, 12:04    [21478638]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
SOFT FOR YOU
Member [заблокирован]

Откуда:
Сообщений: 2761
Кукареку,

Ты заколебал


Leonid Kudryavtsev,

Я не против других решений
Задача - аллоцировать невидимую консоль


All,

Можно почитать и вдохновиться. Я пока повременю :)

+
BOOL WINAPI AllocConsole(void)
{
    HANDLE      handle_in = INVALID_HANDLE_VALUE;
    HANDLE      handle_out = INVALID_HANDLE_VALUE;
    HANDLE      handle_err = INVALID_HANDLE_VALUE;
    STARTUPINFOA        siCurrent;
    STARTUPINFOA    siConsole;
    char                buffer[1024];

    TRACE("()\n");

    handle_in = OpenConsoleW( coninW, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
                              FALSE, OPEN_EXISTING );

    if (VerifyConsoleIoHandle(handle_in))
    {
    /* we already have a console opened on this process, don't create a new one */
    CloseHandle(handle_in);
    return FALSE;
    }

    /* invalidate local copy of input event handle */
    console_wait_event = 0;

    GetStartupInfoA(&siCurrent);

    memset(&siConsole, 0, sizeof(siConsole));
    siConsole.cb = sizeof(siConsole);
    /* setup a view arguments for wineconsole (it'll use them as default values)  */
    if (siCurrent.dwFlags & STARTF_USECOUNTCHARS)
    {
        siConsole.dwFlags |= STARTF_USECOUNTCHARS;
        siConsole.dwXCountChars = siCurrent.dwXCountChars;
        siConsole.dwYCountChars = siCurrent.dwYCountChars;
    }
    if (siCurrent.dwFlags & STARTF_USEFILLATTRIBUTE)
    {
        siConsole.dwFlags |= STARTF_USEFILLATTRIBUTE;
        siConsole.dwFillAttribute = siCurrent.dwFillAttribute;
    }
    if (siCurrent.dwFlags & STARTF_USESHOWWINDOW)
    {
        siConsole.dwFlags |= STARTF_USESHOWWINDOW;
        siConsole.wShowWindow = siCurrent.wShowWindow;
    }
    /* FIXME (should pass the unicode form) */
    if (siCurrent.lpTitle)
        siConsole.lpTitle = siCurrent.lpTitle;
    else if (GetModuleFileNameA(0, buffer, sizeof(buffer)))
    {
        buffer[sizeof(buffer) - 1] = '\0';
        siConsole.lpTitle = buffer;
    }

    if (!start_console_renderer(&siConsole))
    goto the_end;

    if( !(siCurrent.dwFlags & STARTF_USESTDHANDLES) ) {
        /* all std I/O handles are inheritable by default */
        handle_in = OpenConsoleW( coninW, GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,
                                  TRUE, OPEN_EXISTING );
        if (handle_in == INVALID_HANDLE_VALUE) goto the_end;
  
        handle_out = OpenConsoleW( conoutW, GENERIC_READ|GENERIC_WRITE,
                                   TRUE, OPEN_EXISTING );
        if (handle_out == INVALID_HANDLE_VALUE) goto the_end;
  
        if (!DuplicateHandle(GetCurrentProcess(), handle_out, GetCurrentProcess(),
                    &handle_err, 0, TRUE, DUPLICATE_SAME_ACCESS))
            goto the_end;
    } else {
        /*  STARTF_USESTDHANDLES flag: use handles from StartupInfo */
        handle_in  =  siCurrent.hStdInput;
        handle_out =  siCurrent.hStdOutput;
        handle_err =  siCurrent.hStdError;
    }

    /* NT resets the STD_*_HANDLEs on console alloc */
    SetStdHandle(STD_INPUT_HANDLE,  handle_in);
    SetStdHandle(STD_OUTPUT_HANDLE, handle_out);
    SetStdHandle(STD_ERROR_HANDLE,  handle_err);

    SetLastError(ERROR_SUCCESS);

    return TRUE;

 the_end:
    ERR("Can't allocate console\n");
    if (handle_in != INVALID_HANDLE_VALUE)  CloseHandle(handle_in);
    if (handle_out != INVALID_HANDLE_VALUE) CloseHandle(handle_out);
    if (handle_err != INVALID_HANDLE_VALUE) CloseHandle(handle_err);
    FreeConsole();
    return FALSE;
}

static  BOOL    start_console_renderer_helper(const char* appname, STARTUPINFOA* si,
                                              HANDLE hEvent)
{
    char        buffer[1024];
    int                 ret;
    PROCESS_INFORMATION pi;

    /* FIXME: use dynamic allocation for most of the buffers below */
    ret = snprintf(buffer, sizeof(buffer), "%s --use-event=%ld", appname, (DWORD_PTR)hEvent);
    if ((ret > -1) && (ret < sizeof(buffer)) &&
        CreateProcessA(NULL, buffer, NULL, NULL, TRUE, DETACHED_PROCESS,
                       NULL, NULL, si, &pi))
    {
        HANDLE  wh[2];
        DWORD   res;

        wh[0] = hEvent;
        wh[1] = pi.hProcess;
        res = WaitForMultipleObjects(2, wh, FALSE, INFINITE);

        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);

        if (res != WAIT_OBJECT_0) return FALSE;

        TRACE("Started wineconsole pid=%08x tid=%08x\n",
              pi.dwProcessId, pi.dwThreadId);

        return TRUE;
    }
    return FALSE;
}

static  BOOL    start_console_renderer(STARTUPINFOA* si)
{
    HANDLE      hEvent = 0;
    LPSTR       p;
    OBJECT_ATTRIBUTES   attr;
    BOOL                ret = FALSE;

    attr.Length                   = sizeof(attr);
    attr.RootDirectory            = 0;
    attr.Attributes               = OBJ_INHERIT;
    attr.ObjectName               = NULL;
    attr.SecurityDescriptor       = NULL;
    attr.SecurityQualityOfService = NULL;

    NtCreateEvent(&hEvent, EVENT_ALL_ACCESS, &attr, NotificationEvent, FALSE);
    if (!hEvent) return FALSE;

    /* first try environment variable */
    if ((p = getenv("WINECONSOLE")) != NULL)
    {
        ret = start_console_renderer_helper(p, si, hEvent);
        if (!ret)
            ERR("Couldn't launch Wine console from WINECONSOLE env var (%s)... "
                "trying default access\n", p);
    }

    /* then try the regular PATH */
    if (!ret)
        ret = start_console_renderer_helper("wineconsole", si, hEvent);

    CloseHandle(hEvent);
    return ret;
}
8 июн 18, 12:22    [21478690]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
kloun02
Member

Откуда:
Сообщений: 7132
Кукареку,

жду официальных опровержений
8 июн 18, 12:44    [21478784]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10652
SOFT FOR YOU
А тебя не наталкивает на какую-то мысль, что ты при таком раскладе ловишь AV, а я нет? ;)
Справедливости ради
lpNumberOfCharsWritten [out]
A pointer to a variable that receives the number of characters actually written.
Про optional ничего нет, хотя MS обычно о таких вещах пишет
8 июн 18, 12:51    [21478824]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
чччД__
Guest
Leonid Kudryavtsev
...Лично я, в свое время, наоборот рисовал свое окошко и направлял туда вывод консольных приложений, что бы выглядело более-менее "прилично" и вывод внешнего приложения не выпадал из дизайна.
...

+1
8 июн 18, 15:47    [21479551]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Василий 2
Member

Откуда:
Сообщений: 314
Передача (nil)^ в var-параметр - хоть и смахивает на хак, но работает корректно. Компилятор не вычисляет это выражение, а сразу пишет 0:
procedure Test(a: Byte; var i: Byte);
begin

end;

Test(10, PByte(nil)^);

RTDecoder.dpr.17: Test(10, PByte(nil)^);
00747588 33D2             xor edx,edx
0074758A B00A             mov al,$0a
0074758C E88F49FFFF       call Test

НО! Это подходит только для необязательных var параметров (те, которые предварительно проверяются как указатели - через @param для функций Delphi или объявлены указателями для импортированных функций). Как только функция попытается использовать значение параметра - случится бадабум.
15 июн 18, 11:28    [21493209]     Ответить | Цитировать Сообщить модератору
 Re: CreateProcess-аналог AllocConsole  [new]
Василий 2
Member

Откуда:
Сообщений: 314
Василий 2
НО! Это подходит только для необязательных var параметров (те, которые предварительно проверяются как указатели - через @param для функций Delphi или объявлены указателями для импортированных функций). Как только функция попытается использовать значение параметра - случится бадабум.

...или те, которые не используются при некоторых условиях. Например, вот такая конструкция также будет работать: Move(Src, (nil)^, 0);
15 июн 18, 11:30    [21493216]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4]      все
Все форумы / Delphi Ответить