File hash algorithm code c# - c#

Part of my application will hopefully be able to hash files which the user specifies, but I am stuck on the actual code itself. Note that:
filepath512(.text) = Textbox in which the user inserts the file path
fileout(.text) = Output textbox
button21_click = "Hash/confirm" button used to start the hashing algorithm
When I run the application and run the hashing algorithm, nothing happens (the result does not appear in the Output textbox).
A few weeks ago, I actually successfully executed the hashing algorithm with the identical code (well, same structure) and it worked perfectly well!
I have just begun working with C#, so please excuse any messy code!
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string filePath = e.Argument.ToString();
byte[] buffer;
int bytesRead;
long size;
long totalBytesRead = 0;
using (Stream file = File.OpenRead(filePath))
{
size = file.Length;
using (HashAlgorithm hasher = SHA512.Create())
{
do
{
buffer = new byte[4096];
bytesRead = file.Read(buffer, 0, buffer.Length);
totalBytesRead += bytesRead;
hasher.TransformBlock(buffer, 0, bytesRead, null, 0);
backgroundWorker1.ReportProgress((int)((double)totalBytesRead / size * 100));
}
while (bytesRead != 0);
hasher.TransformFinalBlock(buffer, 0, 0);
e.Result = MakeHashString(hasher.Hash);
}
}
}
private static string MakeHashString(byte[] hashbytes)
{
StringBuilder hash = new StringBuilder(32);
foreach (byte b in hashbytes)
hash.Append(b.ToString("X2").ToLower());
return hash.ToString();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar3.Value = e.ProgressPercentage;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
fileout512.Text = e.Result.ToString();
progressBar3.Value = 0;
}
private void button21_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(filepath512.Text);
}

Actually, your code misses a lot of sanity checks. First of all, you should use OpenFileDialog instead of a direct user input for specifying a path. Second, once the process starts, you should make sure the file exists using File.Exists method... if it doesn't, you should return an appropriate result.
Probably, an exception is being thrown by your code, somewhere. From the official MSDN documentation:
If the operation completes successfully and its result is assigned in
the DoWork event handler, you can access the result through the
RunWorkerCompletedEventArgs.Result property.
[...]
Your RunWorkerCompleted event handler should always check the Error
and Cancelled properties before accessing the Result property. If an
exception was raised or if the operation was canceled, accessing the
Result property raises an exception.
So check error details using the Error properties of the event arguments in order to make sure that your code was properly executed without exceptions. If this is the case, you must fix the code so that the hashing doesn't fail anymore.

does the file exists? you have to check whether the file exists always before trying to do operations. debug the filepath and see whether it exist, and it has read permissions.

Related

FileSystemWatcher - Reading last line of file after update?

I'm trying to write a simple console application that waits for a change to a file then reads just the last line of that file. The file watcher works and the change event fires. But I'm struggling to work out how read from the file.
static void Main(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Path = "E:\\myFilePath";
watcher.Filter = "";
watcher.EnableRaisingEvents = true;
watcher.Changed += new FileSystemEventHandler(watcher_Changed);
Console.ReadKey();
}
static void watcher_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine(File.ReadLines(e.FullPath).Last());
}
when testing (editing the file in notepad) it will work once, then after a second edit I get the error...
System.IO.IOException: 'The process cannot access the file '' because
it is being used by another process.'
I still ran into problems using lines.GetEnumerator().Dispose();
You can add a pause before opening the file, just chose your poison for doing so.
static void watcher_Changed(object sender, FileSystemEventArgs e)
{
for (int x = 0; x <= 500000; x++)
{
int t = x;
}
Console.WriteLine(File.ReadLines(e.FullPath).Last());
}
I tried using SreamReader too but still ran into the same problem.
// Does not work
using (StreamReader r = new StreamReader(e.FullPath))
{
while (r.EndOfStream == false)
{
m = r.ReadLine();
}
r.Close();
}
Console.WriteLine("{0}\n", m);
The problem is due to an already open handle to the file. File.ReadLines uses an iterator internally which is Disposable. Use this to ensure Disposal during the lifetime of your event handler.
static void watcher_Changed(object sender, FileSystemEventArgs e)
{
var lines = File.ReadLines(e.FullPath);
Console.WriteLine(lines.Last());
lines.GetEnumerator().Dispose();
}
This should guarantee disposal before the end of event handler.
Edit: In the case that a different process is holding a write lock to the file, use Thread.Sleep(ms) with a safe time as inspecting and releasing file handles is not feasible in C#.

Processing and displaying data from serial port - C#

I'm developing a small program that receives analog data from the serial port and displays it into multiple Textboxes.
The data is 10 bit A2D from a micro in the form of two Hex bytes and a letter to identify which A2D port it came from.
eg: 0x1A, 0x02, A
My program is receiving the data ok, and if I only display receive analog value at a time it works fine.
The problem I have is that I'm unsure how to process the incoming data when I try to receive multple A2D values.
The code below is suppose to display 3 analog values in separate text boxes, but only the first text box displays any data. What would be the best way to go able this?
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
//Initialize a buffer to hold the received data
byte[] buffer = new byte[serialPort1.ReadBufferSize];
int bytes = serialPort1.BytesToRead;
//There is no accurate method for checking how many bytes are read
//unless you check the return from the Read method
bytesRead = serialPort1.Read(buffer, 0, bytes);
nValue = buffer[0] + (buffer[1] << 8);
switch1 = Convert.ToChar(buffer[2]);
switch (switch1)
{
case 'A':
DispString1 = nValue.ToString();
this.Invoke(new EventHandler(textBox0_TextChanged));
break;
case 'B':
DispString2 = nValue.ToString();
this.Invoke(new EventHandler(textBox1_TextChanged));
break;
case 'C':
DispString3 = nValue.ToString();
this.Invoke(new EventHandler(textBox2_TextChanged));
break;
}
}
private void textBox0_TextChanged(object sender, EventArgs e)
{
textBox0.Text = DispString1;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = DispString2;
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox2.Text = DispString3;
}
bytesRead = serialPort1.Read(buffer, 0, bytes);
You blindly assume that you'll get 3 bytes, required to make the rest of the code work. That is not how serial ports work. You in fact usually get only 1 or 2 bytes, serial ports are very slow. So of course your switch() statement cannot get a match.
Get ahead with:
byte[] buffer = new byte[3];
int len = 0;
while (len < 3) {
len += serialPort1.Read(buffer, 0, 3-len);
}
// etc..
Do note that you have a tricky synchronization problem. If you call the Open() method while the device is sending then the first byte you receive is not necessarily the first byte of the 3 byte response. You'll never get a proper response. A device usually sends extra bytes to indicate the start and the end of a frame of data to help solve that problem, that however doesn't seem to be the case here. Fixing this at the device end ought to be a strong goal.

LibUsbDotNet USBEndpointReader DataReceived event is not firing when I expect it to

I have a USB device from which I need to read data via LibUsbDotNet.
If I use the following code after I've successfully opened the device...
protected UsbEndpointReader _libUsbReader = null;
protected UsbEndpointWriter _libUsbWriter = null;
.
IUsbDevice wholeUsbDevice = PhysicalLibUSBDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
// This is a "whole" USB device. Before it can be used,
// the desired configuration and interface must be selected.
// Select config #1
wholeUsbDevice.SetConfiguration(1);
// Claim interface #0.
wholeUsbDevice.ClaimInterface(0);
}
// Create the reader and writer streams
_libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01);
_libUsbWriter = PhysicalLibUSBDevice.OpenEndpointWriter(LibUsbDotNet.Main.WriteEndpointID.Ep02);
_libUsbReader.DataReceivedEnabled = true;
_libUsbReader.DataReceived += OnDataReceived;
_libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
_libUsbReader.ReadBufferSize = 32;
and define the method:
private void OnDataReceived(object sender, EndpointDataEventArgs e)
{
Console.WriteLine("Data received");
}
The event never fires. I know the packets are being received by my code as I have a USB analyser attached and can see them coming in.
If I change the code to remove the reliance upon the event callback and instead use the loop below on a background thread to read the reader object
while(true)
{
ErrorCode ec = ErrorCode.None;
Thread.Sleep(5);
int bytesRead;
byte[] buffer = new byte[32];
ec = _libUsbReader.Read(buffer, 1000, out bytesRead);
if(bytesRead>0) Console.WriteLine("Data Received");
}
Then everything works great.
I've tried playing around with the order I initialise, the values etc and can still get no joy. Can anyone suggest why the events aren't firing if I use the DataReceived event?
I'm using LibUsbDotNet 2.2.8.
I know this is old, but in your code:
...
_libUsbReader.DataReceivedEnabled = true;
_libUsbReader.DataReceived += OnDataReceived;
_libUsbReader.ReadThreadPriority = System.Threading.ThreadPriority.Highest;
_libUsbReader.ReadBufferSize = 32;
...
I have DataReceivedEnabled set after DataReceived (not sure if this makes a difference).
Also, I do not change thread priority and ReadBufferSize. The latter is 4096 by default. When data arrives, the EndpointDataEventArgs parameter to the event has the Count property with the actual number of bytes received.
Hope this helps.
Please try like this:
_libUsbReader.DataReceived += mEp_DataReceived;
private void mEp_DataReceived(object sender, EndpointDataEventArgs e)
{
try
{
Invoke(new OnDataReceivedDelegate(OnDataReceived), new object[] { sender, e });
}
catch
{
closeDevice();
}
}
When opening the endpoint for reading, you should define the endpoint type to interrupt, otherwise the Datarecieve event won't fire.
(Optionally define the size of the read buffer)
In your code you'll have to modify just this row:
_libUsbReader = PhysicalLibUSBDevice.OpenEndpointReader(LibUsbDotNet.Main.ReadEndpointID.Ep01, 64, EndpointType.Interrupt);
I think the sollution is that you should read the endpoint content at the event (or discard it). I had the same problem, when only printing at the console the message I only entered 1 time. When I process in the event the data on the endpoint with read command, the problem seems to be solved.

Coudln't remove file from View Model: IOException was unhandled

I was trying to delete an Image from the view Model after some modification but I'm getting this error message IOException was unhandled
I disposed the current bitmap currImgHandler.CurrentBitmap.Dispose();and also made the Image Source to be null ViewedPhoto.Source = null;
if i click on the button which has the Rotate function (90°) once and clikcing on the delete function which produces the error IOException was unhandled
If i clcik on the button Roate function twicethen click on Delete function; I don't get any error and it deletes image without any problem.
What is the mistake am I doing here? Thank you
Selecting an Image from ListView:
private string saveFilname;
private void showImage(object sender, SelectionChangedEventArgs args)
{
ListBox list = ((ListBox)sender);
if (list != null)
{
int index = list.SelectedIndex;
if (index >= 0)
{
ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
if ((image != null))
{
saveFilname = image.FileName.ToString();
currImgHandler.CurrentFileHandler.Load(image.FileName);
PaintImage();
}
}
}
}
Delete Function:
private void bDeletePhoto_Click(object sender, RoutedEventArgs e)
{
ImageFileCollectionViewModel viewModel = imageListBox.DataContext as ImageFileCollectionViewModel;
if (viewModel != null)
{
ImageFileViewModel image = imageListBox.SelectedItem as ImageFileViewModel;
if (image != null)
{
//remove physical file from disk:
currImgHandler.CurrentBitmap.Dispose();
ViewedPhoto.Source = null;
File.Delete(image.FileName);
//remove item from ObservableCollection:
viewModel.AllImages.Remove(image);
}
}
}
//Rotate Function:
private void Button_Click(object sender, RoutedEventArgs e)//Rotate
{
currImgHandler.CurrentRotationHandler.Flip(RotateFlipType.Rotate90FlipNone);
PaintImage();
}
private void PaintImage()
{
System.IO.MemoryStream stream = new System.IO.MemoryStream();
currImgHandler.CurrentBitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp);
stream.Position = 0;
byte[] data = new byte[stream.Length];
stream.Read(data, 0, Convert.ToInt32(stream.Length));
BitmapImage bmapImage = new BitmapImage();
bmapImage.BeginInit();
bmapImage.CacheOption = BitmapCacheOption.OnLoad;
bmapImage.StreamSource = stream;
bmapImage.EndInit();
ViewedPhoto.Source = bmapImage; //ImageBox
ViewedPhoto.Stretch = Stretch.Uniform;
}
Error message:
Your application is throwing an IOException. Likely culprit:
File.Delete(image.FileName);
IMO You should avoid making calls like this directly in event handlers for the reason demonstrated here - it is hard to catch exceptions thrown directly from an event handler.
If implementing MVVM this doesn't tend to occur.
Perhaps the account privileges under which your application is running are not sufficient to let you delete the file. Please check the credentials of this account against operations on the file you want to delete.
It's only a supposition though, it's hard to be sure without the IOEXception content, and it could also be because the path you're using doesn't exist, etc...
After Drew Rsuggestion i have added a method in the MVVM itself:
public void RemoveOldPhotoItem(ImageFileViewModel imageFile)
{
this._allImages.Remove(imageFile);
this.DataItemsCount++;
File.Delete(imageFile.FileName);
}
I need to dispose the image which was used by a 3rd party .dll....which i disposed properly.
Sorry guys it was my mistake. Thank you for your support!

GetManifestResourceStream - how can it help caching?

i searched for embedding custom drag and drop cursor in my wpf app. i ended up with an article which i have no idea of ONE LINE in the code suggested in (it is highlighted with the comments):
private void textBlock2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
TextBlock btn = (TextBlock)sender;
GiveFeedbackEventHandler handler = new GiveFeedbackEventHandler(DragSource_GiveFeedback);
btn.GiveFeedback += handler;
DataObject dataObj = new DataObject(btn.Text);
DragDrop.DoDragDrop(btn, dataObj, DragDropEffects.Move);
btn.GiveFeedback -= handler;
}
void DragSource_GiveFeedback(object sender, GiveFeedbackEventArgs e)
{
try
{
if (_allOpsCursor == null)
{
////////////////////////////////////////THE UNKOWN ONE LINE STARTS HERE
using (Stream cursorStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SimplestDragDrop.DDIcon.cur")) // AND ENDS HERE
{
_allOpsCursor = new Cursor(cursorStream);
}
}
Mouse.SetCursor(_allOpsCursor);
e.UseDefaultCursors = false;
e.Handled = true;
}
finally { }
}
i checked GetManifestResourceStream, but i still have no idea what a mainfest resource is how could it be handled and where to start to get this caching idea (mentioned in the main article) to work.
Your assembly is loaded into memory as part of the AppDomain executing under the CLR. Because of this, if the resource is embedded into the assembly as part of the compilation process, using a stream to read an in-memory byte array is faster than having to go to disk to open a file, read its contents, close the file.
Alternatives are to store a byte array representing the resource within the source code, though more or less you're arriving at the same place using GetManifestResourceStream.

Categories