using System.IO; using Microsoft.Win32; using System.Diagnostics; using DBObj; using DataCheck; namespace DualScreenDemo { public static class Program { // 定义全局变量 internal static SongListManager songListManager; //internal static ArtistManager artistManager; internal static SerialPortManager serialPortManager; private static PrimaryForm primaryForm; // 儲存實例的參考 [STAThread] static void Main() { Console.WriteLine("隱藏滑鼠游標"); // Cursor.Hide(); AppDomain.CurrentDomain.ProcessExit += (s, e) => { Cursor.Show(); }; Console.WriteLine("正在喚醒SVR裝置(每3分鐘呼叫一次)..."); _ = Task.Run(async () => { while (true) { _ = Directory.Exists(@"\\svr01\video"); _ = Directory.Exists(@"\\svr02\video"); await Task.Delay(180000); // 每3min送一次 } }); // Console.WriteLine("正在與中控取得聯繫..."); /*var sender = new HeartbeatSender.heartbeatSender(); // 同步呼叫非同步登入取得 token bool loginSuccess = sender.LoginAndGetTokenAsync().GetAwaiter().GetResult(); if (loginSuccess) { // 先送一次心跳 (同步呼叫) sender.SendHeartbeatAsync().GetAwaiter().GetResult(); // 背景持續每5分鐘送心跳 _ = Task.Run(async () => { while (true) { await sender.SendHeartbeatAsync(); await Task.Delay(300000); // 每5min送一次 } }); Console.WriteLine("正在發送心跳中..."); } else { Console.WriteLine("登入失敗,無法送出心跳"); } */ //之後需要做添加同步菜單+酒單+背景圖(若圖規格有做正規化) // DataCheck.cs 有預寫好相關流程函式 Console.WriteLine("更新菜單和酒單..."); dataCheck Checkprocess = new dataCheck(); try { // COM 初始化 int hr = ComInterop.CoInitializeEx(IntPtr.Zero, ComInterop.COINIT_APARTMENTTHREADED); if (hr < 0) { Console.WriteLine("Failed to initialize COM library."); return; } // 初始化管理器 songListManager = new SongListManager(); // 使用单例 //artistManager = new ArtistManager(); var commandHandler = new CommandHandler(songListManager); serialPortManager = new SerialPortManager(commandHandler); serialPortManager.InitializeSerialPort(); // 輸出屏幕信息 Console.WriteLine($"Virtual Screen: {SystemInformation.VirtualScreen}"); foreach (var screen in Screen.AllScreens) { Console.WriteLine($"Screen: {screen.DeviceName} Resolution: {screen.Bounds.Width}x{screen.Bounds.Height}"); } // 啟動服務器 Task.Run(() => HttpServerManager.StartServer()); Task.Run(() => TCPServerManager.StartServer()); // 註冊事件 Application.ApplicationExit += (sender, e) => SerialPortManager.CloseSerialPortSafely(); SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged; // 創建主窗體 primaryForm = new PrimaryForm(); //primaryForm.allSongs = songListManager.AllSongs; //primaryForm.allArtists = artistManager.AllArtists; primaryForm.StartPosition = FormStartPosition.Manual; primaryForm.Location = new Point(0, 0); primaryForm.Size = new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); // 在完整初始化後檢查狀態 string stateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "txt", "states.txt"); bool isClosedState = File.Exists(stateFilePath) && File.ReadAllText(stateFilePath).Trim().Equals("CLOSE", StringComparison.OrdinalIgnoreCase); InitializeSecondaryScreen(); // 使用 Shown 事件來確保窗體完全加載後再顯示送客畫面 if (isClosedState) { primaryForm.Shown += (s, e) => { primaryForm.ShowSendOffScreen(); }; } WatchDog _watchDog = new WatchDog( () => VideoPlayerForm.Instance.GetCurrentVideoStatus(), () => primaryForm.IsAppResponsive() ); _watchDog.Start(); Console.WriteLine("啟動WatchDog進行監聽"); AppDomain.CurrentDomain.ProcessExit += (s, e) => { _watchDog.Stop(); }; primaryForm.Show(); Application.Run(primaryForm); } catch (Exception ex) { WriteLog(ex.ToString()); } finally { SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged; } } private static bool IsUrlAclExists(string url) { try { ProcessStartInfo startInfo = new ProcessStartInfo { FileName = "netsh", Arguments = "http show urlacl", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (Process process = Process.Start(startInfo)) { using (StreamReader reader = process.StandardOutput) { string output = reader.ReadToEnd(); return output.Contains(url); // 检查是否包含指定 URL } } } catch (Exception ex) { Console.WriteLine("检查 URL ACL 时出错: " + ex.Message); return false; } } private static void InitializeSecondaryScreen() { if (Screen.AllScreens.Length > 1) { var secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary); if (secondaryScreen != null) { // 确保 primaryForm 和 videoPlayerForm 已经正确初始化 if (primaryForm.videoPlayerForm == null) { primaryForm.videoPlayerForm = new VideoPlayerForm(); } // 设置 videoPlayerForm 的位置和大小 // primaryForm.videoPlayerForm.StartPosition = FormStartPosition.Manual; // primaryForm.videoPlayerForm.Location = secondaryScreen.WorkingArea.Location; // primaryForm.videoPlayerForm.Size = secondaryScreen.WorkingArea.Size; // 显示 videoPlayerForm 在第二显示器 primaryForm.videoPlayerForm.Show(); // 初始化公共播放列表 primaryForm.videoPlayerForm.InitializePublicPlaylist(primaryForm.publicSongList); } } } private static void OnDisplaySettingsChanged(object sender, EventArgs e) { // UI操作應該放在try-catch塊中 try { if (Screen.AllScreens.Length > 1) { primaryForm.Invoke(new System.Action(() => { if (primaryForm.videoPlayerForm == null) { var filePath = @"D:\\video\\100015-周杰倫&aMei-不該-國語-vL-100-11000001.mpg"; if (File.Exists(filePath)) { Screen secondaryScreen = Screen.AllScreens.FirstOrDefault(s => !s.Primary); if (secondaryScreen != null) { primaryForm.videoPlayerForm = new VideoPlayerForm(); // primaryForm.primaryMediaPlayerForm = new PrimaryMediaPlayerForm(primaryForm, primaryForm.secondaryMediaPlayerForm); primaryForm.videoPlayerForm.InitializePublicPlaylist(primaryForm.publicSongList); primaryForm.videoPlayerForm.Show(); } } else { Console.WriteLine("File not found."); } } })); } } catch (Exception ex) { WriteLog("Error during display settings changed: " + ex.Message); } } static void WriteLog(string message) { // 指定日志文件的路径 string logFilePath = Path.Combine(Application.StartupPath, "txt", "mainlog.txt"); try { // 使用 StreamWriter 来向日志文件追加文本 using (StreamWriter writer = new StreamWriter(logFilePath, true)) { writer.WriteLine(String.Format("[{0}] {1}", DateTime.Now, message)); } } catch (Exception ex) { // 如果写入日志文件时发生错误,这里可以处理这些异常 // 例如:打印到控制台 Console.WriteLine(String.Format("Error writing to log file: {0}", ex.Message)); } } private static Form CreatePrimaryForm() { return new Form { WindowState = FormWindowState.Maximized, FormBorderStyle = FormBorderStyle.None }; } private static Form CreateSecondaryForm(Screen screen) { return new Form { Text = "Secondary Screen Form", StartPosition = FormStartPosition.Manual, Bounds = screen.Bounds, WindowState = FormWindowState.Maximized, FormBorderStyle = FormBorderStyle.None }; } } }