23 Feb 2014 @ 1:58 PM 

Recently, a mysterious bug cropped up in one of the programs for which I had most of the responsibility. In this case the bug was a strange “The Program cannot access the specified file because it is in use by another process”

One particularly helpful trait to discovering the cause was that exceptions of this nature are actually logged to the Database, so I was able to determine with some accuracy where the exception was occurring. This was in an “Updater” program; the Exception was occurring when it tried to launch the installer it just finished downloading.

To me that didn’t make a whole lot of sense. I was unable to reproduce the error very often and when I Did I got the exception when the Updater attempted to download to a temporary file that was still in use (which I worked around anyway by attempting to find a filename that wasn’t present at all).

My suspicion is that when the Update Application finishes downloading the file, a Anti-virus program is accessing it on the machines with the issue. The problem appears to only occur for the larger updates, which still seems reasonable with this theory since larger updates would take longer to scan. Also, an AV program typically takes an exclusive lock on items it is scanning while it scans.

Even so, it is still only a guess. The only way to confirm it would be to somehow figure out and keep track of what other program(s) are using the file to try to figure out what is locking it.

On Windows XP, we would be out of luck- at least for any simple solution. It would certainly be possible to add this feature but the advanced memory spelunking Would be a pain- and it would require the use of subject-to-change functions like ntQuerySystemInformation or even a Driver, which is probably going a bit far.

Thankfully, Vista, 7, and 8 have a feature called a “Restart Manager”. The Restart Manager tracks open handles, so if we create a session and try to register a resource we can determine not only if a file is locked, but what processes are using that file.

The Basic steps are reasonably simple, given the complexity of the other alternatives:

  1. Start a Restart Manager Session with rmStartSession
  2. Use rmRegisterResources to attempt to register the file in question.
  3. Use the rmGetList Function to retrieve a list of Processes using said file.
  4. End the Restart Manager Session

The approach is relatively straightforward to create a class to provide this information:

At this point I had a way to retrieve the processes locking a set of files (normally for my uses, one file). leveraging it in the Update Program wouldn’t be entirely straightforward- the intent was to have that information logged, which means it would need to somehow be a part of the Exceptions “ToString()” result. In order to do this I simply created a new Exception:

With the new Exception in place, I was able to use it- My primary interest was in knowing what processes were accessing a file when it was in use. This Exception could be tracked specifically- it would be a Win32Exception with an HRESULT of 0x80004005:

Of course most of that is specific to the Updater implementation; essentially it will track when an updating item encounters an exception and use that to change it’s ListItem’s ProgressBar to be Red, as well as display a cursory set of exception information. The Information is also tracked in the PostGres database in the history, so it can be referred to later.

If the new version works I should be able to determine what other processes were locking the file simply be using the Installation History feature of the Updater. This can help me prove or disprove the possibility of it being Anti-virus related.

Posted By: BC_Programming
Last Edit: 23 Feb 2014 @ 01:58 PM

EmailPermalinkComments (0)
Tags
Tags: , ,
Categories: .NET, API, C#
 30 Jun 2013 @ 7:11 AM 


Embarassingly, I have come back to the FileIterator for other reasons only to discover, much to my horror, that it doesn’t work! It seems as if the work queue is empty far too fast or there are any number of other issues with the program that I’ve been unable to identify. It is unclear what the cause of the problem is- I suspect I will be “forced” to rewrite it entirely. If anybody sees what might be causing it please let me know so I can try to address it!

In a previous post, I looked at using the Win32 API through P/Invoke to directly call the Win32 FindFirstFile, FindNextFile, and FindClose() methods to perform a File search and retrieve those results using an Enumerator Method.

Here, we will look at what we can do to create a fully asynchronous search; in terms of allowing the results to process as the search continues, as well as perform that evaluation in a manner that best uses the available processing by processing multiple elements at the same time.

The first thing is that this won’t be an implementation of an interface; this has a large disadvantage in terms of Usability, but a wrapper could be created to provide IEnumerable<?> capabilities, so it won’t be something that should stop us.

The methodology I’ve thought of for this particular implementation is to use A background worker. When a search is started, the class will spin off that background worker, then proceed to perform it’s search, calling the appropriate filter delegate, and then if the resulting file is determined to “match” then it is added to a ConcurrentQueue. That ConcurrentQueue is examined intently by the BackgroundWorker, which waits until the Queue is Empty and the search is complete before it allows itself to exit. This is to protect from the eventuality where the actual Search logic that adds items to the Queue isn’t able to keep up with the BackgroundWorker Dequeue-ing elements.

We want to allow extensibility and custom filtering for both determining if the File counts as a “match” as well as whether a Directory should be recursed into. Appropriate overloads can be added that provide their own definitions of the more complex delegates, but we want to aim for a core level of functionality on which to build that simpler syntax.

The delegates

While we could feasibly use Predicate<> types as the parameters to the constructor of our search class for filtering, we will instead create specific delegates so we can more fully document the parameters and purpose of the delegates in XML documentation.

Since we will be dealing with the Win32 Find API, the appropriate declarations are a must. The required declarations are the struct, WIN32_FIND_DATA, the constants MAX_PATH and MAX_ALTERNATE, the ERROR_NO_MORE_FILES flag, as well as the FindFirstFile,FindNextFile, and FindClose API functions. We place these in the conventional NativeMethods class.

This also adds a few helpers. The actually search will be given two delegates, and we want to be able to pass in this information. So we will wrap the WIN32_FIND_DATA into a “FileSearchResult” class:

The purpose of this class is simple: First, we want to avoid instantiating a FileSystemInfo object if possible. The delegate method may not need that extra information, so we won’t create it ourselves. Instead, we provide easier wrappers around the WIN32_FIND_DATA, which includes wrapping the FILETIME structures and exposing them as the ‘everyday’ DateTime class type, which is far more familiar.

And there it is. It even has the IEnumerable implementation, as a static method. here’s a short program that uses it:

As it is there are some improvements I can think of. One would involve using Multicast Delegates rather than the basic Delegates, which is a fancy way of saying “use events fool!”. But at the same time that would probably fit more appropriately as a subclass which provides it’s own delegate implementations that instead call into events it declares, or something to that effect.

The full source to this Project can be found Here in a small github repo I created for it. Who knows, maybe it will mutate into a File Search API to Rival “BCFile”, but for .NET.

Posted By: BC_Programming
Last Edit: 21 May 2015 @ 11:02 PM

EmailPermalinkComments (0)
Tags
Tags: , ,
Categories: C#, Programming
 05 Dec 2012 @ 3:07 AM 

Formatting Data Sizes

When we present file-based data to a user, it is often unavoidable to show those byte sizes to the user. While you could get away with a formatted display of the number of bytes, for large files, this loses quite a bit of meaning. Instead, the ideal would be to format it to a prefix, selected based on the actual size.

In order to implement this functionality, let’s create a “ByteSizeFormatter” class. We’ll make it static, and add some string arrays for both the standard as well as the ISO suffixes:

Why use an array? Well, now we can get the appropriate element to use from a given byte size with a bit of math:

And students complain that they’ll never use logarithms in real life. If they became programmers they probably would have implemented the above like this:

TSSK! I say to that. Anyway, the idea here is to get the index of the prefix that, when applied, will give a number above zero but less than 1024; obviously, the idea is to use this routine within another:

[code]
public static String FormatSize(long amount,int numdecimalplaces=2,bool useISO=false)
{
String[] usesuffixes = useISO ? isobytesuffixes : stdbytesuffixes;
int gotindex = getbyteprefixindex(amount);
double calcamount = amount;
calcamount = calcamount / (Math.Pow(1024, gotindex));
return calcamount.ToString(“F” + numdecimalplaces.ToString(CultureInfo.InvariantCulture),
CultureInfo.CurrentCulture) + ” ” + usesuffixes[gotindex];

}
[/code]

FormatSize() formats a given byte amount into an “optimal” value with an appropriate prefix. It does this by generating the appropriate format string to pass to the ToString() method based on the passed number of decimal places.

What else?

So we have a method for formatting a single size. However, we might want to format several sizes with the same “format”; that is, we might want to format a set of values but have them all “comparable” to each other at a glance; 512K can look larger than 3MB at a quick glance, and it is a lot easier to judge and compare file sizes when the values are something you can compare. The first step is a helper method that accepts a calculated index:

“But WAAAIT!” I here you screaming- “That’s duplicating code!” Of course it is- that’s why we can replace the FormatSize() method with a delegated call to this one, like so:

Then, we can use that to create the imagined method from before:

Tada! The capability of Linq is very helpful here since it helps us make the code only three statements, whereas it might normally take more for various loops. This particular implementation is also an enumerator method, simply because it doesn’t strictly require anything specific to arrays.

To finish off- the full source of this class as it appears in my BASeCamp.Updating library:

Posted By: BC_Programming
Last Edit: 05 Dec 2012 @ 03:08 AM

EmailPermalinkComments (0)
Tags
Tags: , , ,
Categories: .NET, C#

 Last 50 Posts
 Back
Change Theme...
  • Users » 43733
  • Posts/Pages » 364
  • Comments » 106
Change Theme...
  • VoidVoid « Default
  • LifeLife
  • EarthEarth
  • WindWind
  • WaterWater
  • FireFire
  • LightLight

PP



    No Child Pages.

Windows optimization tips



    No Child Pages.

Software Picks



    No Child Pages.

BC’s Todo List



    No Child Pages.