Search code examples
c#startupsystem-tray

c# Program that runs on Windows Startup behaving strangely


I have a program in testing - only running on a few desktops - that sometimes gives very strange behavior on Windows startup.

The program starts with this:

public frmClient()
{
    _version = ApplicationDeployment.IsNetworkDeployed ? ApplicationDeployment.CurrentDeployment.CurrentVersion : _version;
    _nicText = string.Format("My Program ({0})", _version.ToString());

    Logger.LogToFile(string.Format("Startup - Build: {0}, Major: {1}, MajorRevision: {2}, Minor: {3}, MinorRevision: {4}, Revision {5}", 
        _version.Build, 
        _version.Major, 
        _version.MajorRevision, 
        _version.Minor, 
        _version.MinorRevision, 
        _version.Revision));

    InitializeComponent();
}

The form actually starts minimized to the System Tray, and in the Load it uses the _nicText to set the tooltip of the Notification Icon as follows:

private void frmClient_Load(object sender, EventArgs e)
{
    try
    {
        Logger.LogToFile("frmClient.frmClient_Load");

        nicMain.Text = _nicText + " - NOT CONNECTED";
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

The Logger class is as follows:

public static class Logger
{
    public static void LogToFile(string LogMessage)

    {
        StreamWriter log;

        if (!File.Exists("logfile.txt"))
        {
            log = new StreamWriter("logfile.txt");
        }
        else
        {
            log = File.AppendText("logfile.txt");
        }

        log.WriteLine(DateTime.Now.ToString("yyyyMMddHHmmss") + " - " + LogMessage);
        log.Close();
    }
}

If I run the program locally, I get (0.0) for the version information, otherwise I get a full version (1.0.0.31 currently)

However, sometimes at startup I'll have a user show (0.0) as a version, and in these cases there is NOTHING written to the log file.

Currently my only guess is that the application is starting before Windows is ready for it (just a blind guess). Does this happen? If so, is there any way for me to delay until Windows is ready? Am I missing something else?


Solution

  • The code that caused the problem wasn't in what I posted in my initial question. As pointed out by user Hans Passant, the issue was actually with the way my program was starting up.

    Originally, this was how I was setting the program to start up:

    RegistryKey regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
    
    if (regKey.GetValue("MyKey") == null || regKey.GetValue("MyKey").ToString() != Application.ExecutablePath.ToString())
    {
        regKey.SetValue("MyKey", Application.ExecutablePath.ToString());
    }
    

    After reading the code at Returning ClickOnce version doesn't work when launching application on startup from the Windows Registry, I have now changed my code to be:

    string compName = "MyCompany";
    string keyName = "MyKey";
    string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
    string shortcutPath = Path.Combine(allProgramsPath, compName);
    shortcutPath = Path.Combine(shortcutPath, keyName) + ".appref-ms";
    
    RegistryKey regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
    
    if (regKey.GetValue(keyName) == null || regKey.GetValue(keyName).ToString() != shortcutPath)
    {
        regKey.SetValue(keyName, shortcutPath);
    }
    

    Now, instead of running the exe directly at startup, it is running the ClickOnce link, which appears to handle the version information correctly.

    Thanks again Hans Passant for the help!