What is NewWindow2 and NewWindow3 in WebForm/WebBrowser - c#

I am trying to convert our current WebForms app to use CefSharp browser which uses ChromimumWebBrowser. I came across the below in current code:
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) {
if (!newWindow3ListenerAdded) {
newWindow3ListenerAdded = true;
SHDocVw.WebBrowser browser = (SHDocVw.WebBrowser)webBrowser.ActiveXInstance;
browser.NewWindow3 += Browser_NewWindow3;
browser.NewWindow2 += browser_NewWindow2;
}
}
private void browser_NewWindow2(ref object ppDisp, ref bool Cancel)
{
webform.webBrowser.GoBack();
ppDisp = webform.webBrowser.ActiveXInstance;
webform.Show();
}
private void Browser_NewWindow3(ref object ppDisp, ref bool cancel, uint dwFlags, string sourceUrl, string targetUrl)
{
cancel = true;
if (targetUrl.Contains(".pdf")) {
WebForm webForm = new WebForm();
webForm.Text = targetUrl;
webForm.Navigate(targetUrl);
webForm.Show();
} else {
webBrowser.Navigate(targetUrl);
}
}
Could someone please guide me in converting this to Cef. I know I have to implement OnBeforePopup() in ILifeSpanHandler. But how exactly can I write the logic to load pdf/GoBack/Navigate(targetUrl) for different types of popups.
I think I can easily convert Browser_NewWindow3() the way it is (checking if targetUrl.Contains(".pdf")) but on what condition do I handle browser_NewWindow2() logic i.e. webBrowser.GoBack(); ?
This is what I tried,
OnBeforePopup() {
newBrowser = null;
if (targetUrl.Contains(".pdf")) {
CefForm cefForm = new CefForm();
cefForm.Text = targetUrl;
cefForm.Navigate(targetUrl);
cefForm.Show();
return false;
} else {
browserControl.Load(targetUrl);
return true;
}
}
But how do I handle browser_NewWindow2 logic ?

Related

How to fix download issues for some users using WebClient DownloadFileAsync?

I created a Windows Form Application in C# that users of my game modification can use to download updates automatically.
The 'Launcher', as I call it, uses WebClient to download the updates. But the first release of the mod is very big (2,7 GB zipped). The launcher works perfect for me and most users, but for some users the extraction of the zip file logs an error where the file is corrupted and not readable.
I searched already on stack, and it is possible that the file might be corrupted or truncated due to bad internet connection. But how do I build in a method that fix that problem?
//Start downloading file
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += new
AsyncCompletedEventHandler(Client_DownloadFileCompleted);
webClient.DownloadProgressChanged += new
DownloadProgressChangedEventHandler(Client_DownloadProgressChanged);
webClient.DownloadFileAsync(new Uri("http://www.dagovaxgames.com/api/downloads/+ patch.path), downloadPath);
}
private void Client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
//install the update
InstallUpdate();
}
private void InstallUpdate()
{
var file = currentPatchPath;
//get the size of the zip file
fileInfo = new FileInfo(file);
_fileSize = fileInfo.Length;
installBackgroundWorker = new BackgroundWorker();
installBackgroundWorker.DoWork += ExtractFile_DoWork;
installBackgroundWorker.ProgressChanged += ExtractFile_ProgressChanged;
installBackgroundWorker.RunWorkerCompleted += ExtractFile_RunWorkerCompleted;
installBackgroundWorker.WorkerReportsProgress = true;
installBackgroundWorker.RunWorkerAsync();
}
EDIT, just showing install code so that you know I am using a backgroundworker to extract the zip.
Common approach here is to download large file in small chunks and put them together on client after completion. Using this approach you can: 1. run few downloads in parallel and 2. in case of problem with network you don't have to download entire file again, just download incomplete chunks.
I faced a similar issue many years ago and created a subclass of WebClient that uses the DownloadProgressChanged event and a timer to abort downloads that get hung up and cancels the download smoother than the underlying internet transport layer does. The code also supports a callback to notify the calling code of progress. I found that sufficient to smoothly handle occasional hiccups downloading 1GB-ish files.
The idea of breaking your download into multiple pieces also has merit. You could leverage a library such as 7-Zip to both create the chunks and piece them back together (many compression libraries have that feature; I'm personally most familiar with 7-Zip).
Here's the code I wrote. Feel free to use and/or modify in any way that's helpful to you.
public class JWebClient : WebClient, IDisposable
{
public int Timeout { get; set; }
public int TimeUntilFirstByte { get; set; }
public int TimeBetweenProgressChanges { get; set; }
public long PreviousBytesReceived { get; private set; }
public long BytesNotNotified { get; private set; }
public string Error { get; private set; }
public bool HasError { get { return Error != null; } }
private bool firstByteReceived = false;
private bool success = true;
private bool cancelDueToError = false;
private EventWaitHandle asyncWait = new ManualResetEvent(false);
private Timer abortTimer = null;
private bool isDisposed = false;
const long ONE_MB = 1024 * 1024;
public delegate void PerMbHandler(long totalMb);
public delegate void TaggedPerMbHandler(string tag, long totalMb);
public event PerMbHandler NotifyMegabyteIncrement;
public event TaggedPerMbHandler NotifyTaggedMegabyteIncrement;
public JWebClient(int timeout = 60000, int timeUntilFirstByte = 30000, int timeBetweenProgressChanges = 15000)
{
this.Timeout = timeout;
this.TimeUntilFirstByte = timeUntilFirstByte;
this.TimeBetweenProgressChanges = timeBetweenProgressChanges;
this.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(MyWebClient_DownloadFileCompleted);
this.DownloadProgressChanged += new DownloadProgressChangedEventHandler(MyWebClient_DownloadProgressChanged);
abortTimer = new Timer(AbortDownload, null, TimeUntilFirstByte, System.Threading.Timeout.Infinite);
}
protected void OnNotifyMegabyteIncrement(long totalMb)
{
NotifyMegabyteIncrement?.Invoke(totalMb);
}
protected void OnNotifyTaggedMegabyteIncrement(string tag, long totalMb)
{
NotifyTaggedMegabyteIncrement?.Invoke(tag, totalMb);
}
void AbortDownload(object state)
{
cancelDueToError = true;
this.CancelAsync();
success = false;
Error = firstByteReceived ? "Download aborted due to >" + TimeBetweenProgressChanges + "ms between progress change updates." : "No data was received in " + TimeUntilFirstByte + "ms";
asyncWait.Set();
}
private object disposeLock = new object();
void MyWebClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
if (cancelDueToError || isDisposed) return;
long additionalBytesReceived = e.BytesReceived - PreviousBytesReceived;
PreviousBytesReceived = e.BytesReceived;
BytesNotNotified += additionalBytesReceived;
if (BytesNotNotified > ONE_MB)
{
OnNotifyMegabyteIncrement(e.BytesReceived);
OnNotifyTaggedMegabyteIncrement(Tag, e.BytesReceived);
BytesNotNotified = 0;
}
firstByteReceived = true;
try
{
lock (disposeLock)
{
if (!isDisposed) abortTimer.Change(TimeBetweenProgressChanges, System.Threading.Timeout.Infinite);
}
}
catch (ObjectDisposedException) { } // Some strange timing issue causes this to throw now and then
}
public string Tag { get; private set; }
public bool DownloadFileWithEvents(string url, string outputPath, string tag = null)
{
Tag = tag;
asyncWait.Reset();
Uri uri = new Uri(url);
this.DownloadFileAsync(uri, outputPath);
asyncWait.WaitOne();
return success;
}
void MyWebClient_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
if (e.Error != null) success = false;
if (cancelDueToError || isDisposed) return;
asyncWait.Set();
}
protected override WebRequest GetWebRequest(Uri address)
{
var result = base.GetWebRequest(address);
result.Timeout = this.Timeout;
return result;
}
void IDisposable.Dispose()
{
lock (disposeLock)
{
isDisposed = true;
if (asyncWait != null) asyncWait.Dispose();
if (abortTimer != null) abortTimer.Dispose();
base.Dispose();
}
}
}
I fixed it using a combination of a BackgroundWorker and downloading in small chunks (following up mtkachenko's solution). It also checks if the length of the downloaded file is the same as the one on the server. Using that, it can continue the download where the connection was interupted.
private void DownloadPatch(Patch patch){
//using background worker now!
downloadBackgroundWorker = new BackgroundWorker();
downloadBackgroundWorker.DoWork += (sender, e) => DownloadFile_DoWork(sender, e, patch);
downloadBackgroundWorker.ProgressChanged += DownloadFile_ProgressChanged;
downloadBackgroundWorker.RunWorkerCompleted += DownloadFile_RunWorkerCompleted;
downloadBackgroundWorker.WorkerReportsProgress = true;
downloadBackgroundWorker.RunWorkerAsync();
}
private void DownloadFile_DoWork(object sender, DoWorkEventArgs e, Patch patch)
{
string startupPath = Application.StartupPath;
string downloadPath = Path.Combine(Application.StartupPath, patch.path);
string path = ("http://www.dagovaxgames.com/api/downloads/" + patch.path);
long iFileSize = 0;
int iBufferSize = 1024;
iBufferSize *= 1000;
long iExistLen = 0;
System.IO.FileStream saveFileStream;
// Check if file exists. If true, then check amount of bytes
if (System.IO.File.Exists(downloadPath))
{
System.IO.FileInfo fINfo =
new System.IO.FileInfo(downloadPath);
iExistLen = fINfo.Length;
}
if (iExistLen > 0)
saveFileStream = new System.IO.FileStream(downloadPath,
System.IO.FileMode.Append, System.IO.FileAccess.Write,
System.IO.FileShare.ReadWrite);
else
saveFileStream = new System.IO.FileStream(downloadPath,
System.IO.FileMode.Create, System.IO.FileAccess.Write,
System.IO.FileShare.ReadWrite);
System.Net.HttpWebRequest hwRq;
System.Net.HttpWebResponse hwRes;
hwRq = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(path);
hwRq.AddRange((int)iExistLen);
System.IO.Stream smRespStream;
hwRes = (System.Net.HttpWebResponse)hwRq.GetResponse();
smRespStream = hwRes.GetResponseStream();
iFileSize = hwRes.ContentLength;
//using webclient to receive file size
WebClient webClient = new WebClient();
webClient.OpenRead(path);
long totalSizeBytes = Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
int iByteSize;
byte[] downBuffer = new byte[iBufferSize];
while ((iByteSize = smRespStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
if (stopDownloadWorker == true)
{
autoDownloadReset.WaitOne();
}
saveFileStream.Write(downBuffer, 0, iByteSize);
long downloadedBytes = new System.IO.FileInfo(downloadPath).Length;
// Report progress, hint: sender is your worker
int percentage = Convert.ToInt32(100.0 / totalSizeBytes * downloadedBytes);
(sender as BackgroundWorker).ReportProgress(percentage, null);
}
}
As you can see, I report the progress, so that I have a working progress bar as well.
private void DownloadFile_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
statusTextLabel.Text = "Downloading updates for version " + currentDownloadingPatch + " (" + e.ProgressPercentage + "%)";
progressBar.Value = e.ProgressPercentage;
}

How to prevent hanging of application when a button is clicked multiple times?

I have an application where user can click on a Scan button to scan the image to preview in the application. When user clicks, usually a "Preparing to scan" message will be shown and goes away when the scan is 100% complete.
The scan works fine. The problem if I stress test it by pressing the scan button many times while it's doing it's work, the application completely hangs and the message just stays there and I had to restart my whole application.
The code: It's just a small section
private void ScanStripButton_Click(object sender, EventArgs e)
{
if (SCAN_INTO_BATCH)
{
GENERATE_BATCH_FOLDER = true;
StartTwainScan();
}
}
Any idea on how to prevent this issue?
Appreciate the help
EDIT:
public void StartTwainScan()
{
Boolean EnableUI = false;
Boolean ADF = false;
Boolean EnableDuplex = false;
if (Properties.Settings.Default.TwainShow.Equals("1"))
{
EnableUI = true;
}
if (Properties.Settings.Default.ScanType.Equals("2"))
{
ADF = true;
}
if (Properties.Settings.Default.DuplexEnable.Equals("1"))
{
EnableDuplex = true;
}
var rs = new ResolutionSettings
{
Dpi = GetResolution(),
ColourSetting = GetColorType()
};
var pg = new PageSettings()
{
Size = GetPageSize()
};
var settings = new ScanSettings
{
UseDocumentFeeder = ADF,
ShowTwainUI = EnableUI,
ShowProgressIndicatorUI = true,
UseDuplex = EnableDuplex,
Resolution = rs,
Page = pg
};
try
{
TwainHandler.StartScanning(settings);
}
catch (TwainException ex)
{
MessageBox.Show(ex.Message);
//Enabled = true;
//BringToFront();
}
}
This isn't going to be the correct answer, but you haven't shown enough code to give you the right code. It should point you in the right direction.
private void ScanStripButton_Click(object sender, EventArgs e)
{
ScanStripButton.Enabled = false;
if (SCAN_INTO_BATCH)
{
GENERATE_BATCH_FOLDER = true;
StartTwainScan();
}
ScanStripButton.Enabled = true;
}
Basically you disable the button when the scan starts and enable it when it finishes.
private async void ScanStripButton_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
if (SCAN_INTO_BATCH)
{
GENERATE_BATCH_FOLDER = true;
StartTwainScan();
}
});
}
or
private bool clicked = false;
private void ScanStripButton_Click(object sender, EventArgs e)
{
try
{
if(clicked)
return;
clicked = true;
if (SCAN_INTO_BATCH)
{
GENERATE_BATCH_FOLDER = true;
StartTwainScan();
}
}
finally
{
clicked = false;
}
}

Allow the user to start multiple processes with redirected output and input for all of them

I've been working on a project called Borealis Server Manager (https://github.com/cyberstrawberry101/Borealis-Server-Manager) since May of this year. I need help from anyone skilled enough in C# to do the following:
Allow the user to start multiple gameserver processes with arguments given to them, in upwards of dozens or hundreds of them as background processes, and still be able to switch the redirected output and input to those processes on-the-fly to the console window within Borealis.
This is what the console page looks like in Borealis:
You can see the screenshot here.
This is the code that currently launches the programs, merged with some code that was suggested by another Facepunch user months ago, but their new code seems to freeze Borealis while even one server is running, which is actually a step backwards, and I can't even get it to properly redirect console output into my console window in Borealis. I am completely okay with a rewrite of the code should someone step up to help Borealis enter beta stages. I've had the code functional enough to launch the servers externally, but internally, I can only get one server's output at a time, without killing all of the other servers. It's a pretty complex problem.
using MetroFramework;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Borealis
{
public partial class TAB_CONTROL : Form
{
#region pInvoke
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();
[DllImport("kernel32.dll")]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH
delegate Boolean ConsoleCtrlDelegate(CtrlTypes CtrlType);
// Enumerated type for the control messages sent to the handler routine
enum CtrlTypes : uint
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT,
CTRL_CLOSE_EVENT,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
public static void StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(Process proc)
{
//This does not require the console window to be visible.
if (AttachConsole((uint)proc.Id))
{
//Disable Ctrl-C handling for our program
SetConsoleCtrlHandler(null, true);
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
//Must wait here. If we don't and re-enable Ctrl-C handling below too fast, we might terminate ourselves.
var wasAborted = false;
var procTask = Task.Run(() =>
{
//This is necessary because when we kill the process, it obviously exits. At that point, there is no proc object to wait for any longer
if (!wasAborted)
proc.WaitForExit();
});
if (!procTask.Wait(10000))
{
wasAborted = true;
proc.Kill();
}
FreeConsole();
//Re-enable Ctrl-C handling or any subsequently started programs will inherit the disabled state.
SetConsoleCtrlHandler(null, false);
}
}
#endregion
private CancellationTokenSource cancelToken;
public TAB_CONTROL()
{
InitializeComponent();
}
//===================================================================================//
// UI HANDLING CODE //
//===================================================================================//
private void ServerControl_Load(object sender, EventArgs e)
{
//Pull all gameserver data from gameservers.json, split all json strings into a list, iterate through that list for specific data.
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly);
}
}
}
private void comboboxGameserverList_SelectedValueChanged(object sender, EventArgs e)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text)
{
//Decide what data to pull from the object at this point in time of development.
GameServer_Object Controlled_GameServer = new GameServer_Object();
Controlled_GameServer.DIR_install_location = Controlled_GameServer.DIR_install_location;
Controlled_GameServer.SERVER_executable = Controlled_GameServer.SERVER_executable;
Controlled_GameServer.SERVER_launch_arguments = Controlled_GameServer.SERVER_launch_arguments;
Controlled_GameServer.SERVER_running_status = Controlled_GameServer.SERVER_running_status;
}
}
btnStartServer.Visible = true;
chkAutoRestart.Visible = true;
lblAutoRestart.Visible = true;
chkStandaloneMode.Visible = true;
lblStandaloneMode.Visible = true;
consolePanel.Visible = true;
}
private void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
consoleOutputList.Items.Add(e.Data);
}
}
private void RefreshData()
{
comboboxGameserverList.Items.Clear();
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
comboboxGameserverList.Items.Add(gameserver.SERVER_name_friendly);
}
}
}
private void ServerControl_Activated(object sender, EventArgs e)
{
RefreshData();
}
private void chkStandaloneMode_OnValueChange(object sender, EventArgs e)
{
if (chkStandaloneMode.Value == true)
{
consolePanel.Visible = false;
}
else
{
consolePanel.Visible = true;
}
}
//===================================================================================//
// SERVER CONTROL: //
//===================================================================================//
private void LaunchServer(string SERVER_executable, string SERVER_launch_arguments, Action<string> redirectedOutputCallback = null, TextReader input = null, string argWorkingDirectory = null, EventHandler onExitedCallback = null, CancellationToken cancelToken = default(CancellationToken))
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.Arguments = SERVER_launch_arguments;
startInfo.FileName = SERVER_executable;
if (redirectedOutputCallback != null) //Redirect Output to somewhere else.
{
startInfo.UseShellExecute = false; //Redirect the programs.
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardInput = true;
startInfo.ErrorDialog = false;
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (var process = Process.Start(startInfo))
{
if (onExitedCallback != null)
{
process.EnableRaisingEvents = true;
process.Exited += onExitedCallback;
}
if (cancelToken != null)
{
cancelToken.Register(() =>
{
StopProgramByAttachingToItsConsoleAndIssuingCtrlCEvent(process);
redirectedOutputCallback?.Invoke("Shutting down the server...");
});
}
process.OutputDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args?.Data))
redirectedOutputCallback(args.Data);
};
process.BeginOutputReadLine();
process.ErrorDataReceived += (sender, args) =>
{
if (!string.IsNullOrEmpty(args?.Data))
redirectedOutputCallback(args.Data);
};
process.BeginErrorReadLine();
//For whenever input is needed
string line;
while (input != null && (line = input.ReadLine()) != null)
process.StandardInput.WriteLine(line);
process.WaitForExit();
}
}
catch
{
StringBuilder errorDialog = new StringBuilder();
errorDialog.Append("There was an error launching the following server:\n")
.Append(startInfo.FileName)
.Append("\n\n")
.Append("[Retry]: Attempt to start the same server again.\n")
.Append("[Cancel]: Cancel attempting to start server.");
}
}
else //No not redirect output somewhere else
{
startInfo.UseShellExecute = true; //Execute the programs.
try
{
// Start the process with the info we specified.
// Call WaitForExit and then the using statement will close.
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
StringBuilder errorDialog = new StringBuilder();
errorDialog.Append("There was an error launching the following server:\n")
.Append(startInfo.FileName)
.Append("\n\n")
.Append("[Retry]: Attempt to start the same server again.\n")
.Append("[Cancel]: Cancel attempting to start server.");
}
}
}
private void btnStartServer_Click(object sender, EventArgs e)
{
if (GameServer_Management.server_collection != null)
{
foreach (GameServer_Object gameserver in GameServer_Management.server_collection)
{
if (gameserver.SERVER_name_friendly == comboboxGameserverList.Text)
{
//SOURCE ENGINE HANDLER
if (gameserver.ENGINE_type == "SOURCE")
{
//Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis.
if (chkStandaloneMode.Value == true) //To be hopefully depreciated soon. Only needed right now as a fallback option to server operators.
{
LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0} +port {1} +map {2} +maxplayers {3}",
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_map,
gameserver.GAME_maxplayers));
}
else
{
LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0} +port {1} +map {2} +maxplayers {3}",
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_map,
gameserver.GAME_maxplayers));
}
}
//SOURCE ENGINE HANDLER
if (gameserver.ENGINE_type == "UNREAL")
{
//Check to see if the gameserver needs to be run with a visible console, or directly controlled by Borealis.
if (chkStandaloneMode.Value == true)
{
/*LaunchServer(gameserver.DIR_install_location + #"\steamapps\common" + gameserver.DIR_root + gameserver.SERVER_executable,
string.Format("{0}?{1}?Port={2}?MaxPlayers={3}",
gameserver.GAME_map,
gameserver.SERVER_launch_arguments,
gameserver.SERVER_port,
gameserver.GAME_maxplayers));
*/
}
else
{
MetroMessageBox.Show(BorealisServerManager.ActiveForm, "Unfortunately Borealis cannot directly control console output at this time; instead, please launch the server in 'standalone mode'.", "Unable to launch server within Borealis.", MessageBoxButtons.OK, MessageBoxIcon.Error);
/*
chkAutoRestart.Visible = false;
lblAutoRestart.Visible = false;
chkStandaloneMode.Visible = false;
lblStandaloneMode.Visible = false;
btnStartServer.Enabled = false;
btnStopServer.Visible = true;
consolePanel.Visible = true;
txtboxIssueCommand.Visible = true;
txtboxIssueCommand.Text = " > Enter a Command";
txtboxIssueCommand.Enabled = true;
Execute(Environment.CurrentDirectory + gameserver.SERVER_executable, gameserver.SERVER_launch_arguments, true);
*/
}
}
}
}
}
}
private void btnStopServer_Click(object sender, EventArgs e)
{
btnStopServer.Visible = false;
btnStartServer.Enabled = true;
chkAutoRestart.Visible = true;
lblAutoRestart.Visible = true;
txtboxIssueCommand.Visible = false;
consoleOutputList.Items.Clear();
txtboxIssueCommand.Text = " > Server is Not Running";
txtboxIssueCommand.Enabled = false;
cancelToken.Cancel();
backgroundWorker01.RunWorkerCompleted += (sender2, e2) =>
{
btnStopServer.Enabled = false;
btnStartServer.Enabled = true;
txtboxIssueCommand.Enabled = false;
txtboxIssueCommand.Text = "> Server is not running";
consoleOutputList.Items.Add("Server stopped...");
};
}
private void txtboxIssueCommand_Enter(object sender, EventArgs e)
{
txtboxIssueCommand.Text = "";
}
private void txtboxIssueCommand_MouseClick(object sender, MouseEventArgs e)
{
txtboxIssueCommand.Text = "";
}
private void backgroundWorker01_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
bool stopped = false;
//It's an assumption that these 3 elements MUST exist
var asyncCallback = comboboxGameserverList.BeginInvoke((Func<string[]>)delegate ()
{
return new string[] {
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "installation_folder" ),
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "default_launchscript" ),
//GameServerXMLData( comboboxGameserverList.SelectedItem as string, "binaries" )
};
});
asyncCallback.AsyncWaitHandle.WaitOne();
var serverParams = comboboxGameserverList.EndInvoke(asyncCallback) as string[];
Action<string> textAddCallback = (args) =>
{
consoleOutputList.BeginInvoke((Action)delegate ()
{
consoleOutputList.Items.Add(args);
});
};
EventHandler exitedHandler = (sender2, e2) =>
{
if (!cancelToken.IsCancellationRequested)
{
//Wait a little until we restart the server
consoleOutputList.BeginInvoke((Action)delegate ()
{
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add("An error occured and the process has crashed. Auto-restarting in 5 seconds...");
//Scroll to the bottom
consoleOutputList.TopIndex = consoleOutputList.Items.Count - 1;
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
consoleOutputList.Items.Add(Environment.NewLine);
});
Thread.Sleep(5000);
}
else
stopped = true;
};
while (chkAutoRestart.Value && !stopped)
LaunchServer(serverParams[0] + serverParams[2], serverParams[1], textAddCallback, null, serverParams[0], chkAutoRestart.Value ? exitedHandler : null, chkAutoRestart.Value ? cancelToken.Token : default(System.Threading.CancellationToken));
}
}
}

Show a Verify/Wrong Picture if i have internet on computer

I want to make a program that checks if the computer is connected to the internet when i start the application.
This is my Form
And this is my Code:
private bool checkinternet()
{
WebRequest request = WebRequest.Create("http://www.google.com");
WebResponse response;
try
{
response = request.GetResponse();
response.Close();
request = null;
return true;
}
catch(Exception)
{
request = null;
return false;
}
}
private void pictureBox1_Click_1(object sender, EvenArgs e)
{
bool checkinternet = false;
{
}
}
The code to check the internet connection works. I tried using buttons, but i want to display an image in imagebox1 if the computer has internet, or display another image if it is not connected.
You need to do the operation in your form load event:
private void Form1_Load(object sender, System.EventArgs e)
{
if (CheckInternet()) // change to upper case (convention for methods)
{
imagebox1.Image = Image.FromFile("p://ath/to/online/image.jpg");
}
else
{
imagebox1.Image = Image.FromFile("p://ath/to/offline/image.jpg");
}
}
The above code is calling your CheckInternet method that returns a bool value whenever there is an internet connection or not.
According to the returned value, you need to set the correct image.
You need to provide the full image path name as parameter to the Image.FromFile method.
First of all you should use a using-directive to automatically dispose your WebRequest:
private bool checkinternet()
{
using(WebRequest request = WebRequest.Create("http://www.google.com"))
{
WebResponse response;
try
{
response = request.GetResponse();
response.Close();
return true;
}
catch(Exception)
{
return false;
}
}
}
Also you need to call your method using braces in an if-statement where you need ==to check for a value:
private void pictureBox1_Click_1(object sender, EvenArgs e)
{
if(checkinternet() == false)
{
//no internet
}
if(checkinternet())
{
//internet
}
if(!checkinternet())
{
//no internet
}
}
Finally, as stated in the answer from ehh you can use the Load event to execute the code when the Form opens:
private void Form1_Load(object sender, System.EventArgs e)
{
if (checkinternet())
{
imagebox1.Image = Image.FromFile("p://ath/to/online/image.jpg");
}
else
{
imagebox1.Image = Image.FromFile("p://ath/to/offline/image.jpg");
}
}

return when winform's webbrowser browse set of url addresses

I need to browse a set of url adresses (yes another web scraper..).
I want to use tasks. But I have problem returning AFTER the browser is finished.
To be sure the site is fully loaded I have to jump to document_completed and from there I call the Navigate method with another url.
Something like this:
private WebBrowser browser;
private List<string> urlsToVisit;
int urlCounter = 0;
public PageBrowser(List<string> urls) //constructor
{
urlCounter = 0;
urlsToVisit = urls;
browser = new WebBrowser(); //one instance of browser for all urls
browser.ScriptErrorsSuppressed = true;
browser.DocumentCompleted += browser_DocumentCompleted;
}
//this I want to call from somewhere else and return true AFTER it opens all sites
public bool Run()
{
VisitPages();
return true;
}
private void VisitPages()
{
if (urlCounter < urlsToVisit.Count)
{
browser.Navigate(urlsToVisit[urlCounter]);
urlCounter++;
}
else
{
browser.Dispose();
}
}
private void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath) return;
System.Threading.Thread.Sleep(3000); //random interval between requests
VisitPages();
}
I am pretty sure, the solution is very simple but I just don't see it..
Thank you
Petr
I would suggest you to use a WebClient instead of a WebBrowser UI component since you don't seem to need to render anything. It seems as you just want to send requests to your list of urls and return true if everything went well, and return false if any type of problem occured.
private async Task<bool> VisitUrls()
{
var urls = new List<string>
{
"http://stackoverflow.com",
"http://serverfault.com/",
"http://superuser.com/"
};
var success = await BrowseUrls(urls);
return success;
}
private async Task<bool> BrowseUrls(IEnumerable<string> urls)
{
var timeoutWebClient = new WebClient();
foreach (var url in urls)
{
try
{
var data = await timeoutWebClient.DownloadDataTaskAsync(url);
if (data.Length == 0) return false;
}
catch (Exception ex)
{
return false;
}
}
//Everything went well, returning true
return true;
}

Categories

Resources