C#Newbie01

Hello, I want to try using the progressbar, but after reading the chapters in my C# book I'm very confused. I would basically like to link the progressbar to the transfer of a file (Something simple to play around with). But when I click the button, it only shows a sliver of the progressbar filled up, then it stops and the file transfers normally. How would I do this to link to the file transfer Here is my code:

private void buttonX3_Click(object sender, EventArgs e)
{
progressBarX1.PerformStep();
File.Copy(@"File", Environment.CurrentDirectory + @"New File", true);
}

Thank you.


Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

to show the progress of some operation, you need to be able to get feedback about where in the process it is, then update the progress bar to show the progress.

The code you had, will step once, copy the file, then return back to the form.

I'm not sure you'd be able to do what you want with the stock copy. You could make your own by opening the source file as a BinaryReader and the destination as a BinaryWriter and then read in from the reader to write to the writer

it'll look something like this psudocode

Code Snippet


progressBar1.Value = progressBar1.Minimum;
System.IO.BinaryReader Reader = new System.IO.BinaryReader(new System.IO.FileStream( textBox1.Text, System.IO.FileMode.Open ));
System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(new System.IO.FileStream( textBox2.Text, System.IO.FileMode.Create ));
progressBar1.Maximum = (int)Reader.BaseStream.Length;
while( Reader.PeekChar() != -1 )
{
Writer.Write(Reader.ReadByte());
progressBar1.PerformStep(); // 1 byte transfered
}
Reader.Close();
Writer.Flush();
Writer.Close();
progressBar1.Value = progressBar1.Maximum;


You may want to change how you get the maximum and how you step.





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Thank you very much for your help, I will try something like that and will read those articles as well. I really appreciate your help, and will post back if I have any problems. One question I do have about this is, where would it reference the file to be copied I don't really understand.

Thank you.




Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

Just change textBox1.Text with the string path for the source file, and textBox2.Text with the string path for the destination file. This will open your source file (file to be copied) with the BinaryReader, and open your destination file as a BinaryWriter.





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Thank you very much for your help, I am trying to understand that code. I did try to implement it, and am getting the following error:

The output char bugffer is too small to contain the decoded ccharacters, encoding 'Unicode (UTF-8' fallback 'System.Text.DecoderReplacementFallback'.
Parameter name: chars.

I am not sure what this error means, but it crashes the program. Do you happen to know how to fix this I'm not sure what it means...

Thank you.




Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

You should probably add a Writer.Flush inside the while loop.

What filetype are you working with It's possible that you may need to increase the size of the copied blocks/while condition to better preserve the file format. Depending on what type of file you're copying, you may/could use different encoding and even use a different stream handler. I choose Binary because it is more generic in what it can read/write.





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Hi, thank you very much for your response and help. I added the Writer.Flush to the while loop. The file I am trying to copy is an .exe file. Does that need to be handled differently I apologize if this created some confusion. Would I need to change things around for a .exe file

Thanks,




Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

Nope, Binary should be the proper streams to use, with copying byte by byte. If you have any more problems, maybe you can post your copy code/file code so that I can see if there might be any other problems.





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Thank you very much for your response, I am still getting that error about 1/4 of the way into the progressbar. The .exe file appears to be copying properly. Here is more information on the error:

See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.ArgumentException: The output char buffer is too small to contain the decoded characters, encoding 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'.
Parameter name: chars
at System.Text.Encoding.ThrowCharsOverflow()
at System.Text.Encoding.ThrowCharsOverflow(DecoderNLS decoder, Boolean nothingDecoded)
at System.Text.UTF8Encoding.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, DecoderNLS baseDecoder)
at System.Text.DecoderNLS.GetChars(Byte* bytes, Int32 byteCount, Char* chars, Int32 charCount, Boolean flush)
at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex, Boolean flush)
at System.Text.DecoderNLS.GetChars(Byte[] bytes, Int32 byteIndex, Int32 byteCount, Char[] chars, Int32 charIndex)
at System.IO.BinaryReader.InternalReadOneChar()
at System.IO.BinaryReader.Read()
at System.IO.BinaryReader.PeekChar()
at WindowsApp.Form1.buttonX1_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

And here is the code:

foreach (Process p in Process.GetProcessesByName("WindowsApp2"))
{
p.Kill();
p.WaitForExit();
}

progressBarX1.Value = progressBarX1.Minimum;
System.IO.BinaryReader Reader = new System.IO.BinaryReader(new System.IO.FileStream(@"S:\WindowsApp2.exe", System.IO.FileMode.Open));
System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(new System.IO.FileStream(Environment.CurrentDirectory + "WindowsApp2.exe", System.IO.FileMode.Create));
progressBarX1.Maximum = (int)Reader.BaseStream.Length;
while (Reader.PeekChar() != -1)
{
Writer.Write(Reader.ReadByte());
progressBarX1.PerformStep();
Writer.Flush();
}
Reader.Close();
Writer.Flush();
Writer.Close();
progressBarX1.Value = progressBarX1.Maximum;
}

I'm not sure what the issue could be, it looks like it copies the file fine, but I get this error and the program crashes.

Thank you.




Re: Visual C# Express Edition Progressbar question?

jrboddie

I am not sure but I think the problem occurs when you do a PeekChar(). In general, a Char can be more than one byte (depending on the encoding) . At the end of the file, you may be peeking only a partial Char--which it does not like. To make a Char equal to one byte, change this line as follows:

System.IO.BinaryReader Reader = new System.IO.BinaryReader(new System.IO.FileStream(@"S:\WindowsApp2.exe", System.IO.FileMode.Open) ,Encoding.ASCII);





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Thank you, I tried that, and now the Progressbar moves very slowly and the application freezes (Not Responding) if I click off of it. The files are not very large, it shouldn't take much time at all to do. Why would it do this The progressbar is a pretty cool control, but appears to be a bit temermental. How can I get this to work I'm open to any suggestions.

Thank you.




Re: Visual C# Express Edition Progressbar question?

jrboddie

My suggestion: Change the read/write loop to something like this:

Code Snippet

int nBytes = (int)Reader.BaseStream.Length;

progressBar1.Maximum = nBytes;

for (int i = 0; i < nBytes; i++)

{

Writer.Write(Reader.ReadByte());

progressBar1.PerformStep();

}





Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

If you're just having the code in an event, then you'll end up with a non-repsonsive UI because the copy is being performed on the UI thread. You may want to look into Threading or a BackgroundWorker to copy your file.

Also, using the number of bytes is a far better way to control the loop.





Re: Visual C# Express Edition Progressbar question?

C#Newbie01

Thank you very much for your help, that is working great. One final question I had if you don't mind (As I was trying to play around with this with no luck). If I needed to copy two or more files, how would I add the second one, etc. I tried a couple of different things, but nothing seemed to work.

Thank you again.





Re: Visual C# Express Edition Progressbar question?

IsshouFuuraibou

Just run through the code again with a different source/destination. Depending on how you get the files, you can put a for/foreach loop around your copy code and increment the file(s) to be copied.

Code Snippet

string[] SourceFiles = { a, b, c };
string[] DestFiles = { aa, bb, cc };
for ( int i = 0; i < SourceFiles.Length; i++ )
{
Open SourceFiles[i] for reading;
Open DestFiles[i] for writing;
Copy source to destination;
}


Pardon the psudo-code, mainly you just need to replace the code inside the for loop with the code to copy (changing the filename to the SourceFiles or DestFiles array respectively) and populate your two arrays. That's the gerenal case, you may want to just have multiple DestFiles. For that you can basically so the same loop with just a = b = c, or loop only on DestFiles.