Why does my program freeze when timer_Tick code runs?

89 Views Asked by At

My program is made to auto open another program when ROBLOX opens. I know that's weird but helpful to me. Once the program is open, my buttons and everything work fine. Once I enable it, and open ROBLOX, the application breaks until ROBLOX is closed. Just freezes, no errors. Doesn't open the other application either. Please help!

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ProtoSmasher_Auto_Opener
{
    public partial class Form1 : Form
    {
        string path;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if(!File.Exists(@"c:\PSAutoStart\path.proto"))
            {
                MessageBox.Show("It seems like this is your first time running. Please make sure File Manager is closed for your first run.", "Notice");
            }
            if (File.Exists(@"c:\PSAutoStart\path.proto"))
            {
                string lastPath;
                using (StreamReader sr = new StreamReader(@"c:\PSAutoStart\path.proto"))
                {
                    lastPath = sr.ReadToEnd();
                }
                textBox1.Text = lastPath;
                path = lastPath;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.BackColor != System.Drawing.Color.Red)
            {
                if(textBox1.Text == "")
                {
                    MessageBox.Show("Please click browse and locate ProtoSmasher to activate.", "Error");
                }
                else
                {
                    button1.BackColor = System.Drawing.Color.Red;
                    button1.Text = "Deactivate";
                    timer1.Start();
                }
            }
            else
            {      
                button1.BackColor = System.Drawing.Color.Green;
                button1.Text = "Activate";
                timer1.Stop();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();
            fileDialog.Filter = "ProtoSmasher (*.exe)|*.exe";
            if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                path = fileDialog.FileName;
                if (!File.Exists(@"c:\PSAutoStart\path.proto"))
                {
                    DirectoryInfo di = Directory.CreateDirectory(@"c:\PSAutoStart");
                    try
                    {
                        System.Threading.Thread.Sleep(2 * 1000);
                        StreamWriter sw = File.CreateText(@"c:\PSAutoStart\path.proto");
                        sw.WriteLine(path);
                        textBox1.Text = path;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Didn't I tell you to close your file manager first?", "Error");
                    }
                }
                else
                {
                    using (StreamWriter sw = File.CreateText(@"c:\PSAutoStart\path.proto"))
                    {
                        sw.WriteLine(path);
                    }
                    textBox1.Text = path;
                }
            }

        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            Process[] roblox = Process.GetProcessesByName("RobloxPlayerBeta");
            if (roblox.Length > 0)
            {
                try
                {
                    Process.Start(textBox1.Text);
                    stillRunning.Start(); //to keep from spamming open
                    timer1.Stop(); 
                }
                catch(Exception ex)
                {
                    MessageBox.Show("Something went wrong: " + ex, "Error");
                }
            }
        }

        private void stillRunning_Tick(object sender, EventArgs e)
        {
            Process[] roblox = Process.GetProcessesByName("RobloxPlayerBeta");
            if(roblox.Length > 0)
            { }
            else
            {
                timer1.Start();
                stillRunning.Stop();
            }
        }
    }
}
1

There are 1 best solutions below

3
Christopher On BEST ANSWER

There is something just shy of a dozen timers in .NET. I am going to asume it is the WindowsForms Timer:

Only one piece of code can run per Thread. And the WindowsForms timer runs in the GUI thread. Timers varry a lot in this regard, but then you also might have to deal with CrossThread saftey. I think you want to add some explicit multitasking into the mix.

Multitasking is a very tricky are to learn. My usual advice for learning it is using the BackgroundWorker in a WindowsForms application. You would not want to be caught with it in production code, but it is a very good set "training wheels". I also have some old example on how to use it:

#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
    if (!bgwPrim.IsBusy)
    {
        //Prepare ProgressBar and Textbox
        int temp = (int)nudPrim.Value;
        pgbPrim.Maximum = temp;
        tbPrim.Text = "";

        //Start processing
        bgwPrim.RunWorkerAsync(temp);
    }
}

private void btnPrimCancel_Click(object sender, EventArgs e)
{
    if (bgwPrim.IsBusy)
    {
        bgwPrim.CancelAsync();
    }
}

private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
    int highestToCheck = (int)e.Argument;
    //Get a reference to the BackgroundWorker running this code
    //for Progress Updates and Cancelation checking
    BackgroundWorker thisWorker = (BackgroundWorker)sender;

    //Create the list that stores the results and is returned by DoWork
    List<int> Primes = new List<int>();


    //Check all uneven numbers between 1 and whatever the user choose as upper limit
    for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
    {
        //Report progress
        thisWorker.ReportProgress(PrimeCandidate);
        bool isNoPrime = false;

        //Check if the Cancelation was requested during the last loop
        if (thisWorker.CancellationPending)
        {
            //Tell the Backgroundworker you are canceling and exit the for-loop
            e.Cancel = true;
            break;
        }

        //Determin if this is a Prime Number
        for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
        {
            if (PrimeCandidate % j == 0)
                isNoPrime = true;
        }

        if (!isNoPrime)
            Primes.Add(PrimeCandidate);
    }

    //Tell the progress bar you are finished
    thisWorker.ReportProgress(highestToCheck);

    //Save Return Value
    e.Result = Primes.ToArray();
}

private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    pgbPrim.Value = e.ProgressPercentage;
}

private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    pgbPrim.Value = pgbPrim.Maximum;
    this.Refresh();

    if (!e.Cancelled && e.Error == null)
    {
        //Show the Result
        int[] Primes = (int[])e.Result;

        StringBuilder sbOutput = new StringBuilder();

        foreach (int Prim in Primes)
        {
            sbOutput.Append(Prim.ToString() + Environment.NewLine);
        }

        tbPrim.Text = sbOutput.ToString();
    }
    else 
    {
        tbPrim.Text = "Operation canceled by user or Exception";
    }
}
#endregion

However I am a bit uncertain what your programm even does. Getting all the processes with a specific string and force-closing them?