purebasic.info

PureBasic forum
Текущее время: Сб дек 16, 2017 11:32 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Консоль
СообщениеДобавлено: Сб июл 08, 2017 2:48 pm 
Не в сети
профессор

Зарегистрирован: Вс авг 31, 2014 12:11 am
Сообщений: 390
Благодарил (а): 49 раз.
Поблагодарили: 18 раз.
Пункты репутации: 10
Как можно подключиться к уже запущенной консоли/процессу? По типу как #PB_Program_Write после RunProgram(), но его использовать нельзя так как открывается ещё одно консольное окно. Хэндл консольного окна (уже запущенного) известен и сейчас могу отправлять различные команды в него (SendMessage_), НО мне нужно чтобы самих команд не было видно, а только результат их выполнения. @echo off не помогает. Кто подскажет?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Сб июл 08, 2017 7:40 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 545
Благодарил (а): 2 раз.
Поблагодарили: 30 раз.
Пункты репутации: 9
Не понятно мне одно раз pid окна известен,то зачем нужен как говоришь запуск для общения с ним,а не просто обращения к этому запущенному окну?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Сб июл 08, 2017 7:55 pm 
Не в сети
профессор

Зарегистрирован: Вс авг 31, 2014 12:11 am
Сообщений: 390
Благодарил (а): 49 раз.
Поблагодарили: 18 раз.
Пункты репутации: 10
Сергейчик, как раз говорил об обратном, что нельзя использовать RunProgram() или OpenConsole() потому как это породит новое окно, а надо работать с тем что уже существует. Сейчас могу отправить в окно строку с нужной командой и она отобразится, чего быть не должно. Это равносильно тому, что в открытой консоли вводить команды с клавиатуры. Вот и думал как-то "приаттачиться" к уже существующему процессу с получением доступа и отправлять строку в stdin.
Как ещё подробней объяснить-то? Вот к примеру два "батника":

1.cmd
Код:
1
2
echo 12345
pause


и
2.cmd
Код:
1
2
3
@echo off
echo 12345
pause


Вот второй-то вариант и нужно получить в итоге, но как?

Добавлено:
Извини, поправлю: pid = processID; хэндл окна - это другое.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Вс июл 09, 2017 8:41 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 545
Благодарил (а): 2 раз.
Поблагодарили: 30 раз.
Пункты репутации: 9
Я понял изначально так запущенное чужое окно проги и с ним нужно общение из своей напрямую ,или ты хочешь сказать что окно к обращаемой проги не запущено нет процесса этой проги и ты хочешь что то получить от её тела(функций)?


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Вс июл 09, 2017 3:12 pm 
Не в сети
профессор
Аватар пользователя

Зарегистрирован: Чт июн 25, 2009 1:02 pm
Сообщений: 2232
Откуда: Russia — Belarus
Благодарил (а): 0 раз.
Поблагодарили: 66 раз.
Пункты репутации: 11
А я понял так:
Запущено (работает) консольное приложение (сервер например, какой-нибудь) и ему (в его консоль) надо отсылать команды из PureBasic команды, но при этом не простой отсылкой символов (команд) в окно консоля, ибо палево.

_________________
EnableExplicit User


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Вс июл 09, 2017 9:36 pm 
Не в сети
профессор

Зарегистрирован: Вс авг 31, 2014 12:11 am
Сообщений: 390
Благодарил (а): 49 раз.
Поблагодарили: 18 раз.
Пункты репутации: 10
Сергейчик, не заморачивайся более. Мне уже помогли. Ниже приведу код. Может он прояснит то, чего я добивался и о чём изначально спрашивал. Больше не знаю как объяснить.

qpAHToMAS, примерно так.

Собственно код, налетайте :D
Код:
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#SystemProcessInformation = 5
 
Structure UNICODE_STRING Align #PB_Structure_AlignC
  Length.w
  MaximumLength.w
  Buffer.i
EndStructure
 
Structure VM_COUNTERS
  PeakVirtualSize.l
  VirtualSize.l
  PageFaultCount.l
  PeakWorkingSetSize.l
  WorkingSetSize.l
  QuotaPeakPagedPoolUsage.l
  QuotaPagedPoolUsage.l
  QuotaPeakNonPagedPoolUsage.l
  QuotaNonPagedPoolUsage.l
  PagefileUsage.l
  PeakPagefileUsage.l
EndStructure
 
Structure IO_COUNTERS
  ReadOperationCount.LARGE_INTEGER
  WriteOperationCount.LARGE_INTEGER
  OtherOperationCount.LARGE_INTEGER
  ReadTransferCount.LARGE_INTEGER
  WriteTransferCount.LARGE_INTEGER
  OtherTransferCount.LARGE_INTEGER
EndStructure
 
Structure SYSTEM_THREAD
  KernelTime.LARGE_INTEGER
  UserTime.LARGE_INTEGER
  CreateTime.LARGE_INTEGER
  WaitTime.l
  StartAddress.l
  UniqueProcess.l
  UniqueThread.l
  Priority.l
  BasePriority.l
  ContextSwitchCount.l
  State.l
  WaitReason.l
  Reserved1.l
EndStructure
 
Structure SYSTEM_PROCESS_INFORMATION
  NextEntryOffset.l
  NumberOfThreads.l
  Reserved1.LARGE_INTEGER[3]
  CreateTime.LARGE_INTEGER
  UserTime.LARGE_INTEGER
  KernelTime.LARGE_INTEGER
  ModuleName.UNICODE_STRING
  BasePriority.i
  ProcessID.l
  InheritedFromProcessId.l
  HandleCount.l
  Reserved2.l[2]
  VirtualMemoryCounters.VM_COUNTERS
  PrivatePageCount.l
  IOCounters.IO_COUNTERS
  ThreadInfo.SYSTEM_THREAD[0]
EndStructure
 
Prototype protoAttachConsole(dwProcessId)
 
Procedure cmdGetProcessId(ModuleName.s)
  *spi.SYSTEM_PROCESS_INFORMATION
  *spi = AllocateMemory(1024 * 1024)
  NtQuerySystemInformation_(#SystemProcessInformation, *spi, MemorySize(*spi), #Null)
  *spi\ModuleName\Buffer = AllocateMemory(#MAX_PATH)
 
  While *spi\NextEntryOffset
    If LCase(PeekS(*spi\ModuleName\Buffer, *spi\ModuleName\Length, #PB_Unicode)) = ModuleName
      dwProcessId = *spi\ProcessID : Break
    Else
      *spi + *spi\NextEntryOffset
    EndIf
  Wend
  ProcedureReturn dwProcessId
EndProcedure
 
Procedure.l cmdOpenConsole(dwProcessId)
  Protected AttachConsole.protoAttachConsole
 
  kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
 
  If IsLibrary(kernel32)
    AttachConsole = GetFunction(kernel32, "AttachConsole")
 
    If AttachConsole(dwProcessId) : hStdInput.l = GetStdHandle_(#STD_INPUT_HANDLE) : EndIf
 
    CloseLibrary(kernel32)
  EndIf
  ProcedureReturn hStdInput
EndProcedure
 
Procedure cmdAddAlias(Source.s, Target.s)
  ProcedureReturn AddConsoleAlias_(Source, Target, "cmd.exe")
EndProcedure
 
Procedure cmdRunScript(hStdInput.l, ScriptText.s, RunAndWait = #False)
  ScriptText + Chr(13)
  nLength = Len(ScriptText) + 1
 
  If nLength > 1
    Dim lpBuffer.INPUT_RECORD(nLength)
 
    For rtnCount = 0 To nLength - 2
      ascKey = Asc(Mid(ScriptText, rtnCount + 1, 1))
      vkKey = VkKeyScanEx_(ascKey, GetKeyboardLayout_(0)) & $FF
      lpBuffer(rtnCount)\EventType = #KEY_EVENT
      lpBuffer(rtnCount)\Event\KeyEvent\bKeyDown = #True
      lpBuffer(rtnCount)\Event\KeyEvent\dwControlKeyState = 0
      lpBuffer(rtnCount)\Event\KeyEvent\uChar = ascKey
      lpBuffer(rtnCount)\Event\KeyEvent\wRepeatCount = 1
      lpBuffer(rtnCount)\Event\KeyEvent\wVirtualKeyCode = vkKey
      lpBuffer(rtnCount)\Event\KeyEvent\wVirtualScanCode = MapVirtualKey_(vkKey, 0)
    Next
    lpBuffer(nLength - 1)\EventType = #KEY_EVENT
    lpBuffer(nLength - 1)\Event\KeyEvent\bKeyDown = #True
    lpBuffer(nLength - 1)\Event\KeyEvent\dwControlKeyState = 0
    lpBuffer(nLength - 1)\Event\KeyEvent\uChar = #VK_RETURN
    lpBuffer(nLength - 1)\Event\KeyEvent\wRepeatCount = 1
    lpBuffer(nLength - 1)\Event\KeyEvent\wVirtualKeyCode = #VK_RETURN
    lpBuffer(nLength - 1)\Event\KeyEvent\wVirtualScanCode = MapVirtualKey_(#VK_RETURN, 0)
    WriteConsoleInput_(hStdInput, @lpBuffer(), nLength, @lpNumberOfCharsWritten)
 
    If RunAndWait
      Repeat
        Result = WaitForSingleObject_(hStdInput, 100)
 
        Select Result
          Case #WAIT_ABANDONED : Break
          Case #WAIT_OBJECT_0 : Delay(100)
          Case #WAIT_TIMEOUT : Break
          Case #WAIT_FAILED : Break
        EndSelect
      ForEver
    EndIf
  EndIf
EndProcedure
 
dwProcessId = cmdGetProcessId("cmd.exe")
 
If Not dwProcessId : RunProgram("cmd") : Delay(200) : dwProcessId = cmdGetProcessId("cmd.exe") : EndIf
 
If dwProcessId
  hStdInput.l = cmdOpenConsole(dwProcessId)
 
  If hStdInput
    If cmdAddAlias(".", "cd C:\&&dir") : cmdRunScript(hStdInput, ".") : EndIf
  EndIf
EndIf



Благодарности товарищу JHPJHP с англоязычного форума.

Добавлено:
Буду благодарен, если Пётр или кто-то ещё посмотрит этот код и поможет избавиться от первоначальной точки и двойного перевода каретки по окончании работы. Чтобы было красиво.
Помнится в командном файле чтобы добиться отступа вставлял вначале один из непечатаемых символов и помоему это была русская буква "я". Не помню, давно было. Может можно как-то применить в этом случае такой подход?

Добавлено:
по поводу перевода строки - закомментировать строку ScriptText + Chr(13).


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Вс июл 09, 2017 10:05 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11070
Благодарил (а): 4 раз.
Поблагодарили: 381 раз.
knower писал(а):
Помнится в командном файле чтобы добиться отступа вставлял вначале один из непечатаемых символов и помоему это была русская буква "я"
Если программа с выключенной поддержкой юникода, то можно поступить также.
Код:
1
If cmdAddAlias(Chr(255), "cd C:\&&dir") : cmdRunScript(hStdInput, Chr(255)) : EndIf

Для юникодной программы
Код:
1
If cmdAddAlias(Chr(160), "cd C:\&&dir") : cmdRunScript(hStdInput, Chr(160)) : EndIf


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Консоль
СообщениеДобавлено: Вс июл 09, 2017 10:23 pm 
Не в сети
профессор

Зарегистрирован: Вс авг 31, 2014 12:11 am
Сообщений: 390
Благодарил (а): 49 раз.
Поблагодарили: 18 раз.
Пункты репутации: 10
Спасибо конечно, Пётр. Но то ли у меня консоль неправильная, то ли ОС, то ли PB.
PB531 и win7x86 - в настройках стоит галочка юникода и формат файла выставлен как utf-8. Всё по умолчанию. В итоге Chr(160) печатает букву "а". Chr(255) - "y". :cry:


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: bnv123 и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB