I'm still a beginner when it comes to programming and this is a small application I did following a C# tutorial.
private void viewImagesToolStripMenuItem_Click(object sender, EventArgs e)
{
string openedfile = "";
openfd.Title = "Insert a text file";
openfd.InitialDirectory = "C:";
openfd.FileName = "";
openfd.Filter = "text files|*.txt|word documents|*.doc|allfiles|*.*";
if (openfd.ShowDialog() == DialogResult.Cancel)
{
MessageBox.Show("Operation canceled");
}
if (openfd.ShowDialog() != DialogResult.Cancel)
{
openedfile = openfd.FileName;
richTextBox1.LoadFile(openedfile,RichTextBoxStreamType.PlainText);
}
While doing this I noticed that if I change the same application's code order just 2 lines-
string openedfile = "";
openedfile = openfd.FileName;
like below It will throw me an error like this when debugging - Empty path name is not legal.
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
openfd.Title = "Insert a text file";
openfd.InitialDirectory = "C:";
openfd.FileName = "";
openfd.Filter = "text files|*.txt|word documents|*.doc|allfiles|*.*";
**string openedfile = "";
openedfile = openfd.FileName;**
if (openfd.ShowDialog() == DialogResult.Cancel)
{
MessageBox.Show("Operation canceled");
}
if (openfd.ShowDialog() != DialogResult.Cancel)
{
richTextBox1.LoadFile(openedfile,RichTextBoxStreamType.PlainText);
}
Isn't there a way to understand errors in these type situations. What is the specific order of coding an application like this?
well, the idea is simple you cannot use a variable that has been not initialized.
in your case sm thing same is happening.
In your first code openedfile = openfd.FileName; is being executed after the dialouge has been shown. Thus the file name comes correctly.
But in the second openedfile = openfd.FileName; is getting initialized before the dilogue has been shown. Since there is no dialogue the name is null, hence it gives error.
Note. I have used initialized word not in tecnical manner.
The line openedfile = openfd.FileName; will not bind the two variables, it will copy the value that openfd.FileName has at this moment into openedfile.
In your second example the user has not yet selected a file at that moment, so this value is still empty (""). The value that is selected later in openfd will be ignored.
EDIT which is why you get the error Empty path name is not legal.
I'm going to go ahead and guess that the problem is the openfd.FileName call outside of the if block (and also before its retrieved), while the if block is still being exectuted the openfd is "left open" if you like, so you can retrieve its result.
When you have left, the if block, you are effectively saying you are done with this dialog, please continue.
In your code you are showing multiple dialogs with multiple calls to show dialog also, consider the following.
if (openfd.ShowDialog() == DialogResult.OK)
{
pictureBox1.Image = Image.FromFile(openfd.FileName);
}
else
{
MessageBox.Show("Operation canceled");
}
(Changed to use dialogresult.ok as this is more than likely the result you wish to receive from the dialog)
Update
With respect to your current applcation, each call to ShowDialog() is opening a new dialog. Consider it similar to
MessageBox.Show("woo");
MessageBox.Show("hoo");
in the above, when the first messagebox is closed, it will close the dialog and move onto handling the second message box (the next line of code), with your
if (openfd.ShowDialog() != DialogResult.Cancel)
Your showdialog is still in use by the if statement so it is deemed to be still in use and not disposed of straight away. When the if statement is finished with, your dialog will then be deemed to be ok to dispose
Also, the error in your application is not to do with the filename path, its trying to load in a file that has no name
I generally Prefer this:
private void viewImagesToolStripMenuItem_Click(object sender, EventArgs e)
{
DialogResult dr=openfd.ShowDialog();
if(dr==DialogResult.Ok)
{
richTextBox1.LoadFile(openfd.FileName,RichTextBoxStreamType.PlainText);
}
else
{
MessageBox.Show("No file Selected!!");
}
}
Related
This may be a bit of a newbie question. I am loading a executable from a server and then want to execute this program. After execution is finished, I want to delete this file.
Here is part of my code:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (check == true)
{
if (webBrowser1.DocumentText.Contains("0"))
{
check = false;
// timer1.Stop();
button1.Enabled = true;
MessageBox.Show("Wrong HWID ");
this.Close();
}
else if (webBrowser1.DocumentText.Contains("1"))
{
check = false;
// timer1.Stop();
button1.Enabled = true;
WebClient wc = new WebClient();
Properties.Settings.Default.Serial = textBox1.Text;
Properties.Settings.Default.Installed = true;
Properties.Settings.Default.Save();
MessageBox.Show("All info correct!");
var result = MessageBox.Show("Do you want to start ?", "Application Exit", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
wc.DownloadFileAsync(uri, filename);
}
if (File.Exists(filename))
{
Process.Start(filename);
}
}
else if (webBrowser1.DocumentText.Contains("2"))
{
check = false;
// timer1.Stop();
button1.Enabled = true;
MessageBox.Show("HWID field left empty");
}
else if (webBrowser1.DocumentText.Contains("3"))
{
check = false;
// timer1.Stop();
button1.Enabled = true;
MessageBox.Show("Wrong serial");
}
else if (webBrowser1.DocumentText.Contains("Object not found"))
Other related code:
Uri uri = new Uri("http://link.com/blabla/blabla.exe");
string filename = #"C:\Users\User\blabla.exe";
If you are fine with locking your current process this can be done synchronously. This is not the recommended way to do it but may work in your case depending on your environment.
Change this:
wc.DownloadFileAsync(uri, filename);
To this:
wc.DownloadFile(uri, filename);
After this you can add:
if (File.Exists(filename)) {
Process process = Process.Start(filename);
process.WaitForExit();
File.Delete(filename);
}
Which will check to see if the file exists, starts it, waits for it to finish, and then deletes it. As always when working with FileIO, you should work to handle exceptions.
This is the better apporach
If it needs to be async then another way to do this may be to trigger an event when the download is complete. You would want to add an event handler like the following to your WebClient:
client.DownloadFileCompleted += new AsyncCompletedEventHandler (DownloadFileCallback);
And then add a handler method similar to the following:
private void DownloadFileCallback(object sender, AsyncCompletedEventArgs e) {
if (File.Exists(filename)) {
Process process = Process.Start(filename);
process.WaitForExit();
}
}
Note that in this handler method, filename is instance data to your class so you know where you saved the file. This should get you started in the right direction.
EDIT:
As mentioned in my answer, using wc.DownloadFile() is synchronous, meaning it will lock your current process. (i.e. you will see this when debugging when you step over this line it will not do anything else until it has finished). This can cause problems when the download (or more generally any synchronous process) takes a long, it has the potential to lock up your UI (if this is UI code). The best practice is to do this asynchronously which is what the original code you posted does. In the code you posted you were using wc.DownloadFileAsync(). To keep using this method, add an event handler like shown above and this handler method will be called once the download has completed. This makes the download run in the background so your thread is free to run other things while this is working. (i.e. this can leave your UI responsive on long downloads) Inside your event handler, your download is finished so you can continue on from there.
EDIT 2:
Since you will only be executing the program and then deleting it, it may be worth just saving it to the temp directory (navigate to %temp%). Something that may work to generate your filename would be the following:
string filename = Path.Combine(Path.GetTempPath(), "MyFile.exe");
This should result in something like the following path C:\Users\Username\AppData\Local\Temp\MyFile.exe
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have bound the openFileDialog control with button. On button event, I am calling the openFileDialog control.
Now, when I am running my application, the openFileDialog box gets open but does not select the file. The open button is not working.
Example code:
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void openFileDialog1_FileOk_1(object sender, CancelEventArgs e)
{
// logic written here
}
It was working fine earlier but now its not working.
You need to use the DialogResult to get the event of open confirmation by the user. Then you can use a stream to read the file. Here is some sample code (provided by MS in the MSDN - source:https://msdn.microsoft.com/en-us/library/system.windows.forms.openfiledialog(v=vs.110).aspx):
private void button1_Click(object sender, System.EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.InitialDirectory = "c:\\" ;
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
openFileDialog1.FilterIndex = 2 ;
openFileDialog1.RestoreDirectory = true ;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Some logic here
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Failed to open file. Original error: " + ex.Message);
}
}
}
Answer post edits
The included code shows the method openFileDialog1_FileOk_1 the "_1" at the end suggest to me that you had some issues binding the event. Perhaps there was at some point a method openFileDialog1_FileOk caused conflict.
You should check if the method is correctly bound to the event.
For that I will remit you to my answer to How to change the name of an existing event handler?
For abstract you want to see what method is bound to the event. You can do it from the properties panel, or by checking the form designer file (that is named something .Designer.cs for example: Form1.Designer.cs).
Addendum: Consider adding a break point in the event handler. It will allow you to debug step by step what is happening. Also, it will allow you notice if the event handlers is not being executed at all, which would suggest that the method is NOT correctly bound to the event.
Original Answer
OpenFileDialog Does not open files, it barely select thems and makes the selection available for your application to do whatever your applications is intended to do with those files.
The following is the usage pattern from the MSDN article linked above:
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Insert code to read the stream here.
}
}
}
catch (Exception ex)
{
MessageBox.Show
(
"Error: Could not read file from disk. Original error: " + ex.Message
);
}
}
Now, observe that after cheking the result of ShowDialog - which returns once the dialogs is closed - the codes uses the method OpenFile to actually open the file. The result is a stream that you can process anyway you prefer.
Alternatively you can retrieve the selected files via the property FileNames, which returns an array of strings. If you have configured the dialog to only allow selecting asingle file you are ok to use FileName instead.
Addendum, if by "Open" you mean to invoke the default application associated with the selected file to open the file. You can accomplish that by passing the file path to System.Diagnostics.Process.Start.
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string name = openFileDialog1.FileName;
object objOpt = Type.Missing;
var excelApp = new Excel.Application();
Excel.Workbook wbclass = excelApp.Workbooks.Open(name, objOpt,
true,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt,
objOpt);
}
I have in my Form1 button click event this line:
Process.Start(Path.GetFullPath(zippedFileDirectory));
Its just openning the location of this directory.
Then I have another line:
Process.Start(Path.GetFullPath(temp));
If I clicked the first button and then the second button I will have two windows opened each of a process.
Now im closing my program so in the Form1 closing event I want to kill this two processes.
In the else part what do I do ?
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you Sure you want to Exit. Click Yes to Confirm and No to continue", "WinForm",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
e.Cancel = true;
}
else
{
}
}
Edit:
I did now in my Form1 top added:
private Process zipFileDirectoryProcess;
Then in the bottom inside the method I did:
private void Compress()
{
string zipFileName = "Diagnosis_Files.zip";
string source = contentDirectory;
string output = zippedFileDirectory;
string programFilesX86 = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
+ "\\Diagnostic Tool\\7z.dll";
if (File.Exists(programFilesX86))
{
SevenZipExtractor.SetLibraryPath(programFilesX86);
}
string programFiles = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFiles)
+ "\\Diagnostic Tool\\7z.dll";
if (File.Exists(programFiles))
{
SevenZipExtractor.SetLibraryPath(programFiles);
}
SevenZipCompressor compressor = new SevenZipCompressor();
compressor.ArchiveFormat = OutArchiveFormat.Zip;
compressor.CompressionMode = CompressionMode.Create;
compressor.TempFolderPath = System.IO.Path.GetTempPath();
string t = Path.Combine(output, zipFileName);
compressor.CompressDirectory(source, t);
zipFileDirectoryProcess.Start(Path.GetFullPath(zippedFileDirectory));
this.TopMost = true;
}
I added the line:
zipFileDirectoryProcess.Start(Path.GetFullPath(zippedFileDirectory));
But im getting an error on this line:
Error 1 Member 'System.Diagnostics.Process.Start(string)' cannot be accessed with an instance reference; qualify it with a type name instead
And before I added this line I had this line:
Process.Start(Path.GetFullPath(zippedFileDirectory));
And it worked good so why now I have this error ?
Process p1 = Process.Start(Path.GetFullPath(zippedFileDirectory));
Process p2 = Process.Start(Path.GetFullPath(temp));
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you Sure you want to Exit. Click Yes to Confirm and No to continue", "WinForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
e.Cancel = true;
}
else
{
p1.Kill();
p2.Kill();
}
}
UPDATE
For your added question, you can't call the Start() method on an instance of Process because:
There is no overriding method (instance method) of Start() taking 1 argument of string. There is only 1 method without any argument Start().
The IDE says you should call the Start() on a type name that means you should call Process.Start(string ....) whereas Process is a type name. This Start(string...) is a static method which can only be called on a type name.
Process.Start returns a process object. You can store this somewhere, and then call Kill() on it if they select yes. So, something like:
Process _proc;
_proc = Process.Start("path);
_proc.Kill();
I have a Label and PictureBox element that in designer i set visibility as false.
now i try this :
private void openExcelButton_Click(object sender, EventArgs e)
{
openExcelDialog.Filter = "Excel files|*.xls;*.xlsx;*.csv";
DialogResult result = openExcelDialog.ShowDialog();
if (result == DialogResult.OK) // Test result.
{
LoadingGIF.Visible = true;
LoadingLabel.Text = "Loading...";
LoadingLabel.Visible = true;
string file = openExcelDialog.FileName;
//more code
LoadingGIF.Visible = false;
LoadingLabel.Text = "Uploading Finished!";
}
}
Now when pressing the button and choosing a file nothing happens untill i finish the code in the //more code section and then the label changes.
Why does this happen?
The reason this happens is because your main thread is becoming non-responsive and not allowing the changes to happen in a sequential order. I had a very similar issue on a project a year ago. The suggested solution by MS is to use a background worker to open the file and manipulate it so the primary thread does not become non-responsive. Microsoft has a fairly decent example of how to use a background worker here: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
I am trying to make SaveFileDialog and FileOpenDialog enforce an extension to the file name entered by the user. I've tried using the sample proposed in question 389070 but it does not work as intended:
var dialog = new SaveFileDialog())
dialog.AddExtension = true;
dialog.DefaultExt = "foo";
dialog.Filter = "Foo Document (*.foo)|*.foo";
if (dialog.ShowDialog() == DialogResult.OK)
{
...
}
If the user types the text test in a folder where a file test.xml happens to exist, the dialog will suggest the name test.xml (whereas I really only want to see *.foo in the list). Worse: if the user selects test.xml, then I will indeed get test.xml as the output file name.
How can I make sure that SaveFileDialog really only allows the user to select a *.foo file? Or at least, that it replaces/adds the extension when the user clicks Save?
The suggested solutions (implement the FileOk event handler) only do part of the job, as I really would like to disable the Save button if the file name has the wrong extension.
In order to stay in the dialog and update the file name displayed in the text box in the FileOk handler, to reflect the new file name with the right extension, see the following related question.
You can handle the FileOk event, and cancel it if it's not the correct extension
private saveFileDialog_FileOk(object sender, CancelEventArgs e)
{
if (!saveFileDialog.FileName.EndsWith(".foo"))
{
MessageBox.Show("Please select a filename with the '.foo' extension");
e.Cancel = true;
}
}
AFAIK there's no reliable way to enforce a given file extension. It is a good practice anyway to verify the correct extension, once the dialog is closed and inform the user that he selected an invalid file if the extension doesn't match.
The nearest I've got to this is by using the FileOk event. For example:
dialog.FileOk += openFileDialog1_FileOk;
private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
if(!dialog.FileName.EndsWith(".foo"))
{
e.Cancel = true;
}
}
Checkout FileOK Event on MSDN.
I ran into this same issue, and I was able to control what was shown by doing the following:
with the OpenFileDialog, the first item in the filter string was the default
openFileDialog1.Filter = "Program x Files (*.pxf)|*.pxf|txt files (*.txt)|*.txt";
openFileDialog1.ShowDialog();
with the SaveFileDialog, the second item in the filter was used as the default:
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.Filter = "txt files (*.txt)|*.txt|Program x Files (*.pxf)|*.pxf";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if (saveFileDialog1.FileName != null)
{
// User has typed in a filename and did not click cancel
saveFile = saveFileDialog1.FileName;
MessageBox.Show(saveFile);
saveCurrentState();
}
}
After having used these two filters with the respective fileDialogs, The expected results finally occurred. By default, when the user selects the save button and the savefiledialog shows up, the selected filetype is that of the Program X files type defined in the filter for the savefiledialog. Likewise the selected filetype for the openfiledialog is that of the Program X Files Type defined in the filter for the openfileDialog.
It would also be good to do some input validation as mentioned above in this thread. I just wanted to point out that the filters seem to be different between the two dialogs even though they both inherit the filedialog class.
//this must be ran as administrator due to the change of a registry key, but it does work...
private void doWork()
{
const string lm = "HKEY_LOCAL_MACHINE";
const string subkey = "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoComplete";
const string keyName = lm + subkey;
int result = (int)Microsoft.Win32.Registry.GetValue(keyName, "AutoComplete In File Dialog", -1);
MessageBox.Show(result.ToString());
if(result.ToString() == "-1")
{
//-1 means the key does not exist which means we must create one...
Microsoft.Win32.Registry.SetValue(keyName, "AutoComplete In File Dialog", 0);
OpenFileDialog ofd1 = new OpenFileDialog();
ofd1.ShowDialog();
}
if (result == 0)
{
//The Registry value is already Created and set to '0' and we dont need to do anything
}
}