Stoping the generation of duplicate of the output file - c#

I have an application where I generate Report at the end of all the materials, by Hitting generate Report button. The report is generated in Excel format. The problem is that whenever I create one report, I can create another report with the same name on the same location. It basically overrides the first report.
I want to give the user a box saying that you can generate a report with the same name or the name already exists and choose a different name.
Thanks for the help!

Just before you save the file you should know what the Filename you are going to save it as. If so then just test if the File already exists. If it does then prompt the user for a new name and save it as the new name e.g.
string filename = #"C:\File.txt";
if(File.Exists(filename)){
// Prompt for new one.
// save the report to the new name instead.
}else
{
// save to filename
}

How about before saving a file, check if the file with this name already exists and if it does, offer to rename the file. Something like this:
if(File.Exists(proposedFileName)){
showDialog("file exists, please choose other name");
}

I always do what DarkXphenomenon suggested, I append a mildate timestamp to the filename of the form:
<filename>_YYMMDD_HHMMSS.ext
While this is't rught for every situation, it has a lot of advantages:
Its simple, and it works
It saves me from having to write in all kinds of gyrations for going back and forth with the user over the name, overwriting, renaming, canceling, etc. Usually deep in code that was never intended to have a user interface.
It makes automation much easier.
It makes testing easier.
It makes diagnosing user problems easier: there's no question over when a file was created or in what order they were created.

Before creating the report you can iterate through the existing files and check whether the name already exists and give proper error message.
string newFileName = "new file";
string[] fileNames = Directory.GetFiles("path");
foreach (string file in fileNames)
{
if (file == newFileName)
{
MessageBox.Show("Error");
break;
}
}

Related

C# OpenFileDialog multiple filename filters including exclude

I have a requirement to allow users to open a specific file for processing. The open file dialog is currently
OpenFileDialog ofg = new OpenFileDialog
{
FileName = "BaseFileName*",
Filter = "CSV File (*.CSV)|*.csv",
Multiselect = false,
InitialDirectory = #"N:\Downloads"
};
However the process adds a suffix of _Processed along with timestamp data to the filename and I want to exclude these renamed files the next time the OpenFileDialog is used to prevent the user trying to reprocess the same file.
I have to leave the original files where they are for internal audit reasons.
So I need an additional filename filter of not equal to "_Processed".
Is there any way to do this with OpenFileDialog or does anyone know of a custom c#/.net component that can do this?
You are asking to omit specific items from the file dialog view.
According to MSDN, this is no longer possible as of Windows 7, but was possible previously.
The C# file dialogs (both WPF and WinForms) use the IFileDialog API.
Here is the function that could have made this work, but is no longer supported:
https://learn.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ifiledialog-setfilter
As it is, you are stuck with checking the file for correctness after the user has already selected it and confirmed it with OK.
You can help the situation a little bit: If you enjoy pain, then you can copy the whole IFileDialog COM interop code from the .NET source code, and implement IFileDialogEvents. This way, when the user clicks "OK", you can deny the selection and display an error before the dialog closes, leaving the dialog open so the user can select a different file.
If you are sane and you don't want to do that, then you'll have to open the dialog again after the verification fails.
The easy way is just saving the processed data with another extension e.g. "BaseFileName_Processed_20105640640.cvs1", that way you keep the data and your file dialog will not show this file.
Another way could be to call the OpenFileDialog() in an if statement (and compare the return to DialogResult.OK), then split the file name for {'_','.'}, then run a loop to count the occurrences of the word Processed( >0), and possibly as a safety check determine whether a timestamp is present in one of the split strings. Finally, reload the FileOpenDialog in the same folder when the wrong file was selected.

Create .txt file and open in Notepad without saving

I need to create a .txt file in C# .
Is there a way (and how to do?) to create a file and open it in Notepad, but without saving in somewhere first? The user would save it after he checks it.
No not really, i've seen some programs that do this like so, but its not ideal:
Create a temporary file, most programs use the temp directory
you get there by using %temp% or C:\Users\{username}\AppData\Local\Temp so e.g. File.Create(#"C:\Users\{username}\AppData\Local\Temp\myTempFile.Txt")
Open the file with notepad. (File.Open(#"C:\Users\{username}\AppData\Local\Temp\myTempFile.Txt"))
The user makes the change and saves
Your program checks the file to see if any edits were made.
if any edits have been made, you can prompt the user to save the file to the actual location.
e.g. !string.IsNullOrWhiteSpace(File.ReadAllText(#"C:\Users\{username}\AppData\Local\Temp\myTempFile.Txt"))
If the user wants to save the file, the file gets copied to the real location
File.Copy(#"C:\Users\{username}\AppData\Local\Temp\myTempFile.Txt", #"c:\myRealPath\MyRealFileName.txt"
I created a way (I don't know if it already exists), using System.Diagnostics and System.Reflection libraries. My code is:
File.WriteAllText($#"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\exampleDoc.txt", "information inside file");
while (!File.Exists($#"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\exampleDoc.txt")) { }
Process.Start($#"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\exampleDoc.txt");
while (Process.GetProcesses().Where(prc => { try { return prc.MainWindowTitle.Contains("exampleDoc.txt"); } catch { return false; } }).Count() == 0) { }
File.Delete($#"{Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\exampleDoc.txt");

How do I Use OpenFileDialog to select files or paths

I am writing a WPF / C# application, and would like to enable a user to select one (or multiple) files, or one (or multiple) folders, without having to select which option they use initially, but intentionally. In my opinion, the best way to acchieve this goal would be to have a standard FolderBrowserDialog, and as long as the user does not seelct a file, but browses to a path, clicking the open button should select that path.
Practically, this solution does not work, because OpenFileDialog does not allow empty selections, you can hit "open", but nothing will happen. There is one workaround descriped here which allows to enter a fake name like "Selected Folder." as filename. which can afterwards be filtered out, which is a workaround, but not a nice one:
http://www.codeproject.com/Articles/44914/Select-file-or-folder-from-the-same-dialog
This solution has two important weaknesses:
1.) you will have to filter for the fake name
2.) if you paste a filename manually, or select a file first, and then switch the selection to a folder instead, the fake name is not inserted automatically.
of course I am aware there is something like FolderBrowserDialog, which I omit using even if I only wanted to select folders and not files. The reason: this dialog has no possibility to paste paths from clipboard, and I find it annoying to navigate all the way, I rather copy paths from somewhere and paste them, which works perfectly fine in OpenFileDialog, but not in FolderBrowserDialog. Besides, FolderBrowserDialog does not allow to select files and folders.
I have googled a lot, but do not find satisfying solutions, although I am sure many people must obviously face this problem.
As mentioned, the most elegant way for me would be to make the OpenFileDialog simply allow empty Filename boxes when clicking Open - any way to acchieve this?
Thanks alot.
Letting a user select a directory OR a file using the same dialog is not practical nor intuitively possible.
However, if you want a solution for selecting a Folder, here it is :
If you don't want to create a custom dialog but still prefer a 100% WPF way and don't want to use separate DDLs, additional dependencies or outdated APIs, I came up with a very simple hack using WPF's Save As dialog for actually selecting a directory.
No using directive needed, you may simply copy-paste the code below !
It should still be very user-friendly and most people will never notice.
The idea comes from the fact that we can change the title of that dialog, hide files, and work around the resulting filename quite easily.
It is a big hack for sure, but maybe it will do the job just fine for your usage...
In this example I have a textbox object to contain the resulting path, but you may remove the related lines and use a return value if you wish...
// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
string path = dialog.FileName;
// Remove fake filename from resulting path
path = path.Replace("\\select.this.directory", "");
path = path.Replace(".this.directory", "");
// If user has changed the filename, create the new directory
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Our final value is in path
textbox.Text = path;
}
The only issues with this hack are :
Acknowledge button still says "Save" instead of something like "Select directory", but in a case like mines I "Save" the directory selection so it still works...
Input field still says "File name" instead of "Directory name", but we can say that a directory is a type of file...
There is still a "Save as type" dropdown, but its value says "Directory (*.this.directory)", and the user cannot change it for something else, works for me...
Most people won't notice these, although I would definitely prefer using an official WPF way if microsoft would get their heads out of their asses, but until they do, that's my temporary fix.

Winforms select filename for saving document

I have some data and I would like to export it to excel. I did all the code, and everything is working fine, Now I want to save that excel file to the hard drive. I could do that too. but my problem is that I couldn't know how to allow the customer to set his/her own file name.
What I have tried:
FolderBrowserDialog brwsr = new FolderBrowserDialog();
//Check to see if the user clicked the cancel button
if (brwsr.ShowDialog() == DialogResult.Cancel)
return;
else
{
string newDirectoryPath = brwsr.SelectedPath;
//Do whatever with the new path
}
the problem of that method is it is just allows the users to select the folder that the want the file to be saved to. I want to all the user to specifiy the path and the file name.
Any idea to help pleaes?
many thanks
You need to use a SaveFileDialog instead. This let's the user specify a path + filename. Check this out for more info: SaveFileDialog on MSDN
SaveFileDialog is pretty similar to FolderBrowserDialog, so you can almost replace the existing code you already have ;)
Specify File Type (EDIT)
Have a look a the Filter property.
Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*

How to Determine If a Word Document Is Read-Only?

I use Word.Interop to work with Word Document and let user to open a file from hard disk.
Sometimes I get error saying that the file that user has chosen is readonly.
How can I check if a file is readonly or not?
Are you sure you are actually talking about the File attribute (that can be set via the Windows file properties dialog)? If so, you can use FileInfo.IsReadOnly:
FileInfo fileInfo = new FileInfo(#"path\to\file");
if (fileInfo.IsReadOnly)
{
// do something
}
otherwise, refer to this answer if another process is using the file.

Categories

Resources