private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog Sdialog = new SaveFileDialog();
Sdialog.ShowDialog();
Sdialog.FileOk += Sdialog_FileOk;
}
void Sdialog_FileOk(object sender, CancelEventArgs e)
{
try
{
StreamWriter FileProtocol = new StreamWriter(((SaveFileDialog)sender).FileName);
FileProtocol.Write(textBox3.Text);
FileProtocol.Close();
MessageBox.Show("File is write ok");
}
catch (Exception)
{
MessageBox.Show("Unknown Error. File is not write");
}
}
Why does event FileOk not work?
Because you need to hook the event up before calling ShowDialog(). When you call ShowDialog() it stops processing on that thread and waits for a response.
So, instead of this:
Sdialog.ShowDialog();
Sdialog.FileOk += Sdialog_FileOk;
do this:
Sdialog.FileOk += Sdialog_FileOk;
Sdialog.ShowDialog();
To use the DialogResult to simplify you're workflow, just do this:
if (Sdialog.ShowDialog() == DialogResult.OK)
{
try
{
StreamWriter FileProtocol =
new StreamWriter(Sdialog.FileName);
FileProtocol.Write(textBox3.Text);
FileProtocol.Close();
MessageBox.Show("File is write ok");
}
catch (Exception)
{
MessageBox.Show("Unknown Error. File is not write");
}
}
ALSO: instead of doing this:
StreamWriter FileProtocol =
new StreamWriter(Sdialog.FileName);
FileProtocol.Write(textBox3.Text);
FileProtocol.Close();
how about simplify it to this:
File.AppendAllText(Sdialog.FileName, textBox3.Text);
The benefit is two fold:
The code is clearly much more concise, and;
The code is safer because it manages the un-managed resources appropriately for you.
Related
How to keep the savefilediallog open when you write to a file which is in use by an other program so that you can change the file name and try to save again?
private void button1_Click_2(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
CsvExport = Class_ExportData.DataTableToCSV(datatabelControle, csvSCheidingteken);
Cursor.Current = Cursors.Default;
saveFileDialog1.OverwritePrompt = true;
saveFileDialog1.Filter = "Komma gescheiden waarden (*.csv)|*.csv|Tekst bestanden (*.txt)|*.txt|Alle formaten (*.*)|*.*";
saveFileDialog1.DefaultExt = "csv";
saveFileDialog1.AddExtension = true;
saveFileDialog1.ShowDialog();
}
private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
{
try
{
string name = saveFileDialog1.FileName; // Get file name.
File.WriteAllText(name, CsvExport); // Write to the file name selected.
}
catch (Exception ex)
{
//file is locked, how to get back to the open save file dialog ???
}
}
Try this. Move the code associated with opening the saveFileDialog1 into its own function and invoke that function from button1_Click:
private void button1_Click_2(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
CsvExport = Class_ExportData.DataTableToCSV(datatabelControle, csvSCheidingteken);
Cursor.Current = Cursors.Default;
ShowSaveFileDialog();
}
private void ShowSaveFileDialog()
{
saveFileDialog1.OverwritePrompt = true;
saveFileDialog1.Filter = "Komma gescheiden waarden (*.csv)|*.csv|Tekst bestanden (*.txt)|*.txt|Alle formaten (*.*)|*.*";
saveFileDialog1.DefaultExt = "csv";
saveFileDialog1.AddExtension = true;
saveFileDialog1.ShowDialog();
}
EDIT: On further consideration, I don't think you want/need the loop here, so I've removed it. You still want to invoke the ShowSaveFileDialog method here in case of exceptions, though:
private void saveFileDialog1_FileOk(object sender, CancelEventArgs e)
{
try
{
string name = saveFileDialog1.FileName; // Get file name.
File.WriteAllText(name, CsvExport); // Write to the file name selected.
return;
}
catch (Exception ex)
{
//file is locked, how to get back to the open save file dialog ???
// maybe display an error message here so that the user knows why they're about to see the dialog again.
}
ShowSaveFileDialog();
}
Technically, this can probably lead to a StackOverflowException if the user tries repeatedly (and I mean thousands of times) to retry the save after an exception, but that's pretty unlikely.
Before you flag this as a duplicate, yes there are questions just like this, i've looked at all of them and still couldn't get this working. I'm trying to code in a feature that downloads and runs a .exe file but it doesn't download, run or do anything. I even removed the try catches to find an error or error codes but I have non, so I have no idea where i'm going wrong, here is my code for it
public test_Configuration()
{
InitializeComponent();
}
Uri uri = new Uri("http://example.com/files/example.exe");
string filename = #"C:\Users\**\AppData\Local\Temp\example.exe";
private void button1_Click(object sender, EventArgs e)
{
try
{
if(File.Exists(filename))
{
File.Delete(filename);
}
else
{
WebClient wc = new WebClient();
wc.DownloadDataAsync(uri, filename);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
if (progressBar1.Value == progressBar1.Maximum)
{
progressBar1.Value = 0;
}
}
private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if(e.Error == null)
{
MessageBox.Show("Download complete!, running exe", "Completed!");
Process.Start(filename);
}
else
{
MessageBox.Show("Unable to download exe, please check your connection", "Download failed!");
}
Change DownloadDataAsync to DownloadFileAsync.
wc.DownloadFileAsync(uri, filename);
This code helped me out quite a bit with updating a file, so I thought I would show my twist in the hopes that someone else out there has a similar requirement as me.
I needed this code to do the following when a button was clicked:
Grab a file from a sever and store it locally in AppData\Temp.
Keep my user up-to-date of install progress (an installer is downloaded).
If successfully downloaded (note the removal of the else after deleting old file check), launch "daInstaller.exe", whilst terminating the current running program.
And if said file already exist (i.e. the old "daIstaller.exe"), delete prior to copying new file to AppData\Temp.
Don't forget to keep the file names the same, else you'll be leaving more trash in that AppData\Temp folder.
private void button1_Click(object sender, EventArgs e)
{
Uri uri = new Uri("http://example.com/files/example.exe");
filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp/example.exe");
try
{
if (File.Exists(filename))
{
File.Delete(filename);
}
WebClient wc = new WebClient();
wc.DownloadFileAsync(uri, filename);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
if (progressBar1.Value == progressBar1.Maximum)
{
progressBar1.Value = 0;
}
}
private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
Process.Start(filename);
Close();
Application.Exit();
}
else
{
MessageBox.Show("Unable to download exe, please check your connection", "Download failed!");
}
}
I have the following:
wc.DownloadDataCompleted += Wc_DownloadDataCompleted;
FileStream f = File.OpenWrite(insLoc + "\\update.zip");
wc.DownloadDataAsync(new Uri("http://example.com/file.zip"), installLoc + "\\file.zip");
(and in a separate function)
private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error == null) {
MessageBox.Show("Download success");
}
else { MessageBox.Show("Download failed"); }
f.Flush();
f.Dispose();
}
When I check the file it is supposed to be downloading to, it exists, but there is nothing in it (ie, it is 0 bytes). I have flushed the FileStream after the download has finished, so what is happening? I have a progress bar as well, and it slowly increases to 100% so I know it's downloading the ZIP file, and the "Download Success" messagebox is shown.
Thanks in advance!
You should use the callback function to save the resulting file (represented as a byte array passed as second argument):
wc.DownloadDataCompleted += Wc_DownloadDataCompleted;
wc.DownloadDataAsync(new Uri("http://example.com/file.zip"));
and then:
private void Wc_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error == null)
{
string resultFile = Path.Combine(insLoc, "update.zip");
System.IO.File.WriteAllBytes(resultFile, e.Result);
MessageBox.Show("Download success");
}
else
{
MessageBox.Show("Download failed");
}
}
Now you can quickly see that using this method the entire file is loaded in memory as a byte array before flushing it to the file system. This is hugely inefficient especially if you are downloading large files. For this reason it is recommended to use the DownloadFileAsync method instead.
wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
string resultFile = Path.Combine(insLoc, "update.zip");
var uri = new Uri("http://example.com/file.zip");
wc.DownloadFileAsync(uri, resultFile);
and the corresponding callback:
private void Wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
if (e.Error == null)
{
MessageBox.Show("Download success");
}
else
{
MessageBox.Show("Download failed");
}
}
I would use DownloadFileTaskAsync method of WebClient which I find very simple to use..
await wc.DownloadFileTaskAsync(new Uri("http://example.com/file.zip"), installLoc + "\\file.zip");
That is all. If you want to see the download progress, you can attach to DownloadProgressChanged event.
I create an empty file and try to copy the contents from an existing to the newly created file. When i do that i am getting an IOexception
private void button1_Click(object sender, EventArgs e)
{
String test = textBox1.Text.ToString();
if (string.IsNullOrEmpty(textBox1.Text))
{
MessageBox.Show("Enter the filename");
}
else
{
StreamWriter File = new StreamWriter(test);
MessageBox.Show(test + " Has been created");
}
}
private void button2_Click(object sender, EventArgs e)
{
String test = textBox1.Text.ToString();
try
{
File.Copy(#"D:\\Study this.txt", test);
}
catch (IOException)
{
MessageBox.Show("IO error occured");
}
}
You will need to close the Stream so in the else statement add File.Close(); that will release the newly created file. That section of the code will now look like this:
StreamWriter File = new StreamWriter(test);
File.Close();
MessageBox.Show(test + " Has been created");
replace line StreamWriter File = new StreamWriter(test); with below
using (File.Create(test)) ;
or with
using (StreamWriter writer = new StreamWriter(test)){}
reason for above change is you need to propery close the opend stream object before the copy.
using block will handle that for you.
I am having trouble calling the string "rlist" from:
public void main()
{
string rlist;
if (radioButton1.Checked)
textBox1.Enabled = false;
textBox1.ReadOnly = true;
rlist = "text";
}
to
public void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFile = new OpenFileDialog();
openFile.Filter = "WTF Files (*.wtf)|*.wtf";
openFile.Title = "Please Pick your realmlist file:";
if (openFile.ShowDialog() == DialogResult.Cancel)
return;
try
{
textBox5.Text = openFile.FileName;
string file = openFile.FileName;
TextWriter rlist_writer = new StreamWriter (openFile.FileName);
rlist_writer.WriteLine(rlist);
rlist_writer.Close();
}
catch (Exception)
{
MessageBox.Show("Error opening file", "File Error",
MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
I get the error on this line:
rlist_writer.WriteLine(rlist);
is it possible to call a string from one function and send it to the other with the same value it had in the function it was originally pulled from?
By the sounds of your question,
Your string is local to your main function.
So judging by your method names and knowledge of winforms(presumed again)
you need to make your string class level
string rlist;
public void main()
{
rlist = "yay"
public void button1_Click(object sender, EventArgs e)
{
someText = rlist;
As it currently stands you are not able to, as temporary (local) variables will be cleaned through garbage collection when you leave the method
Edit
You may wish to review this also
try
{
textBox5.Text = openFile.FileName;
using(TextWriter rlist_writer = new StreamWriter (openFile.FileName))
{
rlist_writer.WriteLine(rlist);
}
}
You can define that variable in your class scope, then if you call that variable in your button_click event, it will maintain the same value as in your main method.