如何在NAnt脚本中运行'color'命令

时间:2010-08-10 04:53:16

标签: command-line colors nant

我刚开始使用Nant进行构建和测试。我想让它在失败时更改我的命令提示文本的颜色(或背景),以便它很容易被注意到。

Windows上命令提示符中的命令为“color 4”,将其更改为红色,将颜色7更改为白色。

如何在构建脚本中运行,echo不起作用,exec不起作用(虽然可能使用exec错误)。我宁愿不必运行perl等来做一些在标准命令提示符窗口中轻松完成的事情。

有谁知道怎么做?

2 个答案:

答案 0 :(得分:5)

尝试使用自定义任务。如果任务包含在nant文件中,则不会有任何外部依赖。

<project >

    <target name="color">
        <consolecolor color="Red" backgroundcolor="White"/>
        <echo message="red text"/>
        <consolecolor color="White" backgroundcolor="Black"/>
        <echo message="white text"/>
    </target>

    <script language="C#">
        <code>
            [TaskName("consolecolor")]
            public class TestTask : Task
            {
            private string _color;
            private string _backgroundColor;

            [TaskAttribute("color",Required=true)]
            public string Color
            {
            get { return _color; }
            set { _color = value; }
            }

            [TaskAttribute("backgroundcolor",Required=false)]
            public string BackgroundColor
            {
            get { return _backgroundColor; }
            set { _backgroundColor = value; }
            }

            protected override void ExecuteTask()
            {
            System.Console.ForegroundColor = (System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),Color);
            System.Console.BackgroundColor = (System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),BackgroundColor);
            }
            }
        </code>
    </script>

</project>

答案 1 :(得分:2)

作为我对@ Martin-Vobr发表的评论的后续跟进:

我添加了额外的逻辑来正确更改背景。这将允许在命令窗口中启动构建,然后可以一目了然地检查进度。我使用蓝色背景“建筑”,绿色表示“成功”,红色表示“失败”。

 <!-- http://stackoverflow.com/questions/3446135/how-to-run-color-command-in-nant-script -->
  <!-- Sample:  <consolecolor color="Red" backgroundcolor="White"/> -->
  <!-- Alternative: http://riccardotramma.com/2011/05/nantcolours-v1-0-a-task-library-for-output-colouring-in-nant/ -->
  <script language="C#">
        <code>
        <![CDATA[
             [TaskName("consolecolor")]
            public class TestTask : Task
            {
                private string _color;
                private string _backgroundColor;

                [TaskAttribute("color",Required=true)]
                public string Color
                {
                    get { return _color; }
                    set { _color = value; }
                }

                [TaskAttribute("backgroundcolor",Required=false)]
                public string BackgroundColor
                {
                    get { return _backgroundColor; }
                    set { _backgroundColor = value; }
                }

                protected override void ExecuteTask()
                {
                    System.Console.ForegroundColor = (System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),Color);
                    System.Console.BackgroundColor = (System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),BackgroundColor);
                    // clearing the screen sets the entire screen to be the new color
                    ChangeColor((System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),Color), (System.ConsoleColor) Enum.Parse(typeof(System.ConsoleColor),BackgroundColor));
                }

                // added by Brad Bruce
                // http://stackoverflow.com/questions/6460932/change-entire-console-background-color-win32-c

                [System.Runtime.InteropServices.DllImport("kernel32.dll")]
                static extern bool ReadConsoleOutputAttribute(IntPtr hConsoleOutput,
                   [System.Runtime.InteropServices.Out] ushort[] lpAttribute, uint nLength, COORD dwReadCoord,
                   out uint lpNumberOfAttrsRead);

                [System.Runtime.InteropServices.DllImport("kernel32.dll")]
                static extern bool FillConsoleOutputAttribute(IntPtr hConsoleOutput,
                   ushort wAttribute, uint nLength, COORD dwWriteCoord, out uint
                   lpNumberOfAttrsWritten);

                [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
                public struct COORD {
                    public short X;
                    public short Y;

                    public COORD(short X, short Y) {
                        this.X = X;
                        this.Y = Y;
                    }
                };

                [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
                 static extern IntPtr GetStdHandle(int nStdHandle);

                //C#: Get stdout handle
                const int STD_OUTPUT_HANDLE = -11;
                const int STD_INPUT_HANDLE = -10;
                const int STD_ERROR_HANDLE = -12;
                //INVALID_HANDLE_VALUE //(return value if invalid handle is specified)

                // http://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes

                public enum CharacterAttributes{
                    FOREGROUND_BLUE = 0x0001,
                    FOREGROUND_GREEN = 0x0002,
                    FOREGROUND_RED = 0x0004,
                    FOREGROUND_INTENSITY = 0x0008,
                    BACKGROUND_BLUE = 0x0010,
                    BACKGROUND_GREEN = 0x0020,
                    BACKGROUND_RED = 0x0040,
                    BACKGROUND_INTENSITY = 0x0080,
                    COMMON_LVB_LEADING_BYTE = 0x0100,
                    COMMON_LVB_TRAILING_BYTE = 0x0200,
                    COMMON_LVB_GRID_HORIZONTAL = 0x0400,
                    COMMON_LVB_GRID_LVERTICAL = 0x0800,
                    COMMON_LVB_GRID_RVERTICAL = 0x1000,
                    COMMON_LVB_REVERSE_VIDEO = 0x4000,
                    COMMON_LVB_UNDERSCORE = 0x8000
                }

                static void ChangeColor(System.ConsoleColor color, System.ConsoleColor backgroundColor) {
                    uint written = 0;
                    COORD writeCoord = new COORD(0, 0);
                    ushort[] attribute = new ushort[400];

                    IntPtr consoleOutputHandle = GetStdHandle( STD_OUTPUT_HANDLE );

                    int consoleBufferWidth = Console.BufferWidth;
                    int consoleBufferLength = Console.BufferHeight;
                    //if (consoleBufferLength > Console.CursorTop) {
                    //    consoleBufferLength = Console.CursorTop;
                    //}

                    for (int y = 0; y < consoleBufferLength; y++)     // rows
                    {
                        writeCoord.X = (short)0;
                        writeCoord.Y = (short)y;
                        ReadConsoleOutputAttribute(consoleOutputHandle, attribute, (uint)consoleBufferWidth, writeCoord, out written);

                        for (int x2 = 0; x2 < consoleBufferWidth; x2++){  // columns
                            attribute[x2] &= 0xFF00;  // zero the background and foreground color
                            attribute[x2] |= (ushort)((((int)backgroundColor) << 4) | (int)color);
                        }
                        FillConsoleOutputAttribute(consoleOutputHandle, attribute[0], (uint)consoleBufferWidth, writeCoord, out written);
                    }
                }
            }
        ]]> 
        </code>
    </script>