I am new to C# and I want to create a windows forms application, which shows (it must be visible!) one window with some information and buttons and also it loads a page from internet (with selenium and phantom.js - though it is deprecated) every minute. I've written something like this:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
namespace WindowsFormsApplication1
{
public partial class Someclass : Form
{
private void label1_Click(object sender, EventArgs e)
{
}
private void Someclass_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// Shows some text "Hello friend"
MessageBox.Show("Hello friend!");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello again", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public Someclass()
{
InitializeComponent();
while (!IsDisposed)
{
MessageBox.Show("Now the page will be downloaded");
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
using (var driver = new PhantomJSDriver(driverService))
{
driver.Navigate().GoToUrl("http://stackoverflow.com/");
MessageBox.Show("Here we are going to open StackOverflow");
var questions = driver.FindElements(By.ClassName("fs-display2"));
foreach (var question in questions)
{
// This will display some text from stackoverflow main page.
Console.WriteLine(question.Text);
question.Click();
MessageBox.Show("This is stackoverflow: " + question.Text);
}
MessageBox.Show("Here we go");
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
}
}
My problem is that if I use "while", my window does not appear (but the page from internet loads correctly - every 1 minute), and if I use "if" instead of "while", my window appears well, but, of cource, the page loading goes only one time. What can solve my problem?
It's a quite simple solution: your while loop is preventing your UI from Update. You have to bring your loop in an extra Thread, or just use a backgroundworker
Yes, friends, you were right. I have put (using panel of instruments-> Background Worker):
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
while (!IsDisposed)
{
......................
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
inside my public partial class someClass : Form after public Someclass()
and also added:
backgroundWorker1.RunWorkerAsync(2000);
inside my public Someclass()
So now the code looks like:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using OpenQA.Selenium;
using OpenQA.Selenium.PhantomJS;
namespace WindowsFormsApplication1
{
public partial class Someclass : Form
{
private void label1_Click(object sender, EventArgs e)
{
}
private void Someclass_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// Shows some text "Hello friend"
MessageBox.Show("Hello friend!");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello again", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
public Someclass()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync(2000);
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
while (!IsDisposed)
{
MessageBox.Show("Now the page will be downloaded");
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.HideCommandPromptWindow = true;
using (var driver = new PhantomJSDriver(driverService))
{
driver.Navigate().GoToUrl("http://stackoverflow.com/");
MessageBox.Show("Here we are going to open StackOverflow");
var questions = driver.FindElements(By.ClassName("fs-display2"));
foreach (var question in questions)
{
// This will display some text from stackoverflow main page.
Console.WriteLine(question.Text);
question.Click();
MessageBox.Show("This is stackoverflow: " + question.Text);
}
MessageBox.Show("Here we go");
}
System.Threading.Thread.Sleep(60000); // delay in microseconds
}
}
}
and works fine.
Related
Iam very new to coding so please pardon my lack of knowledge.
I made a program "Music player" that uses webBrowser to play video from youtube but from what i understood from other posts it cant work due to webBrowser being IE7. I dont neccessarily have to use webBrowser but it seemed like the best way.
Is there a way to "update" IE or do i need to use different method?
code:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.RegularExpressions;
namespace MusicPlayer_V4._1
{
public partial class Form1 : Form
{
string _ytUrl;
public Form1()
{
InitializeComponent();
}
public string VideoId
{
get
{
var ytMatch = new Regex(#"youtu(?:\.be|be\.com) / (?:.*v(?:.*/|=)|(?:.*/)?)([a-zA-Z0-_]+)").Match(_ytUrl);
return ytMatch.Success ? ytMatch.Groups[1].Value : string.Empty;
}
}
//user input (URL)
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
//play button
private void button1_Click(object sender, EventArgs e)
{
_ytUrl = txtUrl.Text;
webBrowser.Navigate($"http://youtube.com/v/{VideoId}?version=3");
}
//help button
private void button2_Click(object sender, EventArgs e)
{
}
//browser
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
}
}
The way moving forward is to use WebView2 which is basically the same thing as a WebView but based on the chromium-based edge. It will be always up to date on windows 10/11 machines and it works down to Windows 7.
https://developer.microsoft.com/en-us/microsoft-edge/webview2/
I am currently using WinForms Application and it seems that I have ran into a problem. I have a button that when pressed it outputs a link in a RichTextBox. However, the link is highlighted in blue but when I click it does not open in my browser. Here is the code(Note that https://something.com/ represents an actual link.):
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Project
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
richTextBox1.Text = "https://something.com/" + textBox1.Text;
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
I cannot get the ui thread to update the ui while the file copy thread is running. My end goal is to have the animation continue to rotate until the large file copy finally completes to let the user know that the program is not frozen. It's a very simple server to server file copy program.
Can someone tell me what I'm doing wrong?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ResetProgress()
{
lblStep1.Image = null;
}
private void SetupProgress()
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private void fileCopy()
{
File.Copy("large file source", "large file destination", true);
}
private void Form1_Load(object sender, EventArgs e)
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private async void button1_Click(object sender, EventArgs e)
{
SetupProgress();
await Task.Run(() => fileCopy());
ResetProgress();
}
private void btnStop_Click(object sender, EventArgs e)
{
// unhandled currently
}
}
}
* Original version *
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Thread workItemsProducerThread;
private Thread workItemsCopyThread;
public Form1()
{
InitializeComponent();
}
private void ResetProgress()
{
lblStep1.Image = null;
}
private void SetupProgress()
{
this.BeginInvoke((MethodInvoker)delegate ()
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
});
}
private void fileCopy()
{
File.Copy("Large file source", "Large file destination", true);
this.BeginInvoke((MethodInvoker)delegate ()
{
MessageBox.Show("Done");
});
}
private void Form1_Load(object sender, EventArgs e)
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
private void btnStart_Click(object sender, EventArgs e)
{
this.workItemsProducerThread = new Thread(new ThreadStart(this.SetupProgress));
this.workItemsProducerThread.IsBackground = true;
this.workItemsProducerThread.Start();
this.SetupProgress();
this.workItemsCopyThread = new Thread(new ThreadStart(this.fileCopy));
this.workItemsCopyThread.IsBackground = true;
this.workItemsCopyThread.Start();
while (workItemsCopyThread.IsAlive)
{
Thread.Sleep(1000); // wait
}
MessageBox.Show("Done");
}
private void btnStop_Click(object sender, EventArgs e)
{
if (this.workItemsProducerThread != null)
{
this.workItemsProducerThread.Abort();
lblStep1.Image = global::animation1.Properties.Resources.animation;
}
}
private void btnTest_Click(object sender, EventArgs e)
{
fileCopy();
}
}
}
Don’t sleep in your click handler. That freezes the UI thread. Just let the clock handler exit. In your file copy thread, when the copy is don’t. Use Invoke(or BeginInvoke) to cause the done messagebox to pop up on the UI thread.
Try this oldy style
private void SetupProgress()
{
Invoke((MethodInvoker) delegate
{
lblStep1.Image = global::animation1.Properties.Resources.animation;
});
}
private Thread TDoSomeWork()
{
var t = new Thread(() => DoSomeWork());
t.Start();
return t;
}
TDoSomeWork();
So for some reason when I code this.Close(); into my program it won't actually close it.
I have the program open a different .exe file then close, but I open my task manager and it actually is still running in the background. I have this issue with the "Close" option on my context menu also.
Any ideas why?
EDIT: Even when I exit with the button, it's still in the background.
EDIT:
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
this.Close();
}
private void launch_Click(object sender, EventArgs e)
{
System.Diagnostics.Process.Start(Environment.ExpandEnvironmentVariables("%AppData%\\program.exe"));
this.Close();
}
Only actual two codes that are closing the program. But it's still running in the background.
Even when I exit through the actual x button, it still runs in the background.
You must close the process that you've created. Create a variable to save the process that has been created and when you close the form or press another button close process. See: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.close.aspx
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
private Process _process;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this._process = Process.Start("notepad.exe");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (this._process != null) {
this._process.CloseMainWindow();
this._process.Close();
}
}
}
}
As menstion in above comment add using System.Diagnostics; to your code and try this code
public Form1()
{
InitializeComponent();
Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
}
void Application_ApplicationExit(object sender, EventArgs e)
{
Process.GetCurrentProcess().Kill();
}
I want to transfer my code to a WinForms.
I know how to create buttons, text, etc... and how to operate them.
The problem is that I made my code in a windows application, and I want to transform it to WinForms application. I don't know how to copy and paste the whole code, cause in the WinForms application there is no main method..
Here is my code that I am trying to transfer to WinForms:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
TcpClient connection = new TcpClient("127.0.0.1", 5000);
StreamReader sr = new StreamReader(connection.GetStream());
StreamWriter sw = new StreamWriter(connection.GetStream());
string name2 = "";
while (true)
{
Console.WriteLine("Enter your name and press submit");
name2=Console.ReadLine();
if (name2 != "")
{
sw.WriteLine(name2);
break;
}
}
Console.WriteLine("Loop is over");
Thread t2 = new Thread(Reader);
t2.IsBackground = true;
t2.Start(connection);
while (true)
{
sw.WriteLine(Console.ReadLine());
sw.Flush();
}
}
public static void Reader(object o)
{
TcpClient con = o as TcpClient;
if (con == null)
return;
StreamReader sr = new StreamReader(con.GetStream());
while (true)
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine();
}
Console.WriteLine(sr.ReadLine());
Console.WriteLine();
}
}
}
}
Here is the Form that I have created:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void label1_Click(object sender, EventArgs e)
{
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
}
}
}
In windows form application there is main method but it is in program.cs file and its starts your default form after you program starts execution.
You can add the the textbox in form and on button event get the text of the textbox.
String username = textboxusername.Text;
Similarly you can do all the things you want.
The code that you have written before was for console application and that is not the same for the windows form application.
You have to code differently for this.