Exemplo n.º 1
0
 private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);
Exemplo n.º 2
0
 private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate handlerRoutine, bool add); // 由于不支持泛型,所以采用delegate
Exemplo n.º 3
0
 public static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate handlerRoutine, bool Add);
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            // 先注入一个dll,Hook要绘制的窗体的WndProc函数,吃掉WM_PAINT消息,不然任务管理器会闪烁
            var dllInjectionContext = DllInjection.Injection("Taskmgr", Path.Combine(Environment.CurrentDirectory, "HookWinProc.dll"));

            controlCtrlDelegate = type => {
                switch (type)
                {
                case 0:                         // CTRL_C_EVENT
                case 2:                         // CTRL_CLOSE_EVENT
                case 5:                         // CTRL_LOGOFF_EVENT
                case 6:                         // CTRL_SHUTDOWN_EVENT
                                                // 控制台关闭后清理掉注入的dll
                    DllInjection.FreeLibrary(dllInjectionContext);
                    break;
                }
                return(true);
            };
            SetConsoleCtrlHandler(controlCtrlDelegate, true);


            // 获得CPU核心数,其实我之后的代码已经写死默认是4个核心的情况
            var kernelCount = Environment.ProcessorCount;

            var hwnd = WinApi.FindWindow("TaskManagerWindow", "任务管理器");
            var root = new Window(hwnd);

            if (root.Childs.Count == 1 && root.Childs[0].ClassName == "NativeHWNDHost")
            {
                root = root.Childs[0];
            }
            else
            {
                throw new Exception("未找到窗体");
            }
            if (root.Childs.Count == 1 && root.Childs[0].ClassName == "DirectUIHWND")
            {
                root = root.Childs[0];
            }
            else
            {
                throw new Exception("未找到窗体");
            }

            // 拿到4个子窗体,但是顺序还不确定
            var drawWindows = root.Childs
                              .Where(w => w.ClassName == "CtrlNotifySink" && w.Childs.Count == 1 && w.Childs[0].ClassName == "CvChartWindow")
                              .Select(w => w.Childs[0])
                              .OrderByDescending(w => w.Rect.Width * w.Rect.Height)
                              .Take(kernelCount)
                              .ToArray();

            // 以下是捕获声音有关的代码,使用的是WASAPI Loopback的方式
            var screenWidth = WinApi.GetScreenWidth();
            FixedQueueArray <float> leftWaveQueue = new FixedQueueArray <float>(screenWidth), rightWaveQueue = new FixedQueueArray <float>(screenWidth);
            IWaveIn loopbackCapture = new WasapiLoopbackCapture();
            var     observer        = new StreamObserver <float>(FFTSize, FFTSize / 2, 2);

            float[] leftFixedWaveData = new float[FFTSize], rightFixedWaveData = new float[FFTSize];

            // 捕获声音
            // leftFixedWaveData 和 rightFixedWaveData 之后会交给绘制频谱的线程处理
            observer.Completed += newData => {
                lock (fftLock) {
                    for (int i = 0; i < leftFixedWaveData.Length; i++)
                    {
                        leftFixedWaveData[i]  = newData[2 * i + 0];
                        rightFixedWaveData[i] = newData[2 * i + 1];
                    }
                }
            };

            // 捕获声音
            // leftWaveQueue 和 rightWaveQueue 之后会交给绘制声波的线程处理
            loopbackCapture.DataAvailable += (_, e) => {
                var waveData   = MemoryMarshal.Cast <byte, float>(new ReadOnlySpan <byte>(e.Buffer, 0, e.BytesRecorded));
                int copyLength = Math.Min(waveData.Length / 2, screenWidth);
                if (copyLength == 0)
                {
                    return;
                }
                Span <float> leftNextData = stackalloc float[copyLength], rightNextData = stackalloc float[copyLength];
                for (int i = 0; i < copyLength; i++)
                {
                    leftNextData[i]  = waveData[2 * i + 0];
                    rightNextData[i] = waveData[2 * i + 1];
                }
                leftWaveQueue.Write(leftNextData);
                rightWaveQueue.Write(rightNextData);
                observer.Write(waveData);
            };
            loopbackCapture.StartRecording();

            var  sampleRate    = loopbackCapture.WaveFormat.SampleRate;
            bool polylineStyle = false;

            // 找出对应位置的子窗体
            var leftTopWin     = drawWindows.OrderBy(w => w.Rect.X + w.Rect.Y).First();
            var rightTopWin    = drawWindows.OrderBy(w => - w.Rect.X + w.Rect.Y).First();
            var leftBottomWin  = drawWindows.OrderBy(w => w.Rect.X - w.Rect.Y).First();
            var rightBottomWin = drawWindows.OrderBy(w => - w.Rect.X - w.Rect.Y).First();

            void StartThread(Action action)
            {
                new Thread(new ThreadStart(action))
                {
                    Priority = ThreadPriority.Highest
                }.Start();
            }

            // 启动线程开始捕获声音并绘制,每个窗体一个线程
            StartThread(() => DrawWave(leftTopWin, leftWaveQueue, polylineStyle, 1));
            StartThread(() => DrawWave(rightTopWin, rightWaveQueue, polylineStyle, 2));
            StartThread(() => DrawSpectrum(leftBottomWin, leftFixedWaveData, sampleRate, polylineStyle, 3));
            StartThread(() => DrawSpectrum(rightBottomWin, rightFixedWaveData, sampleRate, polylineStyle, 4));

            Thread.Sleep(Timeout.Infinite);
        }
        public void StartService(String args)
        {
            if (_StartMode != ConsoleStartMode.Default || TCPServer != null || UDPServer != null)
            {
                Console.WriteLine("Input Arguments Exception.");
                return;
            }

            Console.Title = Title;
            _StartMode    = ConsoleStartMode.Service;

            //安全退出处理
            ControlCtrl = new ControlCtrlDelegate(ConsoleExitHandler);
            ConsoleApplication.SetConsoleCtrlHandler(ControlCtrl, true);

            //服务模式启动后不可重复启动
            bool  createdNew;
            Mutex mutex = new Mutex(true, InputHeader + ".Service", out createdNew);

            if (!createdNew)
            {
                Console.WriteLine("Services Error 服务正在运行中 ...");
                MessageBox.Show("服务正在运行中...", "Error", MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);
                Console.WriteLine("Exiting ...");

                Thread.Sleep(100);
                Environment.Exit(0);
                return;
            }

            if (!String.IsNullOrWhiteSpace(args) && ConsoleApplication.Uint_Regex.IsMatch(args))
            {
                ServicePort = Convert.ToInt32(args);
            }

            //独立线程运行服务
            Thread thread = new Thread(() =>
            {
                Console.Title = String.Format("{0}   Port:{1}", Title, ServicePort);
                Console.WriteLine("{0} Starting ... ", Title);

                TCPServer = new TCPServer();
                if (TCPServer.Start(ServicePort))
                {
                    TCPServer.ServerDataReceived += Server_DataReceived;
                    TCPServer.ServerStateChanged += Server_StateChanged;
                    TCPServer.ClientStateChanged += Server_ClientStateChanged;
                    Console.WriteLine("TCP Server 启功完成 Port:{0},等待客户端连接 ...", ServicePort);
                }
                else
                {
                    TCPServer.Destroy();
                    TCPServer = null;
                    Console.WriteLine("TCP Server 启动失败,检查端口 {0} 是否被占用", ServicePort);
                }

                UDPServer = new UDPServer();
                if (UDPServer.Start(ServicePort))
                {
                    UDPServer.ServerDataReceived += Server_DataReceived;
                    UDPServer.ServerStateChanged += Server_StateChanged;
                    UDPServer.ClientStateChanged += Server_ClientStateChanged;
                    Console.WriteLine("UDP Server 启功完成 Port:{0},等待客户端连接 ...", ServicePort);
                }
                else
                {
                    UDPServer.Destroy();
                    UDPServer = null;
                    Console.WriteLine("UDP Server 启动失败,检查端口 {0} 是否被占用", ServicePort);
                }
                Console.Write("{0}>", InputHeader);
            });

            thread.Name = Title;
            thread.Start();

            //可输入模式
            while (_StartMode == ConsoleStartMode.Service)
            {
                Console.Write("{0}>", InputHeader);
                String input = Console.ReadLine();
                if (String.IsNullOrWhiteSpace(input))
                {
                    continue;
                }

                String[] arguments = ConsoleApplication.ParserInput(input);
                if (arguments != null)
                {
                    ConsoleApplication.Run(this, arguments);
                }
            }
        }
Exemplo n.º 6
0
		public static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate HandlerRoutine, bool Add);