Source

background / Program.cs

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using System.Reflection;

namespace background
{
    static class Program
    {
        #region API
        [DllImport("kernel32", SetLastError = true)]
        static extern bool AttachConsole(int dwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool FreeConsole();

        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll", SetLastError = true)]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetPriorityClass(IntPtr hProcess, uint dwPriorityClass);

        static uint PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000;
        //static uint PROCESS_MODE_BACKGROUND_END = 0x00200000;
        #endregion

        static bool attached = false;
        static string version = Assembly.GetExecutingAssembly().GetName().Version.ToString();

        [STAThread]
        static int Main(string[] args)
        {
            attached = AttachToConsole();
            if (!attached) return 0;
            Thread.Sleep(10000);

            //only show info if run via command line with no arguments
            if (args.Length == 0 || (args.Length > 1 && (args[1] == "--help" || args[1] == "--h" || args[1] == "-help" || args[1] == "-h" || args[1] == "--?" || args[1] == "-?" || args[1] == "/help" || args[1] == "/h" || args[1] == "/?")))
            {
                Console.WriteLine(ShowInfo(false));
            }
            else
            {
                string program_path = Environment.ExpandEnvironmentVariables(args[1]);
                string program_args = (args.Length > 2) ? Environment.CommandLine.Substring(Environment.CommandLine.IndexOf(args[1]) + args[1].Length + 1) : string.Empty;

                Console.WriteLine();
                Console.WriteLine("background.exe v" + version + "\thttp://factormystic.net/utils");
                Console.WriteLine();
                Console.WriteLine("Setting process to background priority...");

                if (!SetPriorityClass(Process.GetCurrentProcess().Handle, PROCESS_MODE_BACKGROUND_BEGIN))
                {
                    Win32Exception ex = new Win32Exception(Marshal.GetLastWin32Error());

                    Console.WriteLine("Error setting process priority:");
                    Console.WriteLine(ex.Message);
                }

                Console.WriteLine("Starting " + program_path + "...");

                try
                {
                    Process program = Process.Start(program_path, program_args);
                }
                catch (Exception e)
                {
                    Console.WriteLine("Error: " + e.Message);
                }

                Console.WriteLine("Done.");
            }
            FreeConsole();
            return 0;
        }

        private static bool AttachToConsole()
        {
            //    int foreground;
            //    GetWindowThreadProcessId(GetForegroundWindow(), out foreground);
            //    return AttachConsole(Process.GetProcessById(foreground).Id);

            ////attempt to attach to parent console
            if (!AttachConsole(-1))
            {
                //not started from console
                MessageBox.Show(ShowInfo(true), "background.exe usage");
                return false;
            }
            else return true;
        }

        private static string ShowInfo(bool extra)
        {
            string info = string.Empty;

            if (!extra) info += "\n";
            info += "background.exe v" + version + "\thttp://factormystic.net/utils" + "\n";
            info += "Start programs with background I/O and CPU priority.\n";

            if (extra) info += "\n" + "This program is designed to be launched from the command line, or by a shortcut.\n";

            info += "\n";
            info += "Usage:\tbackground [options] program [parameters]\n";
            //info += "\t-cpu\tManually set process CPU priority. Valid options are:\n";
            //info += "\t\tidle, below, normal, above, realtime\n";
            //info += "\t\tIf this option is omitted, idle priority will be used.\n";
            //info += "\n";
            info += "\t-io\tManually set process I/O priority. Valid options are:\n";
            info += "\t\tidle, below, normal, above, realtime\n";
            info += "\t\tIf this option is omitted, idle priority will be used.";

            if (!extra) info += "\n";

            return info;
        }
    }
}