ReadConsoleOutputCharacer API

  • Thread starter Thread starter Stefano Camaiani
  • Start date Start date
S

Stefano Camaiani

Hello, it's strange but in the web there are not (or i found not)
explanation on howto use ReadConsoleOutputCharacter from C# or Vb.Net....
Very much articles, but not one word of this particular API and also
ReadConsoleOutput too....

May be of this API is disabled on those new Languages?

Regards.
Stefano.
 
Stefano Camaiani said:
Hello, it's strange but in the web there are not (or i found not)
explanation on howto use ReadConsoleOutputCharacter from C# or Vb.Net....
Very much articles, but not one word of this particular API and also
ReadConsoleOutput too....

May be of this API is disabled on those new Languages?

It's a Win32 API, not part of the .NET framework. It's not that it's so
much "disabled" - it's just not part of the framework. You could use
P/Invoke, of course, but I think there are other .NET console APIs out
there which may well be easier to use.
 
Thanks Jon, i will reply to you here too...
I understand you, but why all other API related are supported then?
First: Sorry for my bad english, i'm Italian...
Here some APIs Console related wich i'm able tu use with Vb.Net and C#:
SetConsoleTextAttribute

GetStdHandle

SetConsoleCursorInfo

GetConsoleMode

SetConsoleMode

SetConsoleTitleA

GetConsoleTitleA

GetConsoleScreenBufferInfo

SetConsoleCursorPosition

SetConsoleTextAttribute

FillConsoleOutputCharacter

FillConsoleOutputAttribute

SetConsoleCursorPosition

SetConsoleCursorInfo

ReadConsole

Then why if those APIs are not part of framework they works well?

Regards.

Stefano...
 
Stefano Camaiani said:
Thanks Jon, i will reply to you here too...
I understand you, but why all other API related are supported then?

Um, they're not, as far as I can see...
First: Sorry for my bad english, i'm Italian...
Here some APIs Console related wich i'm able tu use with Vb.Net and C#:
SetConsoleTextAttribute

Which class is that in? It doesn't appear in the MSDN index when I have
the Visual C# filter on.

Then why if those APIs are not part of framework they works well?

Could you give a small sample program that shows them being used?
 
Well, then i'm really unhappy of Microsoft has NOT released a Visual
Basic version _NOT_ Framework... :(

I love Visual Basic, but i really need this API to continue my Job.....
Why? Because the standard Console functions of Visual Basic.Net and c#
are not able to handle my problem...

Then i will need to continue to use VB6 forever?

Please, if you know some other useful APIs to get Console Output Buffer,
before a shelled application end, and before some data buffer has full
filled the StandardOutput PIPE buffer, then please let me know.....


Regards.

Stefano.
 
Stefano Camaiani said:
Well, then i'm really unhappy of Microsoft has NOT released a Visual
Basic version _NOT_ Framework... :(

I love Visual Basic, but i really need this API to continue my Job.....
Why? Because the standard Console functions of Visual Basic.Net and c#
are not able to handle my problem...

Then i will need to continue to use VB6 forever?

No; you can call Win32 routines such as this one by using PInvoke.
 
Well, first: Thanks... Second: Sorry for my bad english...

Ok, i worked on 2 existing class i found in the Web.
Vb.Net = http://www.allapi.net/classlib/class.php?id=4
C# =
http://www.gotdotnet.com/Community/UserSamples/Details.aspx?SampleGuid=b
76d1f08-2d79-47bd-825b-0489938aae0f

I tried to implement ReadConsoleOutputCharacter and also
ReadConsoleOutput on it without success....

This is my code for Vb.Net:
Api declarations:

<DllImport("KERNEL32.DLL",
EntryPoint:="ReadConsoleOutputCharacterA", CharSet:=CharSet.Ansi,
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ReadConsoleOutputCharacter(ByVal
hConsoleOutput As Integer, ByVal lpCharacter As String, ByVal nLenght As
Integer, ByVal dwCursorPosition As COORD, ByVal lpNumberOfCharsRead As
Integer) As Integer
End Function

<DllImport("KERNEL32.DLL", EntryPoint:="ReadConsoleOutputA",
CharSet:=CharSet.Ansi, SetLastError:=False, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ReadConsoleOutput(ByVal hConsoleOutput As
Integer, ByVal lpCharacter As CHAR_INFO, ByVal dwBufferSize As COORD,
ByVal dwBufferCoord As COORD, ByVal lpReadRegion As SMALL_RECT) As
Integer
End Function

and my code is:
Public Shared Property OutputS() As String
Get
Dim NumberOfCharRead As Integer
Dim ConsoleInfo As CONSOLE_SCREEN_BUFFER_INFO
Dim CaptureStart As Integer
Dim NrOfVisibleChars As Integer
With ConsoleInfo.srWindow
NrOfVisibleChars = (ConsoleAttributes.WindowHeight *
ConsoleAttributes.WindowWidth) 'Calculate area to capture
End With
'MsgBox(NrOfVisibleChars)
Dim crd As COORD
crd.x = 1
crd.y = 1
Dim sb3 As New String(" ", 256)
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
MyScreenBufferInfo)
CaptureStart = ConsoleInfo.srWindow.Left Or
(ConsoleInfo.srWindow.Top * &H10000)
'CaptureStart = MyScreenBufferInfo.srWindow.Top * &H10000
'CaptureStart = 1048576
'CaptureStart = 1

MsgBox(MyScreenBufferInfo.wAttributes.ToString)
ReadConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE),
sb3, NrOfVisibleChars, crd, NumberOfCharRead)
'MsgBox(NumberOfCharRead)
Return sb3
End Get
Set(ByVal Value As String)
End Set
End Property

Public Shared Property GetConsoleOutputS() As String
Get
Dim CharacterInfo As CHAR_INFO
Dim crd1 As COORD
crd1.x = 10
crd1.y = 10
Dim crd2 As COORD
crd2.x = 20
crd2.y = 20
Dim Coordinates As SMALL_RECT
Coordinates.Top = 1
Coordinates.Bottom = 10
Coordinates.Left = 1
Coordinates.Right = 10
'MsgBox(NrOfVisibleChars)
ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE),
CharacterInfo, crd2, crd1, Coordinates)
MsgBox(Len(CharacterInfo))
Return CharacterInfo.Char1.ToString
End Get
Set(ByVal Value As String)
End Set
End Property
************************************************************************
************************************************************************
*********************************
This is my Api Declaration on c#
[DllImport("kernel32.dll", EntryPoint="ReadConsoleOutputCharacterA",
SetLastError=true,
CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern bool ReadConsoleOutputCharacter(int
hConsoleInput,
StringBuilder buf, int nNumberOfCharsToRead, COORD dwReadCoord, ref
int lpNumberOfCharsRead);


and this is my code:
public static string ReadChar2()
{
// Temporarily disable character echo (ENABLE_ECHO_INPUT) and line
input
// (ENABLE_LINE_INPUT) during this operation
SetConsoleMode(hConsoleInput,
(int) (InputModeFlags.ENABLE_PROCESSED_INPUT |
InputModeFlags.ENABLE_WINDOW_INPUT |
InputModeFlags.ENABLE_MOUSE_INPUT));

int lpNumberOfCharsRead = 0;
//StringBuilder buf = new StringBuilder(1);
StringBuilder buf = new StringBuilder(100);

COORD c = new COORD();
c.x = (short)1;
c.y = (short)1;
bool success = ReadConsoleOutputCharacter(hConsoleInput, buf, 5, c,
ref lpNumberOfCharsRead);

// Reenable character echo and line input
SetConsoleMode(hConsoleInput,
(int) (InputModeFlags.ENABLE_PROCESSED_INPUT |
InputModeFlags.ENABLE_ECHO_INPUT |
InputModeFlags.ENABLE_LINE_INPUT |
InputModeFlags.ENABLE_WINDOW_INPUT |
InputModeFlags.ENABLE_MOUSE_INPUT));

if (success)
return buf.ToString();
else
throw new ApplicationException("Attempt to call ReadConsole API
failed.");
}
'***********************************************************************
************************************************************************
*********************************

If you would like i have also the VB 6.0 code wich work great with only
few lines of code:


Dim ConsoleInfo As CONSOLE_SCREEN_BUFFER_INFO
Dim ConsoleText As String
Dim NrOfVisibleChars As Long
Dim NrOfCharsRead As Long
Dim CaptureStart As Long

' Execute DOS command, the command will now use the previously
allocated console window

'Any shell here.....

StdOut = GetStdHandle(STD_OUTPUT_HANDLE) ' Get a handle to Std_out
'MsgBox (StdOut)
GetConsoleScreenBufferInfo StdOut, ConsoleInfo ' Get info about the
console window, such as width and height
With ConsoleInfo.srWindow
NrOfVisibleChars = (.Bottom - .Top) * (.Right - .Left) ' Calculate
area to capture
End With

ConsoleText = String(NrOfVisibleChars, vbNullChar) ' Reserve space for
captured text

' This is a little trick that has to be done in order to be able to pass
the X and Y coordinates to ReadConsoleOutputCharacter
' They should really be passsed as a COORD structure, but VB won't allow
user defined types to be passed by value...
CaptureStart = ConsoleInfo.srWindow.Left Or (ConsoleInfo.srWindow.Top *
&H10000)
MsgBox CaptureStart
ReadConsoleOutputCharacter StdOut, ConsoleText, NrOfVisibleChars,
CaptureStart, NrOfCharsRead ' Get all visible text in the console
window

ConsoleText = Left(ConsoleText, NrOfCharsRead) ' Trim results

Text1.Text = ConsoleText

'***********************************************************************
************************************************************************
*********************************

Here is it.....
Why i need those APIs? Because i only must read an Output of a command
line tools....but i should not use the standard redirections because
they show me the output buffer only when the command line tool has
exited or if the PIPE buffer is full....too slow for me...i need to get
the output immediately...

I will very thanks you very very very much if you should give me a
way....
Note: Visual C++.net is able to use both ReadConsoleOutput and
ReadConsoleOutputCharacter APIs.....(windows.h)...If you would like i
should post it too.....

Please don't lose too much time on searching for my problem. because
ithink of VB.Net and C# should not use those APIs.....
 
Well,
i surrender....
But i have created a Visual C++ 7.0 console wich do this work for me....
Thanks to all...
 
Stefano,
<DllImport("KERNEL32.DLL",
EntryPoint:="ReadConsoleOutputCharacterA", CharSet:=CharSet.Ansi,
SetLastError:=True, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ReadConsoleOutputCharacter(ByVal
hConsoleOutput As Integer, ByVal lpCharacter As String, ByVal nLenght As
Integer, ByVal dwCursorPosition As COORD, ByVal lpNumberOfCharsRead As
Integer) As Integer
End Function

Should be

<DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto, SetLastError:=True)>
_
Private Shared Function ReadConsoleOutputCharacter(ByVal
hConsoleOutput As IntPtr, ByVal lpCharacter As StringBuilder, ByVal
nLenght As Integer, ByVal dwCursorPosition As COORD, ByRef
lpNumberOfCharsRead As Integer) As Boolean
End Function

<DllImport("KERNEL32.DLL", EntryPoint:="ReadConsoleOutputA",
CharSet:=CharSet.Ansi, SetLastError:=False, ExactSpelling:=True,
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ReadConsoleOutput(ByVal hConsoleOutput As
Integer, ByVal lpCharacter As CHAR_INFO, ByVal dwBufferSize As COORD,
ByVal dwBufferCoord As COORD, ByVal lpReadRegion As SMALL_RECT) As
Integer
End Function

<DllImport("KERNEL32.DLL", CharSet:=CharSet.Auto)> _
Private Shared Function ReadConsoleOutput(ByVal hConsoleOutput As
IntPtr, <[In], Out> ByVal lpCharacter() As CHAR_INFO, ByVal
dwBufferSize As COORD, ByVal dwBufferCoord As COORD, ByRef
lpReadRegion As SMALL_RECT) As Boolean
End Function



Mattias
 
Back
Top