I'm been wondering is there a way to save a file in specific's folder in C#?
The only method that I know is 'SaveFileDialog' but the problems is I want to save files
in folder without showing saveFilesDialog's Box.
saveFilesDialog's Box : is a box that prompts you to Click 'YES' or 'CANCEL'.
Code samples
-In form1
public Form1()
{
InitializeComponent();
}
private string Path =#"D:\Files"; //locaction i wanna stores all the files in
private int i = 0;
private button1_Click(object sender,EventArgs e)
{
i++;
SaveDialogFile save = new SaveDialogFile();
if(Save.
if (save.ShowDialog() != DialogResult.OK)return; //Prompt's Dialog will show
save.Filter = "File Text(*.txt)|*.txt";
save.InitialDirectory = Path;
save.FileName = "txt"+i.ToString();
//Goal : i want 'save.FileName' store in 'Path' without Click 'OK' or Show Prompt Dialog's box
}
Expect Result
[1]: https://i.stack.imgur.com/9JqWO.png
Anyone can help me? I kinda stuck rn :)
This is my full code it's hard to read but you'll get the point
public partial class convertMp3ToWav : Form
{
public convertMp3ToWav()
{
InitializeComponent();
}
BackgroundWorker bw;
string withoutEx;
List<string> song_lists = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
bw = new BackgroundWorker();
bw.DoWork += (obj, ae) => newThread();
bw.RunWorkerAsync();
}
void newThread()
{
Thread th = new Thread
((ThreadStart)(() =>
{
file();
}));
th.SetApartmentState(ApartmentState.STA);
th.Start();
th.Join();
}
void file()
{
string path = #"D:\musics\wav";
Directory.CreateDirectory(path);
FolderBrowserDialog f = new FolderBrowserDialog();
f.ShowDialog();
string[] lists = Directory.GetFiles(f.SelectedPath, "*.*", SearchOption.AllDirectories);
foreach (string list in lists)
{
if (Path.GetExtension(list) == ".mp3")
{
string fn = Path.GetFullPath(list);
withoutEx = Path.GetFileNameWithoutExtension(fn);
song_lists.Add(fn);
Console.WriteLine(withoutEx);
SaveFileDialog save = new SaveFileDialog();
save.Filter = "Wav FIle (*.wav)|*.wav;";
//save.FileName = song_lists[0];
save.FileName = withoutEx;
save.InitialDirectory = path;
if (save.ShowDialog() == DialogResult.OK)
{
using (Mp3FileReader mp3 = new Mp3FileReader(fn))
{
using (WaveStream pcm = WaveFormatConversionStream.CreatePcmStream(mp3))
{
WaveFileWriter.CreateWaveFile(save.FileName, pcm);
}
}
}
}
}
}
}
this code's work pretty well!! but i need to click 'OK' everytime!!
so is there anyway to save file without click 'OK' everytime!!
Conceptually the only thing SaveFileDialog is doing, if you merely click OK when it shows, is changing the file extension*. Use Path.ChangeExtension instead
var pathToSaveWavTo = Path.ChangeExtension(pathToMp3, "wav");
The wav will be saved alongside the mp3. If you want to save it elsewhere, use Path.Combine to build a new path e.g.
pathToSaveWavTo = Path.Combine(#"c:\temp", Path.GetFileName(pathToSaveWavTo));
*I say this because giving it a filter of *.WAV and a filename xxx without the mp3 extension will cause it to give you a filename of xxx.wav when you only click OK, thus xxx.mp3 -> xxx.wav
Related
i'm stuck with my program in c#. So the user has to press a button to create a random string (working fine) he can then chose to click on the other button. this one opens a filedialog and let him chose a dll file he want to rename into the random string. i can't get it working. it says my dll is already running in another process (wich is not). Any help is greatly appreciated :)
private void btnEncrypt_Click_1(object sender, EventArgs e)
{
// sets a random string to txtEncrypt.text
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog MyOpenFileDialog = new OpenFileDialog();
//filedialog
MyOpenFileDialog.Filter = "dll files (*.dll) |*.dll";//filter
MyOpenFileDialog.Title = "Chose the dll file";
MyOpenFileDialog.InitialDirectory = "C:\\Users\\Gebruiker\\Desktop";
MyOpenFileDialog.FilterIndex = 1;
MyOpenFileDialog.RestoreDirectory = true;
//if ok
if (MyOpenFileDialog.ShowDialog() == DialogResult.OK)
{
strPath = MyOpenFileDialog.FileName;
StreamReader reader = new StreamReader(strPath);
System.IO.File.Move(strPath, "C:\\Users\\Gebruiker\\Desktop\\" + txtEncrypt.Text + ".dll");
}
else //cancel
{
strPath = null;
}
It's because your StreamReader is opening the file so it can't be moved. That line doesn't appear to be doing anything anyway so you can probably remove it. Ideally replace it with
if (System.IO.File.Exists(strPath))
{
System.IO.File.Move(strPath, "C:\\Users\\Gebruiker\\Desktop\\" + txtEncrypt.Text + ".dll");
}
Just comment the initialization of the streem reader line or move it next to the rename line but don't forget to pass the new name
I try to open System file dialog to select a pic. the code ran normally in my computer. But in another computer cant show the system file dialog.
And here is my simple code:-
private void PicInputBtn_Click(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.OpenFileDialog
{
DefaultExt = ".jpg",
Filter = "img file|*.jpg",
};
if (dialog.ShowDialog() != true)
{
return;
}
}
If nothing happens but the mouse pointer turning into a little busy-indicator.
You can try to set your thread to STAThread:
[STAThread]
static void Main(string[] args)
{
var o = new OpenFileDialog();
var r = o .ShowDialog();
}
Howover they are many reasons that can break the OpenFileDialog, you can try to launch your program in admin mode and try to reinstall .net Framework
Change your code to:
private void PicInputBtn_Click(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.OpenFileDialog
{
DefaultExt = ".jpg",
Filter = "img file|*.jpg" // You had an extra ',' here.
};
if ((Nullable<bool>dialog.ShowDialog()) == true) // Also you forgot to put Nullable<bool>
{
// string filename = dlg.FileName;
}
else
{
return;
}
}
My issue is that I keep seeing a recurring theme with trying to allow my Notepad clone to save a file. Whenever I try to save a file, regardless of the location on the hard disk, the UnauthorizedAccess Exception continues to be thrown. Below is my sample code for what I've done, and I have tried researching this since last night to no avail. Any help would be greatly appreciated.
//located at base class level
private const string fileFilter = "Text Files|*.txt|All Files|*.*";
private string currentPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
private void MenuFileSaveAs_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.DefaultExt = "*.txt";
sfd.Filter = fileFilter;
sfd.AddExtension = true;
sfd.InitialDirectory = currentPath;
sfd.RestoreDirectory = true;
sfd.OverwritePrompt = true;
sfd.ShowDialog();
try
{
System.IO.File.WriteAllText(currentPath,TxtBox.Text,Encoding.UTF8);
}
catch (ArgumentException)
{
// Do nothing
}
catch(UnauthorizedAccessException)
{
MessageBox.Show("Access Denied");
}
}
Change the following lines.
...
if (sfd.ShowDialog() != true)
return;
try
{
using (var stream = sfd.OpenFile())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
writer.Write(TxtBox.Text);
}
}
...
I hope it helps you.
You need to get the correct path context and file object from the dialog box once the user has hit 'ok'. Namely verify the user actually hit ok and then use the OpenFile property to see what their file selection is:
if (sfd.ShowDialog.HasValue && sfd.ShowDialog)
{
if (sfd.OpenFile() != null)
{
// convert your text to byte and .write()
sfd.OpenFile.Close();
}
}
I am working on a C# project and i need the file to deleted after 30 seconds. So once the file sent to the machine i need the software to count till 30 seconds and at same time show a splash form and once 30 seconds crossed close the splash screen and then delete the file.
I have added a splash screen called "image". So now what happens is, the data is only sent to the printer after the splash screen is closed. I need to multi thread the job. I mean the data should print in one side while the splash screen should show at the same time. Is there a way i can come out!!.. Please help me out.
So in my case i am copying the file to the bin/debug folder. then sending data to the machine simultaneously show the splash screen for 30 seconds and close the splash screen and then i need to delete the file..
codes:
private void button4_Click(object sender, EventArgs e)
{
//string filePath = image_print();
// MessageBox.Show(filePath, "path");
string s = image_print() + Print_image();
if (String.IsNullOrEmpty(s) || img_path.Text == "")
{
return;
}
else
{
//here its coming to the splash screen code, But data is transferred to the machine only after the splash screen is close :-(
this.Hide();
omg = new image();
omg.ShowDialog();
this.Show();
//splash screen closed and then data is transferred.. which i don't need.. i need simultaneous job to be done at the same time..
PrintFactory.sendTextToLPT1(s);
}
}
private string image_print()
{
OpenFileDialog ofd = new OpenFileDialog();
string path = "";
string full_path = "";
string filename_noext = "";
ofd.InitialDirectory = #"C:\ZTOOLS\FONTS";
ofd.Filter = "GRF files (*.grf)|*.grf";
ofd.FilterIndex = 2;
ofd.RestoreDirectory = true;
if (ofd.ShowDialog() == DialogResult.OK)
{
filename_noext = System.IO.Path.GetFileName(ofd.FileName);
path = Path.GetFullPath(ofd.FileName);
img_path.Text = filename_noext;
//MessageBox.Show(filename_noext, "Filename"); - - -> switching.grf
// MessageBox.Show(full_path, "path");
//move file from location to debug
string replacepath = #"\\bin\Debug";
string fileName = System.IO.Path.GetFileName(path);
string newpath = System.IO.Path.Combine(replacepath, fileName);
// string newpath = string.Empty;
if (!System.IO.File.Exists(filename_noext))
System.IO.File.Copy(path, newpath);
filename_noext = img_path.Text;
MessageBox.Show(filename_noext, "path");
}
if (string.IsNullOrEmpty(img_path.Text))
return "";//
StreamReader test2 = new StreamReader(img_path.Text);
string s = test2.ReadToEnd();
return s;
}
private string Print_image()
{
//some codes
return s;
}
In image form: I have the following codes
public partial class image : Form
{
string filePath;
public image()
{
InitializeComponent();
// this.filePath = FileToDeletePath;
System.Timers.Timer timer1 = new System.Timers.Timer();
timer1.Interval = 30000;
timer1.Elapsed += timer1_Elapsed;
timer1.Start();
}
private void image_Load(object sender, EventArgs e)
{
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
//delete the file using "filePath"
string Filename = img_path.Text; // here i cannot pass the old string file name with extension to this form.. Any ways please help me out
if (string.IsNullOrEmpty(Filename))
return;
if (Filename.ToCharArray().Intersect(Path.GetInvalidFileNameChars()).Any())
return;
File.Delete(Path.Combine(#"\\bin\Debug", Filename));
}
}
something like this????
Task waitfordelete = Task.Run(() =>
{
image im = new image();
});
Assumptions: window image should be shown as a dialog (modal), and only while the call to PrintFactory.sendTextToLPT1 is in progress.
If that's correct, then something like this could work for you:
// Don't forget, you need to dispose modal dialogs
image omg = new image();
// Ensure the dialog has been shown before starting task. That
// way the task knows for sure the dialog's been opened and can
// be closed.
omg.Loaded += (sender, e) =>
{
// Run the print task in a separate task
Task.Run(() =>
{
PrintFactory.sendTextToLPT1(s);
// But get back onto the main GUI thread to close the dialog
Dispatcher.Invoke(() => omg.Close());
});
};
this.Hide();
omg.ShowDialog();
this.Show();
Apologies in advance for any typos/syntax errors/etc. Hopefully the above is sufficient to express the general idea.
The answer given by Narzul and Peter both are correct. You can implement any one. But, I know your next question will be how to implement that method in your code.
you can use Thread or Task class object to separate the process. So when one process is running then other process can perform their taks at that time. There are two process in your login. The first one is send the file to the printer and the second one is the show dialog for 30 seconds and then delete the file. You should create the another thread to invoke the any one of the process so other process can perform asynchronously.
1st: make the seperate process for Print file.
Task waitfordelete = Task.Run(() =>
{
PrintFactory.sendTextToLPT1(s);
});
this.Hide();
omg = new image();
omg.ShowDialog();
this.Show();
2nd: make the seperate process for show dialog and delete the file. But, I think you may get the error in this method. You cannot change the UI from other thread
Task waitfordelete = Task.Run(() =>
{
Dispatcher.Invoke(() => this.ShowSplashScreen());
});
PrintFactory.sendTextToLPT1(s);
private void ShowSplashScreen()
{
this.Hide();
omg = new image();
omg.ShowDialog();
this.Show();
}
if you don't want to use the thread or task then just simply handle the close event of Image form
this.Hide();
omg = new image();
omg.Show();
PrintFactory.sendTextToLPT1(s);
omg.FormClosed += (object sender, EventArgs e) => {
File.Delete(Path.Combine(Application.StartupPath, Path.GetFileName(img_path.Text));
this.Show();
};
and modify the code in timer_tick event in Image form and add the this.Close() after delete file statement.
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
....
//File.Delete(Path.Combine(#"\\bin\Debug", Filename)); comment this line
this.Close();
}
Another hidden question I have found here. here i cannot pass the old string file name with extension to this form.. Any ways please help me out
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
//delete the file using "filePath"
string Filename = img_path.Text; // here i cannot pass the old string file name with extension to this form.. Any ways please help me out
for that, you can create the property in Image class and assign the file name from the parent form.
Image omg = new Image()
omg.FileName = Path.Combine(Application.StartupPath, Path.GetFileName(img_path.Text));
omg.Show();
and the property in Image form will be created like this
public class Image : Form
{
public string FileName { get; set; }
public Image()
{
}
void timer1_Elapsed(object sender, ElapsedEventArgs e)
{
....
File.Delete(Path.Combine(Application.StartupPath, this.Filename));
this.Close();
}
}
NOTE: Use the Application.StartupPath istead of \\bin\debug
I am using this code to import text file to my ListBox
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
listBox2.Items.Add("");
}
It works fine for small text files, with 10 lines or so, but when I try to import bigger list, (4-5 megabytes) the program isn't responding and it's crashing.
Any help?
Use the BufferedStream class in C# to improve performance.
http://msdn.microsoft.com/en-us/library/system.io.bufferedstream.aspx
By using this:
string[] text = System.IO.File.ReadAllLines(file);
listBox1.Items.AddRange(text);
instead of this:
string[] text = System.IO.File.ReadAllLines(file);
foreach (string line in text)
{
listBox2.Items.Add(line);
}
you will speed up the execution at least 10-15 times because you are not invalidating listBox on every Item insert.
I have measured with few thousand lines.
The bottleneck could also be ReadAllLines if your text has too many lines. Even though I can't figure out why you would be inserting so many lines, will user be able to find the line he/she needs?
EDIT OK then I suggest you to use BackgroundWorker, here is the code:
First you initialize BackGroundWorker:
BackgroundWorker bgw;
public Form1()
{
InitializeComponent();
bgw = new BackgroundWorker();
bgw.DoWork += new DoWorkEventHandler(bgw_DoWork);
bgw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgw_RunWorkerCompleted);
}
Then you call it in your method:
private void button1_Click(object sender, EventArgs e)
{
if (!bgw.IsBusy)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
string file = openFileDialog1.FileName;
listView1.BeginUpdate();
bgw.RunWorkerAsync(file);
}
}
else
MessageBox.Show("File reading at the moment, try later!");
}
void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
listView1.EndUpdate();
}
void bgw_DoWork(object sender, DoWorkEventArgs e)
{
string fileName = (string)e.Argument;
TextReader t = new StreamReader(fileName);
string line = string.Empty;
while ((line = t.ReadLine()) != null)
{
string nLine = line;
this.Invoke((MethodInvoker)delegate { listBox1.Items.Add(nLine); });
}
}
It will add each line when it reads it, you will have responsive UI, and lines won't affect the listBox before it finishes loading.
It maybe simply not completing its job, and you should have to wait for more. Try with this solution:
http://www.bytechaser.com/en/articles/f3a3niqyb7/display-large-lists-in-listview-control-quickly.aspx
could use a stream to store the data:
class Test
{
public static void Main()
{
string path = #"c:\temp\MyTest.txt";
//Create the file.
using (FileStream fs = File.Create(path))
{
AddText(fs, "This is some text");
AddText(fs, "This is some more text,");
AddText(fs, "\r\nand this is on a new line");
AddText(fs, "\r\n\r\nThe following is a subset of characters:\r\n");
for (int i=1;i < 120;i++)
{
AddText(fs, Convert.ToChar(i).ToString());
}
}
//Open the stream and read it back.
using (FileStream fs = File.OpenRead(path))
{
byte[] b = new byte[1024];
UTF8Encoding temp = new UTF8Encoding(true);
while (fs.Read(b,0,b.Length) > 0)
{
Console.WriteLine(temp.GetString(b));
}
}
}
private static void AddText(FileStream fs, string value)
{
byte[] info = new UTF8Encoding(true).GetBytes(value);
fs.Write(info, 0, info.Length);
}
}
then you event handler
privateasyncvoid Button_Click(object sender, RoutedEventArgs e)
{
UnicodeEncoding uniencoding = new UnicodeEncoding();
string filename = #"c:\Users\exampleuser\Documents\userinputlog.txt";
byte[] result = uniencoding.GetBytes(UserInput.Text);
using (FileStream SourceStream = File.Open(filename, FileMode.OpenOrCreate))
{
SourceStream.Seek(0, SeekOrigin.End);
await SourceStream.WriteAsync(result, 0, result.Length);
}
}
Your application becomes unresponsive because it's waiting for the ReadAllLines method to complete and blocks the UI thread. You may want to read files on a separate thread to avoid blocking the UI. I cannot guarantee that the code below will work without errors but it should give you an idea on how to tackle the problem.
First of all, you'll need a method to append an item to the ListBox:
private void AddListBoxItem(string item)
{
if(!InvokeRequired)
{
listBox2.Items.Add(item);
}
else
{
var callback = new Action<string>(AddListBoxItem);
Invoke(callback, new object[]{item});
}
}
The method above checks if it is executed on UI thread and if yes, it simply adds an item to the listBox2.Items collection; if not, it creates a delegate from itself and invokes that delegate on UI thread.
Next, you'll need to move the code that reads the file to another thread and call AddListBoxItem method. For the sake of readability, let's put that into a separate method:
private void AddFileContentsToList(string fileName)
{
using(var reader = new System.IO.StreamReader(fileName))
{
while(!reader.EndOfStream)
{
var line = reader.ReadLine();
AddListBoxItem(line);
}
}
}
And now we will call the method on a separate thread:
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Text Files|*.txt";
openFileDialog1.Title = "Select a Text file";
openFileDialog1.FileName = "";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
var thread = new Thread(AddFileContentsToList);
thread.Start();
}
Hope this helps!