示例#1
0
        public void DebugWholeConsole()
        {
            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();

            Debug.WriteLine("");
            Debug.WriteLine("------------------------------ Complete Current Console [Cursor = " + info.dwCursorPosition.X.ToString() + "," + info.dwCursorPosition.Y.ToString() + "] ----------------------------------");
            for (int yy = 0; yy <= info.dwCursorPosition.Y; yy++)
            {
                ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
                COORD LineBufferSize = new COORD();
                LineBufferSize.X = info.dwSize.X;
                LineBufferSize.Y = 1;
                COORD Origin = new COORD();
                Origin.X = Origin.Y = 0;

                ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
                ConsoleRect.Left   = 0;
                ConsoleRect.Right  = (short)(info.dwSize.X - 1);
                ConsoleRect.Top    = (short)yy;
                ConsoleRect.Bottom = (short)yy;

                Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

                StringBuilder sb = new StringBuilder();
                for (int xx = 0; xx < info.dwSize.X; xx++)
                {
                    sb.Append(LineBuffer[xx].UnicodeChar);
                }
                string sLine = sb.ToString().TrimEnd();
                Debug.WriteLine(sLine);
            }
            Debug.WriteLine("------------------------------");
        }
示例#2
0
        /// <summary>
        /// PeekCurrentLine() retrieves the contents of the line under the cursor, with cursor position as it was during the last call to ReadNew().
        /// Any whitespace at the end of the line is trimmed.
        /// </summary>
        public string PeekCurrentLine()
        {
            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();

            ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
            COORD LineBufferSize = new COORD();

            LineBufferSize.X = info.dwSize.X;
            LineBufferSize.Y = 1;
            COORD Origin = new COORD();

            Origin.X = Origin.Y = 0;

            ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
            ConsoleRect.Left   = 0;
            ConsoleRect.Right  = (short)(info.dwSize.X - 1);
            ConsoleRect.Top    = (short)LastCursorPosition.Y;
            ConsoleRect.Bottom = (short)LastCursorPosition.Y;

            Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

            StringBuilder sb = new StringBuilder();

            for (int xx = 0; xx < info.dwSize.X; xx++)
            {
                sb.Append(LineBuffer[xx].UnicodeChar);
            }
            return(sb.ToString().TrimEnd());
        }
示例#3
0
        /// <summary>
        /// CheckForLineScroll() looks at the console's top line and tries to determine if any lines have vanished as the console has scrolled up.  It is an imperfect
        /// check in that it can be fooled, and a more thorough console validation would be required for certainty, but it is good for identifying some "delta" situations
        /// where the console can be re-synced simply by removing some lines at the top.
        /// </summary>
        /// <param name="Stale">Set to true if CheckForLineScroll() has determined that the console is sufficiently out-of-sync with the tracker that the
        /// line scroll check cannot be performed reliably.</param>
        /// <returns>The number of lines which have vanished from the top of the console.</returns>
        public int CheckForLineScroll(out bool Stale)
        {
            if (PendingReload)
            {
                PendingReload = false; Stale = true; return(0);
            }                                                                          // Force first read to always give Stale so we use GetWholeConsole().

            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();
            if (info.dwCursorPosition.Y < LastCursorPosition.Y)
            {
                Stale = true; return(0);
            }
            Stale = false;

            ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
            COORD LineBufferSize = new COORD();

            LineBufferSize.X = info.dwSize.X;
            LineBufferSize.Y = 1;
            COORD Origin = new COORD();

            Origin.X = Origin.Y = 0;

            ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
            ConsoleRect.Left   = 0;
            ConsoleRect.Right  = (short)(info.dwSize.X - 1);
            ConsoleRect.Top    = (short)0;
            ConsoleRect.Bottom = (short)0;

            // Read the top of the console to compare against our current state
            Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

            StringBuilder sbLine = new StringBuilder();

            for (int xx = 0; xx < info.dwSize.X; xx++)
            {
                sbLine.Append(LineBuffer[xx].UnicodeChar);
            }
            string FirstLine = sbLine.ToString().TrimEnd();

            sbLine.Clear();

            if (Lines.Count > 0 && Lines[0] != FirstLine)
            {
                for (int yy = 0; yy < Lines.Count; yy++)
                {
                    if (Lines[yy] == FirstLine)
                    {
                        Lines.RemoveRange(0, yy);
                        return(yy);
                    }
                }
                Stale = true;
                return(0);
            }

            return(0);
        }
示例#4
0
        /// <summary>
        /// Also refreshes Lines.
        /// </summary>
        /// <param name="MaxSize"></param>
        /// <returns></returns>
        public string ReadWholeConsole(int MaxSize = int.MaxValue)
        {
            StringBuilder sb = new StringBuilder();

            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();

            ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
            COORD LineBufferSize = new COORD();

            LineBufferSize.X = info.dwSize.X;
            LineBufferSize.Y = 1;
            COORD Origin = new COORD();

            Origin.X = Origin.Y = 0;

            ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
            ConsoleRect.Left  = 0;
            ConsoleRect.Right = (short)(info.dwSize.X - 1);

            Lines.Clear();

            for (int yy = 0; yy <= info.dwCursorPosition.Y; yy++)
            {
                if (sb.Length > MaxSize)
                {
                    LastCursorPosition.X = 0;
                    LastCursorPosition.Y = (short)yy;
                    return(sb.ToString());
                }

                ConsoleRect.Top    = (short)yy;
                ConsoleRect.Bottom = (short)yy;

                Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

                StringBuilder sbLine = new StringBuilder();
                for (int xx = 0; xx < info.dwSize.X; xx++)
                {
                    sbLine.Append(LineBuffer[xx].UnicodeChar);
                }
                sb.Append(sbLine.ToString().TrimEnd());
                if (yy < info.dwCursorPosition.Y)
                {
                    Lines.Add(sbLine.ToString().TrimEnd());
                    sb.AppendLine();
                }
            }
            LastCursorPosition = info.dwCursorPosition;
            return(sb.ToString());
        }
示例#5
0
        /// <summary>
        /// SpotCheckState() looks at a handful of random lines in the console and compares them to ConsoleTracker's current expectations.  If they match, then we can assume we are ok doing the
        /// usual delta analysis we do.  If something mismatches, then the delta analysis got tripped up- as can happen normally- and we need to refresh the entire console to get back in sync.
        /// This can happen with something as simple as the "cls" command, or a CheckForLineScroll() that incorrectly lined up the top line with the wrong line in our records because the same
        /// line appears more than once, or if the cursor bounces around and makes changes that we don't see.
        /// </summary>
        /// <param name="PartialOnly">If true, we only expect to be sync'd up to the end of the current Lines list.  In this case, we do not need to trigger Stale for any content beyond the
        /// current Lines list.  If false, then we expect our Lines list to be comprehensive (except the current line) and can freely check anywhere.</param>
        /// <param name="Stale"></param>
        public void SpotCheckState(bool PartialOnly, out bool Stale)
        {
            if (PendingReload)
            {
                PendingReload = false; Stale = true; return;
            }                                                                        // Force first read to always give Stale so we use GetWholeConsole().

            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();
            if (info.dwCursorPosition.Y < LastCursorPosition.Y)
            {
                Stale = true; return;
            }

            Stale = false;

            ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
            COORD LineBufferSize = new COORD();

            LineBufferSize.X = info.dwSize.X;
            LineBufferSize.Y = 1;
            COORD Origin = new COORD();

            Origin.X = Origin.Y = 0;

            ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
            ConsoleRect.Left  = 0;
            ConsoleRect.Right = (short)(info.dwSize.X - 1);

            for (int ii = 0; ii < 3; ii++)
            {
                int yy = rng.Next() % info.dwSize.Y;
                if (yy == info.dwCursorPosition.Y)
                {
                    continue;                                           // We don't track the current line in the Lines listing.
                }
                if (PartialOnly && yy >= Lines.Count)
                {
                    continue;                                           // In this mode, we only compare the part we've so far sync'd.
                }
                ConsoleRect.Top    = (short)yy;
                ConsoleRect.Bottom = (short)yy;

                // Read the line
                Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

                StringBuilder sbLine = new StringBuilder();
                for (int xx = 0; xx < info.dwSize.X; xx++)
                {
                    sbLine.Append(LineBuffer[xx].UnicodeChar);
                }
                string ConsoleLine = sbLine.ToString().TrimEnd();

                if (yy >= Lines.Count)
                {
                    if (ConsoleLine.Length == 0)
                    {
                        continue;                               // Ok, saw a blank line where we expected it - beyond the end of our listing.
                    }
                    else
                    {
                        Stale = true; return;
                    }                                           // Not ok, saw something out where we didn't expect it.
                }
                if (ConsoleLine != Lines[yy])
                {
                    Stale = true; return;
                }                                                           // Found a difference in our spot check.
            }

            return;
        }
示例#6
0
        /// <summary>
        /// ReadNew() is similar to CheckForLineScroll() in that it examines the console and looks for "delta" situations.  As with CheckForLineScroll(), it
        /// can be fooled, but is good for minimizing bandwidth use in most situations.
        /// </summary>
        /// <param name="Stale">Set to true if changes to the console have been detected that cannot be captured by ReadNew(), and therefore the console is
        /// sufficiently out-of-sync as to warrant a complete reload via ReadWholeConsole().</param>
        /// <param name="MaxedMessage">Set to true if the MaxSize constraint triggered.  This would indicate that the ConsoleTracker is not expected to be
        /// fully in sync as yet, except up to the line that we've so far retrieved.</param>
        /// <param name="IncludeCurrentLine"></param>
        /// <param name="MaxSize"></param>
        /// <returns>New content from the console to be appended.</returns>
        public string ReadNew(out bool Stale, out bool MaxedMessage, bool IncludeCurrentLine = false, int MaxSize = int.MaxValue)
        {
            MaxedMessage = false;
            if (PendingReload)
            {
                PendingReload = false; Stale = true; return("");
            }                                                                           // Force first read to always give Stale so we use GetWholeConsole().

            ConsoleApi.CONSOLE_SCREEN_BUFFER_INFO info = Console.GetInfo();

            if (info.dwCursorPosition.X == LastCursorPosition.X && info.dwCursorPosition.Y == LastCursorPosition.Y)
            {
                Stale = false; return("");
            }
            if (info.dwCursorPosition.Y < LastCursorPosition.Y)
            {
                Stale = true; return("");
            }
            Stale = false;
            //System.Diagnostics.Debug.WriteLine("Console Cursor @ (" + info.dwCursorPosition.X.ToString() + "," + info.dwCursorPosition.Y.ToString() + ")");

            int Y1 = LastCursorPosition.Y;
            int Y2 = info.dwCursorPosition.Y;

            ConsoleApi.CHAR_INFO[] LineBuffer = new ConsoleApi.CHAR_INFO[info.dwSize.X];
            COORD LineBufferSize = new COORD();

            LineBufferSize.X = info.dwSize.X;
            LineBufferSize.Y = 1;
            COORD Origin = new COORD();

            Origin.X = Origin.Y = 0;

            ConsoleApi.SMALL_RECT ConsoleRect = new ConsoleApi.SMALL_RECT();
            ConsoleRect.Left   = 0;
            ConsoleRect.Right  = (short)(info.dwSize.X - 1);
            ConsoleRect.Top    = (short)Y1;
            ConsoleRect.Bottom = (short)Y1;

            // Read the first line (which might be the only one changed)
            Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);

            StringBuilder sb     = new StringBuilder();
            StringBuilder sbLine = new StringBuilder();

            // Find characters from the previous cursor to EOL
            int X2 = info.dwSize.X;

            if (Y1 == Y2)
            {
                X2 = info.dwCursorPosition.X;
            }
            int X1 = LastCursorPosition.X;

            if (IncludeCurrentLine)
            {
                X1 = 0;
            }

            for (int xx = X1; xx < X2; xx++)
            {
                sbLine.Append(LineBuffer[xx].UnicodeChar);
            }
            if (Y1 == Y2)
            {
                LastCursorPosition = info.dwCursorPosition;
                return(sbLine.ToString().TrimEnd());
            }
            // Since Y1 doesn't equal Y2, at least one line has been committed to the console.
            sb.Append(sbLine.ToString().TrimEnd());
            Lines.Add(sbLine.ToString().TrimEnd());
            sbLine.Clear();
            sb.AppendLine();

            // Now lets work on any additional committed lines, but not the one with the cursor (yet)
            for (int yy = Y1 + 1; yy < Y2; yy++)
            {
                // Read and consume whole line
                ConsoleRect.Left   = 0;
                ConsoleRect.Right  = (short)(info.dwSize.X - 1);
                ConsoleRect.Top    = (short)yy;
                ConsoleRect.Bottom = (short)yy;
                Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);
                for (int xx = 0; xx < info.dwSize.X; xx++)
                {
                    sbLine.Append(LineBuffer[xx].UnicodeChar);
                }
                sb.Append(sbLine.ToString().TrimEnd());
                Lines.Add(sbLine.ToString().TrimEnd());
                sbLine.Clear();
                sb.AppendLine();

                if (sb.Length > MaxSize)
                {
                    MaxedMessage         = true;
                    LastCursorPosition.X = 0;
                    LastCursorPosition.Y = (short)(yy + 1);
                    return(sb.ToString());
                }
            }

            // Final line (contains the cursor)
            ConsoleRect.Left   = 0;
            ConsoleRect.Right  = (short)(info.dwSize.X - 1);
            ConsoleRect.Top    = (short)Y2;
            ConsoleRect.Bottom = (short)Y2;
            Console.ReadOutput(LineBuffer, LineBufferSize, Origin, ref ConsoleRect);
            for (int xx = 0; xx < info.dwCursorPosition.X; xx++)
            {
                sbLine.Append(LineBuffer[xx].UnicodeChar);
            }
            sb.Append(sbLine.ToString().TrimEnd());

            LastCursorPosition = info.dwCursorPosition;
            return(sb.ToString());
        }