从program.cs中的Main方法启动Form的计时器

问题描述 投票:0回答:1

我在系统托盘中启动我的应用程序,如下所示:

static void Main(){

//mutex (Prevents app from running twice
if (mutex.WaitOne(TimeSpan.Zero, true))
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
   
    mutex.ReleaseMutex();

   
    RadForm2 mainForm = new RadForm2();
  

    // Handle the FormClosing event to minimize to tray instead of closing
    mainForm.FormClosing += (sender, e) =>
    {
        e.Cancel = true;
        mainForm.Hide();
    };

    // Create a NotifyIcon to display in the system tray
    NotifyIcon notifyIcon = new NotifyIcon();
    notifyIcon.Icon = System.Drawing.Icon.ExtractAssociatedIcon(Application.ExecutablePath);
    notifyIcon.Text = "My App";
    notifyIcon.Visible = true;

    // Handle the DoubleClick event of the NotifyIcon to show the main form
    notifyIcon.DoubleClick += (sender, e) =>
    {
        mainForm.Show();
        mainForm.WindowState = FormWindowState.Normal;
    };

    // Add a context menu to the NotifyIcon for additional options
    ContextMenu contextMenu = new ContextMenu();
    contextMenu.MenuItems.Add("Open", (sender, e) =>
    {
        mainForm.Show();
        mainForm.WindowState = FormWindowState.Normal;
    });
    contextMenu.MenuItems.Add("Exit", (sender, e) =>
    {
        notifyIcon.Visible = false;
        mainForm.Dispose();
        Application.Exit();
        //Environment.Exit(0); // if dispose is not used app wont exit
    });
    notifyIcon.ContextMenu = contextMenu;

    // Run the application
    Application.Run();
    
}
else
{
    MessageBox.Show("Already running", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

Mainform 上有一个

fileSystemWatcher
控件,用于监视特定文件夹,当该文件夹发生更改时,它会启动计时器来发送电子邮件。

这是这里的主要问题:

  1. 我的应用程序在托盘中启动没有问题
  2. 发生更改时触发
    fileSystemWatcher
  3. 从这一步开始,
    timer
    将不起作用。

注意:如果我双击通知图标并显示主窗体,一切都会按预期工作,但不会显示主窗体,

the timer won't work.

有什么解决办法吗?

c# winforms timer
1个回答
0
投票

根据您的描述和代码,我尝试重现您所看到的问题,但没有成功。唯一未知的似乎是“无论

RadForm2
中的计时器处理程序中发生了什么”,但在这个最小的示例中(它所做的只是更新标题栏中的时钟),计时器明显正在运行。

internal static class Program
{
    [STAThread]
    static void Main()
    {
        if (mutex.WaitOne(TimeSpan.Zero, true))
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            ApplicationConfiguration.Initialize();
            var path = Path.Combine(
                Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                Assembly.GetEntryAssembly().GetName().Name
            );
            Directory.CreateDirectory(path);

            // Open the folder so we can mess with the files.
            Process.Start(new ProcessStartInfo { FileName = path, UseShellExecute = true});

            using (var mainForm = new RadForm2())
            using(var fileWatcher = new FileSystemWatcher(path))
            {
                mainForm.MyTimer = new System.Windows.Forms.Timer
                {
                    Interval = 100,
                    Enabled = true,
                };
                mainForm.MyTimer.Tick += (sender, e) =>
                {
                    // In System Windows Forms.Timer, the Tick is already
                    // marshaled onto the UI thread and won't allow reentrancy.
                    // Other timers are less forgiving than that. To make sure
                    // that it's running, have it update a clock in the title bar.
                    if (mainForm.Visible) mainForm.Text = DateTime.Now.ToString();
                };
                fileWatcher.EnableRaisingEvents = true;
                fileWatcher.Created += (sender, e) => Debug.WriteLine($"{nameof(FileSystemWatcher.Created)}: {e.Name}");
                fileWatcher.Changed += (sender, e) => Debug.WriteLine($"{nameof(FileSystemWatcher.Changed)}: {e.Name}");
                fileWatcher.Renamed += (sender, e) => Debug.WriteLine($"{nameof(FileSystemWatcher.Renamed)}: {e.Name}");
                fileWatcher.Deleted += (sender, e) => Debug.WriteLine($"{nameof(FileSystemWatcher.Deleted)}: {e.Name}");
                mainForm.FormClosing += (sender, e) =>
                {
                    if (e.CloseReason == CloseReason.UserClosing)
                    {
                        e.Cancel = true;
                        mainForm.Hide();
                    }
                };
                NotifyIcon notifyIcon = new NotifyIcon();
                notifyIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
                notifyIcon.Text = "My App";
                notifyIcon.Visible = true;
                notifyIcon.DoubleClick += (sender, e) =>
                {
                    mainForm.Show();
                    mainForm.WindowState = FormWindowState.Normal;
                };
                ContextMenuStrip contextMenu = new ContextMenuStrip();
                contextMenu.Items.Add("Open", null, (sender, e) =>
                {
                    mainForm.Show();
                    mainForm.WindowState = FormWindowState.Normal;
                });
                contextMenu.Items.Add("Exit", null, (sender, e) =>
                {
                    notifyIcon.Visible = false;
                    mutex.ReleaseMutex();
                    Application.Exit();
                });
                notifyIcon.ContextMenuStrip = contextMenu;
                Application.Run();
            }
        }
        else
        {
            MessageBox.Show("Already running", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
    static Mutex mutex = new Mutex(true, "{3B50E02B-383F-4604-AF3E-6B79DD5B0926}");
}

代码中建议进行三处更改,但它们实际上不应该对您所看到的实际问题产生任何影响。

  • 将互斥释放移至“退出”处理程序,以便它将执行您所描述的操作。
  • 更改了
    formClosing
    ,以便在用户关闭时保留
    hWnd
    ,但允许其他所有操作(例如在应用程序尝试关闭时处置窗口)。
  • IDisposable
    实例包装在
    using
    块中。
© www.soinside.com 2019 - 2024. All rights reserved.