Amazon.com Widgets WilliaBlog.Net | I dream in code

WilliaBlog.Net

I dream in code

About the author

Robert Williams is an internet application developer for the Salem Web Network.
E-mail me Send mail
Go Daddy Deal of the Week: 30% off your order at GoDaddy.com! Offer expires 11/6/12

Recent comments

Archive

Authors

Tags

Code Project Associate Logo

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.


Printable HBO Game of Thrones Viewer's Guide

Like many people, after thoroughly enjoying the first season of Game of Thrones on HBO, my wife and I started reading the books. Even with the show fresh in our minds, we found ourselves getting confused Jory/Jorah, Tyrion/Tywin so we went online looking for a nice cheat sheet. If you haven't already been there, take a look at the official HBO viewer's guide. It's presented beautifully, and easy to follow. As a web developer, I can appreciate the hard work that went into this great site.

However, thinking that we didn't want to keep going online to check every time we needed to, we thought it would be great to print it all out. What a mistake that was. All formatting is gone, and this is the result:

With the layout all messed up, the printed pages are useless!

So, with a little help from FireBug for Firefox and Adobe Photoshop, I have created a nice printable version of the site:

Download it here in Adobe PDF Format:

HBO Game of Thrones Guide to Houses.pdf (2.27 mb)

http://www.entertainmentearth.com/pjdoorway.asp?source=pjn&subid={subid}&url=hitlist.asp?theme=Game+of+Thrones


Posted by Williarob on Monday, July 25, 2011 2:10 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Moving Files in Visual Studio and SVN

I'm writing this down because (1) I've had to figure it out a few times already and don't want to figure it out again, and (2) it may save you some snortin' and cussin' if you run across it yourself. It is astonishingly annoying.

If you have an MVC 3 project in Visual Studio 2010 and while refactoring you move a file - for example you move a view model to the shared area, you may suddenly encounter a compile error in some random temporary file like the one below:

The type or namespace name 'xxx' does not exist in the namespace 'xxx' (are you missing an assembly reference?)    c:\Users\[user name]\AppData\Local\Temp\Temporary ASP.NET Files\temp\eab6c63b\948de17e\App_Web_hadnllup.0.cs

Cleaning the solution and/or deleting the temporary files will not resolve the problem. This can happen whether you simply drag and drop the file to the new location, then change the namespace yourself, or if you right click on the file and choose Refactor > Move and have Visual Studio move the file and update the namespaces for you. The latter process (in theory) will update all references to the file within your project automatically, while with the former, you would typically try to compile the project and then fix all the broken items that now appear in the Error list as a result of the namespace change. However, unless you do a global find and replace, you will probably still end up getting the cryptic error above because chances are that the @model declaration in one or more of your Views is still pointing to the old namespace for that viewmodel file. Update the view(s) and the error will go away and all will be fine.

Now, if you use SVN, things are a little more complicated: If you move the file using either of the techniques described above, what will happen is SVN will delete the original file and create a new one for the new location, which is fine, unless you were hoping to preserve the full subversion history of that file. If you want to preserve the file history in SVN and move the file, this is how you do it: in Windows Explorer, right-click and drag the file from its old location to its new location, then select "SVN move versioned item" from the context menu. This will not only move the actual file itself, but it will also make sure that all the file history stays with it after you check in your changes. Back in Visual Studio, use the Solution Explorer in VS2010 to "exclude from project" the (now-missing) copy of the file in its old location, and then "include in project" the file in its new location. You may need to refresh the view in solution explorer and/or make sure you are viewing all the files by clicking the "Show all Files" icon at the top (next to the refresh icon) in order to see these files.

After you update the namespace to reflect the new location, I recommend using a global find and replace before you try to compile to save yourself a lot of trouble.

To summarize, if you find yourself getting obsolete, broken references in auto-generated files that you can't permanently delete, look in your Views folder for the bad references.


Posted by Williarob on Wednesday, May 25, 2011 7:33 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Firefox 4 doesn't save tabs

Problem: I've downloaded Firefox 4 and now I am no longer able to save my tabs. How can I fix that?

Solution: By default this function has been disabled. To enable it, do the following:

1. In the address line, type in "about:config" (without quotation marks). Click on "I'll be careful, I promise!"

2. In the filter field, type in browser.showQuitWarning. This should filter out all other options

3. Double click on the option that is left in the list. The value should switch from "false" to "true".

4. Close about:config tab and it should work


Posted by Williarob on Friday, May 06, 2011 1:53 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Using System.Threading.Tasks and BlockingCollections to FTP multiple Files at the same time

I recently needed to write an application that would loop through a queue of files and FTP them to our Content Delivery Network for streaming. Users upload files, and our administrators can mark some of them as urgent. Urgent ones need to jump to the front of the queue, otherwise everything should be orderd by broadcast date. My initial code was basically a loop that looked something like this:

While (GetFtpQueue().Count > 0)
{
    // Gather all the info from the db,  Ftp the file, then clean up (move the source file, update the db, etc.

}

It worked beautifully while we were just uploading small audio files, but as soon asl we started adding a lot of video files to the queue it became so slow that it might take 2 hours or more to upload a single video file. So, we experimented with Filezilla to see how many concurrent uploads we could add before the overall speed of each upload started to drop. We found that at our location, 4 simultaneous FTP uploads seemed to hit the sweet spot: instead of uploading 1 file at 500 kb/s we could upload all four and each one would still be at that speed, quadrupling our throughput.

I read up on using the new Threading classes in .Net 4.0, and began refactoring my FTP application. I decided to use the Task Factory to manage the threads, in conjunction with a BlockingCollection to create a classic Producer/Consumer pattern. My first attempt looked a lot like this:

int maxThreads = 4;
var filesToFtp = new BlockingCollection<FtpItem>(maxThreads);
var processedFiles = new BlockingCollection<FtpItem>();

// Stage #1: Producer
var initFtp = Task.Factory.StartNew(() =>
{
    try
    {
        While (GetFtpQueue().Count > 0)
        {
            // Gather all the info from the db and use it to create FtpItem objects
            // Add them to list of filesToFtp, which only allows maxThreads in at a time (this allows us to have an urgent item jump to the top while current items are still FTPing)
            filesToFtp.Add(new FtpItem { ... };
        }
    }
    finally { filesToFtp .CompleteAdding(); }
});

// Stage #2 Consumer of initFtpTask and Producer for Cleanup Task
var process = Task.Factory.StartNew(() =>

{
    try
    {
        foreach(var file in filesToFtp.GetConsumingEnumerable()
        {
            // Ftp the file
            // Add to list of processedFiles
            processedFiles.Add(file);
        }
    }
    finally { processedFiles.CompleteAdding(); }
});

// Stage #3
var cleanup = Task.Factory.StartNew(() =>
{
    foreach(var file in processedFiles.GetConsumingEnumerable()
    {
        // Clean up (move the source file, update the db, etc.
    }
});

Task.WaitAll(initFtp, process, cleanup);

Initially, this looked quite promising. I wrote a bare bones version of it like the one above that just did thread.sleep to simulate work and iterated through a list of ints. I was ablt to verify that each "stage" was running on it's own thread, that it never allowed more than 4 items through at a time, that I could add items to the front of the queue and get them processed next, and that it never tried to 'cleanup' a file until that file had passed through both stage 1 and stage 2. However, I did notice that the elapsed time was the same as when I ran a similar unit test in a simple while loop. It might be obvious to you why this is, but at the time I put it down to a limitation of the unit test and pushed my new code to production. The first thing I noticed was that it wasn't any faster. Not even slightly. It took me hours of staring at the code to finally figure out why my multi threaded code was not running any faster, but the answer is simple: I only created one consumer of filesToFtp. I had incorrectly assumed that because I was creating up to 4 ftpItems at a time, and the ftp process was running on it's own thread, that it would consume as many as it could, but the reality is that in the code above, while each of the three stages are running on their own thread, the whole process was still happening in series, since stage 1 doesn't create 4 items at once, it creates them one after the other, stage 2 does begin working before stage 1 is complete (as soon as there is an item to consume), but then it will be busy Ftping that first item until that item is fully uploaded, only then will it grab the next file.

To resolve this problem, I simply wrapped stage 2 in a for loop, and created a IList of Tasks to wait on:

int maxThreads = 4;
var filesToFtp = new BlockingCollection<FtpItem>(maxThreads);
var processedFiles = new BlockingCollection<FtpItem>();
IList<Task> tasks = new List<Task>();

// Stage #1: Producer
tasks.Add(Task.Factory.StartNew(() =>
{
    try
    {
        While (GetFtpQueue().Count > 0)
        {
            // Gather all the info from the db and use it to create FtpItem objects
            // Add them to list of filesToFtp, which only allows maxThreads in at a time (this allows us to have an urgent item jump to the top while current items are still FTPing)
            filesToFtp.Add(new FtpItem { ... };
        }
    }
    finally { filesToFtp .CompleteAdding(); }
}));

// Start multiple instances of the ftp process
for (int i = 0; i < maxThreads; i++)
{
    // Stage #2 Consumer of initFtpTask and Producer for Cleanup Task
    tasks.Add(Task.Factory.StartNew(() =>
    {
	try
	{
		foreach(var file in filesToFtp.GetConsumingEnumerable()
		{
			// Ftp the file
			// Add to list of processedFiles
			processedFiles.Add(file);
		}
	}
	finally { processedFiles.CompleteAdding(); }
	}));
}

// Stage #3
tasks.Add(Task.Factory.StartNew(() =>
{
	foreach(var file in processedFiles.GetConsumingEnumerable()
	{
		// Clean up (move the source file, update the db, etc.
	}
}));

Task.WaitAll(tasks.ToArray());

I reran the unit test and it was faster! Very nearly 4 times faster in fact. Wahoo! I updated the code, published my changes and sat back. Sure enough, the Ftp process finally started to make up some ground. In the mean time, I went back to my unit test and began tweaking. The first thing I noticed was that sometimes I would get a "System.InvalidOperationException: The BlockingCollection<T> has been marked as complete with regards to additions." Luckily, this didn't take a lot of head scratching to figure out: the first thread to reach the 'finally' clause of  stage 2 closed the processedFiles collection, leaving the other three threads hanging. A final refactoring resolved the issue:

int maxThreads = 4;
var filesToFtp = new BlockingCollection<FtpItem>(maxThreads);
var processedFiles = new BlockingCollection<FtpItem>();
IList<Task> tasks = new List<Task>();

// maintain a seperate list of wait handles for the FTP Tasks, 
// since we need to know when they all complete in order to close the processedFiles blocking collection
IList<Task> ftpProcessTasks = new List<Task>();

// Stage #1: Producer
tasks.Add(Task.Factory.StartNew(() =>
{
	try
	{
		While (GetFtpQueue().Count > 0)
		{
			// Gather all the info from the db and use it to create FtpItem objects
			// Add them to list of filesToFtp, which only allows maxThreads in at a time (this allows us to have an urgent item jump to the top while current items are still FTPing)
			filesToFtp.Add(new FtpItem { ... };
		}
	}
	finally { filesToFtp .CompleteAdding(); }
}));

// Start multiple instances of the ftp process
for (int i = 0; i < maxThreads; i++)
{
	// Stage #2 Consumer of initFtpTask and Producer for Cleanup Task
	ftpProcessTasks.Add(Task.Factory.StartNew(() =>
	{
		try
		{
			foreach(var file in filesToFtp.GetConsumingEnumerable()
			{
				// Ftp the file
				// Add to list of processedFiles
				processedFiles.Add(file);
			}
		}
	}));
}

// Stage #3
tasks.Add(Task.Factory.StartNew(() =>
{
	foreach(var file in processedFiles.GetConsumingEnumerable()
	{
		// Clean up (move the source file, update the db, etc.
	}
}));


// When all the FTP Threads complete
Task.WaitAll(ftpProcessTasks.ToArray());

// Notify the stage #3 cleanup task that there is no need to wait, there will be no more processedFiles.
processedFiles.CompleteAdding();

// Make sure all the other tasks are complete too.
Task.WaitAll(tasks.ToArray());

Download a working example (Just enter your FTP Server details prior to running):

ProducerConsumer.zip (11.18 mb)


Posted by Williarob on Monday, April 18, 2011 11:47 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Visual Studio C# Statement Collapsing

Many seasoned developers would argue that if your method is so long, and contains so many nested blocks of code in braces that you need to be able to collapse the sections to make better sense of your code, that you should refactor that code! And of course, they are right. This can be done either by moving sections out to new methods, or perhaps inverting your if statements to reduce nesting. However, lets be honest, when you initially write something, it often starts out as a single really long method and in order to refactor it you still need to identify where each block starts and ends. And of course sometimes you have to work with code other developers wrote. Wouldn't it be nice to be able to collapse a loop, or a try catch block just by clicking on a little minus sign? True you could wrap these sections with regions, but to do that you would have to figure out where the section starts and ends to insert the region statements and by doing that you wouldn't really need them anymore. If you are working in C++ in Visual Studio, you can collapse code blocks, but this functionality is not part of the C# options. Fortunately, there is a Visual Studio 2010 extension you can install to add this functionality to C#.


Posted by Williarob on Friday, April 15, 2011 1:51 PM
Permalink | Comments (0) | Post RSSRSS comment feed

Working with Metafile Images in .Net

What is a Metafile Image?

The Windows Metafile (WMF) is a graphics file format on Microsoft Windows systems, originally designed in the 1990s.

Internally, a metafile is an array of variable-length structures called metafile records. The first records in the metafile specify general information such as the resolution of the device on which the picture was created, the dimensions of the picture, and so on. The remaining records, which constitute the bulk of any metafile, correspond to the graphics device interface (GDI) functions required to draw the picture. These records are stored in the metafile after a special metafile device context is created. This metafile device context is then used for all drawing operations required to create the picture. When the system processes a GDI function associated with a metafile DC, it converts the function into the appropriate data and stores this data in a record appended to the metafile.

After a picture is complete and the last record is stored in the metafile, you can pass the metafile to another application by:

  • Using the clipboard
  • Embedding it within another file
  • Storing it on disk
  • Playing it repeatedly

A metafile is played when its records are converted to device commands and processed by the appropriate device.

There are two types of metafiles:

I had worked with Metafiles in Visual Basic 6 many years ago, when I worked for Taltech.com, a company that strives to produce the highest quality barcode images that Windows can create. As I remember it, this involved making lots of Windows API calls, and something called "Hi Metric Map Mode" (MM_HIMETRC). "Basically, the mapping mode system enables you to equate an abstract, logical drawing surface with a concrete and constrained display surface.  This is good in principle but GDI had a major drawback inasmuch as the logical drawing area coordinates were based upon signed integers.  This meant that creating drawing systems based upon some real-world measurement system such as inches or millimeters required you to use a number of integer values to represent a single unit of measure for example, in the case of MM_LOMETRC mapping there are ten integer values to each linear millimeter and in the case of MM_LOENGLISH there are 100 integer values to each linear inch." - Bob Powell. Bob has written a great article: Comparing GDI mapping modes with GDI+ transforms for anyone wanting to learn more about this.

Bob goes on to say that "Given the fact that matrix transformations have been recognized as the only sensible method to manipulate graphics for many years, GDI mapping modes were a very limited alternative and always a bit of a kludge", and he's probably right. To be honest, all that matrix stuff went way over my head. Luckily, today, the simplicity of matrix transformations is built into GDI+, and most of those API calls have been integrated into the System.Drawing Namespaces of the .Net Framework. Having already found a way to draw a barcode as a bitmap using the .Net Framework, I wanted to see how easy it would be to create a barcode as a metafile, since bitmaps are a lossy format, and barcodes need to be as high quality as possible to ensure that the scanners read them correctly.

You might think that creating a metafile would be as easy as using the Save() Method of System.Drawing.Image and giving the file a .wmf or .emf extension, but sadly this is not the case. If you do that, what you actually get, is a Portable Network Graphics (PNG) file, with a .wmf or .emf extension. Even if you use the ImageFormat overload, and pass in the filename and ImageFormat.Emf or ImageFormat.Wmf, you still end up with a PNG. It doesn't matter whether you create a Bitmap and call Save() or you go to the trouble of creating an in memory Metafile (more on that later) and then call Save(), you will never get a true Metafile. If you visit the MSDN documentation on the Metafile Class, you can see under 'Remarks' it casually states:

When you use the Save method to save a graphic image as a Windows Metafile Format (WMF) or Enhanced Metafile Format (EMF) file, the resulting file is saved as a Portable Network Graphics (PNG) file instead. This behavior occurs because the GDI+ component of the .NET Framework does not have an encoder that you can use to save files as .wmf or .emf files.

This is confirmed in the documentation for the System.Drawing.Image.Save Method:

If no encoder exists for the file format of the image, the Portable Network Graphics (PNG) encoder is used. When you use the Save() method to save a graphic image as a Windows Metafile Format (WMF) or Enhanced Metafile Format (EMF) file, the resulting file is saved as a Portable Network Graphics (PNG) file. This behavior occurs because the GDI+ component of the .NET Framework does not have an encoder that you can use to save files as .wmf or .emf files.

Saving the image to the same file it was constructed from is not allowed and throws an exception.

In order to save your in memory metafile as a true metafile, you must make some old fashioned API calls, and I will show you how to do this in due course, but first you need to know how to create an in memory Metafile. Let's assume that, like me, you already have some code that generates a bitmap image which looks just the way you want it. Here is some sample code distilled from a nice BarCode Library project written by Brad Barnhill

        static void Main(string[] args)

        {

            int width = 300;

            int height = 100;

 

            Bitmap b = new Bitmap(width, height);

            int pos = 0;

            string encodedValue =

                "1001011011010101001101101011011001010101101001011010101001101101010100110110101010011011010110110010101011010011010101011001101010101100101011011010010101101011001101010100101101101";

            int barWidth = width / encodedValue.Length;

            int shiftAdjustment = (width % encodedValue.Length) / 2;

            int barWidthModifier = 1;

 

            using (Graphics g = Graphics.FromImage(b))

            {

                // clears the image and colors the entire background

                g.Clear(Color.White);

 

                // lines are barWidth wide so draw the appropriate color line vertically

                using (Pen pen = new Pen(Color.Black, (float)barWidth / barWidthModifier))

                {

                    while (pos < encodedValue.Length)

                    {

                        if (encodedValue[pos] == '1')

                        {

                            g.DrawLine(

                                pen,

                                new Point(pos * barWidth + shiftAdjustment + 1, 0),

                                new Point(pos * barWidth + shiftAdjustment + 1, height));

                        }

 

                        pos++;

                    } // while

                } // using

            } // using

 

            b.Save(@"d:\temp\test.png", ImageFormat.Png);

        }

As you can see, this code creates a new Bitmap image, creates a Graphics object from it, draws on it using the Pen class then saves it as a .png. The resulting image looks like this:

So far so good. As we have already established, simply rewriting the last line as

b.Save(@"d:\temp\test.emf", ImageFormat.Emf);

is not enough to convert this image to a metafile. Sadly, substituting the word "Metafile" for "Bitmap" is not all it takes to create an in memory metafile. Instead, you will need to have a device context handle and a stream handy. If you are working on a Windows Forms application you can create a Graphics object easily by simply typing Graphics g = this.CreateGraphics(); but if you are writing a class library or a console application you have to be a bit more creative and use an internal method (FromHwndInternal) to create the Graphics object out of nothing:

            Graphics offScreenBufferGraphics;

            Metafile m;

            using (MemoryStream stream = new MemoryStream())

            {

                using (offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))

                {

                    IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();

                    m = new Metafile(

                        stream,

                        deviceContextHandle,

                        EmfType.EmfPlusOnly);

                    offScreenBufferGraphics.ReleaseHdc();

                }

            }

OK, so now your code looks like this:

        static void Main(string[] args)

        {

            int width = 300;

            int height = 100;

 

            Graphics offScreenBufferGraphics;

            Metafile m;

            using (MemoryStream stream = new MemoryStream())

            {

                using (offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))

                {

                    IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();

                    m = new Metafile(

                        stream,

                        deviceContextHandle,

                        EmfType.EmfPlusOnly);

                    offScreenBufferGraphics.ReleaseHdc();

                }

            }

 

            int pos = 0;

            string encodedValue =

                "1001011011010101001101101011011001010101101001011010101001101101010100110110101010011011010110110010101011010011010101011001101010101100101011011010010101101011001101010100101101101";

            int barWidth = width / encodedValue.Length;

            int shiftAdjustment = (width % encodedValue.Length) / 2;

            int barWidthModifier = 1;

 

            using (Graphics g = Graphics.FromImage(m))

            {

                // clears the image and colors the entire background

                g.Clear(Color.White);

 

                // lines are barWidth wide so draw the appropriate color line vertically

                using (Pen pen = new Pen(Color.Black, (float)barWidth / barWidthModifier))

                {

                    while (pos < encodedValue.Length)

                    {

                        if (encodedValue[pos] == '1')

                        {

                            g.DrawLine(

                                pen,

                                new Point(pos * barWidth + shiftAdjustment + 1, 0),

                                new Point(pos * barWidth + shiftAdjustment + 1, height));

                        }

 

                        pos++;

                    } // while

                } // using

            } // using

 

            m.Save(@"d:\temp\test2.png", ImageFormat.Png);

         }

But wait, what happened to my barcode? It's all off center, yet the code used to draw it hasn't changed:

Luckily this is easy to fix. We need to use a different overload when creating the metafile, so that we can specify a width and height, and a unit of measure:

            Graphics offScreenBufferGraphics;

            Metafile m;

            using (MemoryStream stream = new MemoryStream())

            {

                using (offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))

                {

                    IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();

                    m = new Metafile(

                        stream,

                        deviceContextHandle,

                        new RectangleF(0, 0, width, height),

                        MetafileFrameUnit.Pixel,

                        EmfType.EmfPlusOnly);

                    offScreenBufferGraphics.ReleaseHdc();

                }

            }

 

Now it looks the same when saved as a .png, but it may still look all wrong (and more importantly be completely unreadable by a barcode scanner) if printed and the resolution of the printer does not match that of your desktop when you created the metafile. Furthermore, if I save this as a real EMF file and email it to you, when you view it you may see a different rendering, because the desktop I created it on has a resolution of 1920x1080, but if your desktop has a higher or lower resolution it will affect how it is displayed. Remember a metafile is a stored set of instructions on how to render the image and by default it will use the stored resolution for reference. To correct this, we have to add some additional code to the Graphics object to ensure this doesn't happen (thanks go to Nicholas Piasecki and his blog entry for pointing this out):

 

                MetafileHeader metafileHeader = m.GetMetafileHeader();

                g.ScaleTransform(metafileHeader.DpiX / g.DpiX, metafileHeader.DpiY / g.DpiY);

                g.PageUnit = GraphicsUnit.Pixel;

                g.SetClip(new RectangleF(0, 0, width, height));

So how can we save it as a real Metafile anyway?

Well, first we need to declare some old fashioned Win API calls:

        [DllImport("gdi32.dll")]

        static extern IntPtr CopyEnhMetaFile(  // Copy EMF to file

            IntPtr hemfSrc,   // Handle to EMF

            String lpszFile // File

        );

 

        [DllImport("gdi32.dll")]

        static extern int DeleteEnhMetaFile(  // Delete EMF

            IntPtr hemf // Handle to EMF

        );

Then we can replace the m.Save(...); line with this:

            // Get a handle to the metafile

            IntPtr iptrMetafileHandle = m.GetHenhmetafile();

 

            // Export metafile to an image file

            CopyEnhMetaFile(iptrMetafileHandle, @"d:\temp\test2.emf");

 

            // Delete the metafile from memory

            DeleteEnhMetaFile(iptrMetafileHandle);

and finally we have a true metafile to share. Why Microsoft failed to encapsulate this functionality within the framework as an image encoder is a mystery. Windows Metafiles, and Enhanced Metafiles are after all their own creation. So our final version of the code looks like this:

        static void Main(string[] args)

        {

            int width = 300;

            int height = 100;

 

            Graphics offScreenBufferGraphics;

            Metafile m;

            using (MemoryStream stream = new MemoryStream())

            {

                using (offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))

                {

                    IntPtr deviceContextHandle = offScreenBufferGraphics.GetHdc();

                    m = new Metafile(

                        stream,

                        deviceContextHandle,

                        new RectangleF(0, 0, width, height),

                        MetafileFrameUnit.Pixel,

                        EmfType.EmfPlusOnly);

                    offScreenBufferGraphics.ReleaseHdc();

                }

            }

 

            int pos = 0;

            string encodedValue =

                "1001011011010101001101101011011001010101101001011010101001101101010100110110101010011011010110110010101011010011010101011001101010101100101011011010010101101011001101010100101101101";

            int barWidth = width / encodedValue.Length;

            int shiftAdjustment = (width % encodedValue.Length) / 2;

            int barWidthModifier = 1;

 

            using (Graphics g = Graphics.FromImage(m))

            {

                // Set everything to high quality

                g.SmoothingMode = SmoothingMode.HighQuality;

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                g.CompositingQuality = CompositingQuality.HighQuality;

 

                MetafileHeader metafileHeader = m.GetMetafileHeader();

                g.ScaleTransform(

                    metafileHeader.DpiX / g.DpiX,

                    metafileHeader.DpiY / g.DpiY);

 

                g.PageUnit = GraphicsUnit.Pixel;

                g.SetClip(new RectangleF(0, 0, width, height));

 

                // clears the image and colors the entire background

                g.Clear(Color.White);

 

                // lines are barWidth wide so draw the appropriate color line vertically

                using (Pen pen = new Pen(Color.Black, (float)barWidth / barWidthModifier))

                {

                    while (pos < encodedValue.Length)

                    {

                        if (encodedValue[pos] == '1')

                        {

                            g.DrawLine(

                                pen,

                                new Point(pos * barWidth + shiftAdjustment + 1, 0),

                                new Point(pos * barWidth + shiftAdjustment + 1, height));

                        }

 

                        pos++;

                    } // while

                } // using

            } // using

 

            // Get a handle to the metafile

            IntPtr iptrMetafileHandle = m.GetHenhmetafile();

 

            // Export metafile to an image file

            CopyEnhMetaFile(iptrMetafileHandle, @"d:\temp\test2.emf");

 

            // Delete the metafile from memory

            DeleteEnhMetaFile(iptrMetafileHandle);

        }

There is one more Metafile Gotcha I'd like to share. As part of my original Bitmap generating code, I had a boolean option to generate a label, that is the human readable text that appears beneath the barcode. If this option was selected, before returning the bitmap object I would pass it to another method that looked something like this:

        static Image DrawLabel(Image img, int width, int height)

        {

            Font font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold); ;

 

            using (Graphics g = Graphics.FromImage(img))

            {

                g.DrawImage(img, 0, 0);

                g.SmoothingMode = SmoothingMode.HighQuality;

                g.InterpolationMode = InterpolationMode.HighQualityBicubic;

                g.PixelOffsetMode = PixelOffsetMode.HighQuality;

                g.CompositingQuality = CompositingQuality.HighQuality;

 

                StringFormat f = new StringFormat();

                f.Alignment = StringAlignment.Center;

                f.LineAlignment = StringAlignment.Near;

                int LabelX = width / 2;

                int LabelY = height - font.Height;

 

                //color a background color box at the bottom of the barcode to hold the string of data

                g.FillRectangle(new SolidBrush(Color.White), new RectangleF((float)0, (float)LabelY, (float)width, (float)font.Height));

 

                //draw datastring under the barcode image

                g.DrawString("038000356216", font, new SolidBrush(Color.Black), new RectangleF((float)0, (float)LabelY, (float)width, (float)font.Height), f);

 

                g.Save();

            }

 

            return img;

        }

When passing the bitmap, this works great, but when passing the metafile, the line using (Graphics g = Graphics.FromImage(img)) would throw a System.OutOfMemoryException every time. As a workaround, I copied the label generating code into the main method that creates the barcode. Another option might be to create a new metafile (not by calling m.Clone() - I tried that and still got the out of memory exception), send that to the DrawLabel() method, then when it comes back, create a third Metafile, and call g.DrawImage() twice (once for each metafile that isn't still blank) and return this new composited image. I think that will work, but I also think it would use a lot more resources and be grossly inefficient, so I think copying the label code into both the DrawBitmap() and DrawMetafile() methods, is a better solution.


Categories: C# | CodeProject | Windows
Posted by Williarob on Monday, April 04, 2011 6:51 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Prevent Skype calls from adjusting the volume of other applications

Problem

You are listening to music and receive a skype call. You pause the music, take the call and after you hang up you restart your music only to find that the volume has been turned way down and only closing the app (be it Winamp, Windows Media Player, Media Player Classic, etc,) and restarting it can the volume be restored.

Solution

Control Panel > Sound > Communications > Select "Do Nothing"

 

By default, Windows 7 will automatically reduce the volume of other applications by 80% when a skype (or other) call is detected, but it often fails to restore the volume when the call is completed.


Posted by Williarob on Tuesday, December 14, 2010 12:22 PM
Permalink | Comments (0) | Post RSSRSS comment feed

JQuery Code only working correctly when Firebug is open

If you ever come across a situation where a page on your site is not working as it should, but when you open Firebug to see what is happening it all works fine, chances are that somewhere in your Javascript/JQuery code there is a console.log() statement. If Firebug is not open, console will be undefined and the rest of the scripts may not run. In my case, the problem was reported that clicking the save button on an html form resulted in the Json results prompting “Save As” dialog like the one below, instead of being processed:

 

Json results prompting “Save As” dialog in browser instead of being processed

Naturally, I spent most of the afternoon looking into why JSON results might prompt you with a Save As Dialog in an MVC application, and none of the reported fixes was working. I opened Firebug to look at some html and noticed that suddenly the page looked different - there was a lot more formatting, and it just looked like this was how the page was supposed to look. Not only that, but with Firebug open, the Save button correctly used Ajax to submit the form and the Save as Dialog didn't popup. So I closed Firebug and refreshed the page. Broken Again. Luckily for me, a collegue had recently had the same problem last week, and pointed out that a console.log statement had been responsible. There were no console.log statements on the page in question, but a global Find operation located one on the master page. Commenting it out made everything work as it was supposed to.

The moral of the story is that if you use console.log statements while debugging, make sure you remove them all when you are done, or better yet, create a global Javascript function that you can call from anywhere which first ensures that console is not undefined. Something like this should work:

    function debug(text) {
        if ((typeof(Debug) !== 'undefined') && Debug.writeln) {
            Debug.writeln(text);
        }
        if (window.console && window.console.log) {
            window.console.log(text);
        }
        if (window.opera) {
            window.opera.postError(text);
        }
        if (window.debugService) {
            window.debugService.trace(text);
        }
    }


Categories: JavaScript | JQuery
Posted by Williarob on Monday, November 01, 2010 6:20 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Checking for a Running Instance

Sometimes you may not want a user to launch multiple instances of your program, or you may have a processor or I/O intensive scheduled task that runs every few minutes and you want to make sure that if it is started again before the last instance has finished it simply exits immediately. One way to check to see if your program is already running is to look at the list of running processes:

 

namespace RunningInstance

{

    using System;

    using System.Diagnostics;

    using System.Reflection;

 

    class Program

    {

        static void Main(string[] args)

        {

            if (RunningInstance())

            {

                Console.WriteLine("Another instance of this process was already running, exiting...");

                return;

            }

 

            // ...

        }

 

        static bool RunningInstance()

        {

            Process current = Process.GetCurrentProcess();

            Process[] processes = Process.GetProcessesByName(current.ProcessName);

 

            // Loop through the running processes in with the same name

            foreach (Process p in processes)

            {

                // Ignore the current process

                if (p.Id != current.Id)

                {

                    // Make sure that the process is running from the exe file.

                    if (Assembly.GetExecutingAssembly().Location.Replace("/", @"\") == current.MainModule.FileName)

                    {

                        return true;

                    }

                }

            }

 

            return false;

        }

    }

}

 

However, suppose you have a multi function console application that accepts a dozen different command line arguments to perform different jobs, all of which run as separate scheduled tasks at overlapping intervals. If this is the case, then checking the list of running processes may well find your executable already running, but have no idea which command line argument was used to start it. I tried adding:

 

Console.WriteLine("Instance started with args: '{0}'", p.StartInfo.Arguments);

above the "return true" statement in RunningInstance() but it will not print the command line args used to start it. Lets suppose we add 2 classes to our project. Task1 and Task2. For the sake of simplicity, they both look something like this:

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task1

    { 

        public void Start()

        {

            Console.WriteLine("Starting Task 1");

        }

    }

}

 

Task 2 is exactly the same, except it prints "Starting Task 2". If we keep our RunningInstance check in place Main() now looks like this:

 

        static void Main(string[] args)

        {

            if (RunningInstance())

            {

                Console.WriteLine("An instance of this application is already running. Exiting.");

                Console.ReadLine();

                return;

            }

 

            if(args.Length < 1)

            {

                Console.WriteLine("Unrecognized Command.");

                return;

            }

 

            switch (args[0])

            {

                case "-task1":

                    var t1 = new Task1();

                    t1.Start();

                    break;

                case "-task2":

                    var t2 = new Task2();

                    t2.Start();

                    break;

                default:

                    Console.WriteLine("Unrecognized Command.");

                    break;

            }

        }

Task 2 will not run, if task 1 is still running, and vice versa. However, suppose the two tasks are completely unrelated. The first is only a minor chore, that simply counts the number of items marked as "queued" in a database table and sends out an email if the number is too high, while task 2 is much lengthier process that FTPs files. We may need both of these tasks to run as scheduled, but not want multiple instances of either task to run at the same time. How can we achive this? We use a Mutex. Mutex is an abbreviation of "Mutual exclusion" and is traditionally used in multi threaded applications to avoid the simultaneous use of a common resource, such as a global variable. After adding a mutex to each task, our final code looks like this:


        static void Main(string[] args)

        { 

            if(args.Length < 1)

            {

                Console.WriteLine("Unrecognized Command.");

                return;

            }

 

            switch (args[0])

            {

                case "-task1":

                    var t1 = new Task1();

                    t1.Start();

                    break;

                case "-task2":

                    var t2 = new Task2();

                    t2.Start();

                    break;

                default:

                    Console.WriteLine("Unrecognized Command.");

                    break;

            }

        }

 

 

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task1

    {

        /// <summary>Gets the mutex that prevents multiple instances of this code running at once.</summary>

        private static Mutex mutex1;

 

        public void Start()

        {

            bool createdNew;

            mutex1 = new Mutex(true, "RunningInstance.Task1", out createdNew);

            if (!createdNew)

            {

                // Instance already running; exit.

                Console.WriteLine("Exiting: Instance already running");

                return;

            }

 

            Console.WriteLine("Starting Task 1");

        }

    }

}

 

 

namespace RunningInstance

{

    using System;

    using System.Threading;

 

    public class Task2

    {

        /// <summary>Gets the mutex that prevents multiple instances of this code running at once.</summary>

        private static Mutex mutex1;

 

        public void Start()

        {

            bool createdNew;

            mutex1 = new Mutex(true, "RunningInstance.Task2", out createdNew);

            if (!createdNew)

            {

                // Instance already running; exit.

                Console.WriteLine("Exiting: Instance already running");

                return;

            }

            Console.WriteLine("Starting Task 2");

        }

    }

}

 

Each Task has its own Mutex, uniquely named. If the mutex already exists, then that code must already be running, so exit, otherwise, run. Couldn't be simpler. By using this particular overload of the constructor, we don't even need to worry about releasing the mutex at the end of the program.

Categories: C# | CodeProject
Posted by Williarob on Monday, October 04, 2010 5:57 AM
Permalink | Comments (0) | Post RSSRSS comment feed

Random Sample Data Generator

I recently found myself testing a webservice which required simple registration data - Name, Address, City, State, Zip/Postal Code, Phone, Email, etc. Real world testing requires navigating to the appropriate page on our site, selecting a product and completing the registration form. I don't know about you, but I'm pretty lazy when it comes to testing like this. I soon find myself entering the same test data every time, and before long end up typing gibberish like "ASDF" and "QWERTY" to speed things along. Anyone who has tested like this before, will understand the limitations to this approach and how it leads to major bugs slipping through the net. So naturally, I soon found myself writing some unit tests to do the heavy lifting for me. This is an MVC Site, so writing the unit tests was a breeze, but the sample data remained a problem. How could I produce data that would be different every time, but not be gibberish, and really look like real world data?

Well one approach would be to pull real data from our database and recycle it. Such practices, however, can violate a number of data privacy regulations. For example, the 1996 Health Insurance Portability and Accountability Act (HIPAA) mandates companies restrict access to people’s personal health data on a “need to know” basis. Likewise, the Sarbanes-Oxley Act of 2002 requires companies to control access and track changes to systems handling corporate financial information. In addition, over 30 states have passed data breach notification laws requiring companies to notify consumers if their personal information may have been compromised. This includes such things as a person’s name and address, date of birth, social security number, and credit card and bank account numbers. (Mathew Schwartz - The Dangers of Testing with Real Data).

So, the problem then, is how can you get your hands on quality sample data that won't violate privacy regulations? After looking at an Excel Add-in with similar intent, I chose to write a Random Sample Data Generator in C#. The first thing I did was create an XML File full of real first names taken from a list found here. Then I added a list of real last names found on the US Census site. Next I found a list of fake company names and added that. Our database already had a list of countries and states, so I pulled those in too. I created a list of popular street names (Elm, Main, First, Second, Walnut, etc.) and street name suffixes like Road, Street, Blvd., etc. I found a list of common city names somewhere and added that too, as well as name prefixes (Mr., Mrs, Dr., etc) and suffixes (III, Jr., Sr., etc.). Finally, in order to create credible email addresses, I took the fake company name list and turned them into possible domain names. Numeric data such as zip codes and phone numbers is easy to generate, no need to list those unless you must have real zip codes and real area codes. Currently, zip codes and phone numbers are just random digits, but if you wanted to extend it to use real area codes and real zip codes you could add them to the xml file, and write new methods to generate them. Obviously, a little more complex code would be required to pull a matching state, zip code and area code.

All that remained was to write some C# code that could randomly pull data from the lists now stored in my xml file, and here it is:

namespace DataGenerator

{

    using System;

    using System.IO;

    using System.Linq;

    using System.Reflection;

    using System.Text;

    using System.Xml;

    using System.Xml.Linq;

 

    using Extensions;

 

    public static class Generate

    {

        private static readonly XDocument dataDocument;

 

        static Generate()

        {

            if (null == dataDocument)

            {

                using (Stream datafileStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DataGenerator.Data.xml"))

                {

                    if (datafileStream != null)

                    {

                        XmlTextReader xmlReader = new XmlTextReader(datafileStream);

                        dataDocument = XDocument.Load(xmlReader);

                    }

                }

            }

        }

 

        /// <summary>

        /// Random Number Generator

        /// </summary>

        /// <param name="min"></param>

        /// <param name="max"></param>

        /// <example>int myInt = GetRandomInt(5, 1000); // gives in random integer between 5 and 1000</example>

        public static int RandomInt(int min, int max)

        {

            Random rnd = new Random();

            return rnd.Next(min, max);

        }

 

        /// <summary>

        /// Returns a string representing a common name prefix, e.g. Mr., Mrs., Dr., etc.

        /// </summary>

        public static string RandomNamePrefix()

        {

            var randomPrefix = dataDocument.Descendants("data").Descendants("prefixes").Descendants("prefix").ToList().RandomItem(new Random());

            return randomPrefix.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons last name, randomly selected from actual first names.

        /// </summary>

        public static string RandomFirstName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("names").Descendants("first").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons last name, randomly selected from actual last names.

        /// </summary>

        public static string RandomLastName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("names").Descendants("last").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a persons full name, randomly selected from actual first and last names

        /// </summary>

        public static string RandomFullName()

        {

            return string.Format("{0} {1}", RandomFirstName(), RandomLastName());

        }

 

        /// <summary>

        /// Returns a string representing a common name suffix, e.g. III, Jr., M.D., etc.

        /// </summary>

        public static string RandomNameSuffix()

        {

            var randomSuffix = dataDocument.Descendants("data").Descendants("suffixes").Descendants("suffix").ToList().RandomItem(new Random());

            return randomSuffix.Value;

        }

 

        /// <summary>

        /// Returns a random company name based on a list of fake company names

        /// </summary>

        public static string RandomCompanyName()

        {

            var randomName = dataDocument.Descendants("data").Descendants("companies").Descendants("company").Descendants("name").ToList().RandomItem(new Random());

            return randomName.Value;

        }

 

        /// <summary>

        /// Returns a string representing a street address, e.g. 123 First Ave.

        /// </summary>

        public static string RandomStreetAddress()

        {

            var randomStreet = dataDocument.Descendants("data").Descendants("addresses").Descendants("streetNames").Descendants("streetName").ToList().RandomItem(new Random());

            var randomStreetSuffix = dataDocument.Descendants("data").Descendants("addresses").Descendants("streetSuffixes").Descendants("streetSuffix").ToList().RandomItem(new Random());

            return string.Format("{0} {1} {2}", RandomInt(1, 1999), randomStreet.Value, randomStreetSuffix.Value);

        }

 

        /// <summary>

        /// Returns a random name that could be a city

        /// </summary>

        public static string RandomCity()

        {

            var randomCity = dataDocument.Descendants("data").Descendants("cities").Descendants("city").Descendants("name").ToList().RandomItem(new Random());

            return randomCity.Value;

        }

 

        /// <summary>

        /// Returns a real US/Canadian State name at random, e.g Texas

        /// </summary>

        public static string RandomStateName()

        {

            var randomState = dataDocument.Descendants("data").Descendants("states").Descendants("state").Descendants("name").ToList().RandomItem(new Random());

            return randomState.Value;

        }

 

        /// <summary>

        /// Returns a real US/Canadian State code at random, e.g TX

        /// </summary>

        public static string RandomStateCode()

        {

            var randomState = dataDocument.Descendants("data").Descendants("states").Descendants("state").Descendants("code").ToList().RandomItem(new Random());

            return randomState.Value;

        }

 

        /// <summary>

        /// Returns a Random 5 digits between 11111 and 99999 to use for a zip code

        /// </summary>

        /// <remarks>Unlikely to produce many real zipcodes that the postoffice would recognize</remarks>

        public static string RandomZipCode()

        {

            return RandomInt(11111, 99999).ToString();

        }

 

        /// <summary>

        /// Returns a real country name at random

        /// </summary>

        public static string RandomCountry()

        {

            var randomCountry = dataDocument.Descendants("data").Descendants("countries").Descendants("country").Descendants("name").ToList().RandomItem(new Random());

            return randomCountry.Value;

        }

 

        /// <summary>

        /// Returns a real looking email address

        /// </summary>

        public static string RandomEmailAddress()

        {

            var randomDomain = dataDocument.Descendants("data").Descendants("domainNames").Descendants("domainName").ToList().RandomItem(new Random());

            var randomDomainSuffix = dataDocument.Descendants("data").Descendants("domainNameSuffixes").Descendants("suffix").ToList().RandomItem(new Random());

            return string.Format("{0}.{1}@{2}.{3}", RandomFirstName(), RandomLastName(), randomDomain.Value, randomDomainSuffix.Value);

        }

 

        /// <summary>

        /// Returns a 10 digit phone number in the format (###) ###-####

        /// </summary>

        /// <remarks>Area codes are unlikely to be real</remarks>

        public static string RandomPhone()

        {

            StringBuilder phone = new StringBuilder();

 

            // Lets generate 10 numbers

            while (phone.Length < 10)

            {

                int next = RandomInt(1, 999);

                phone.Append(next.ToString());

            }

 

            return String.Format("{0:(###) ###-####}", Convert.ToInt64(phone.ToString().Substring(0, 10)));

        }

    }

}

I chose to embed the xml file as a resource within the dll, simply because that way we never need to worry about pathing issues. I used an Extension method I found here to randomly select an XML node:

namespace DataGenerator.Extensions

{

    using System;

    using System.Collections.Generic;

 

    public static class IEnumerableExtensions

    {

        public static T RandomItem<T>(this List<T> list, Random rg)

        {

            if (list == null)

            {

                throw new ArgumentNullException("list");

            }

 

            if (rg == null)

            {

                throw new ArgumentNullException("rg");

            }

 

            int index = rg.Next(list.Count);

            return list[index];

        }

    }

}

Using the class couldn't be easier:

            Console.WriteLine(DataGenerator.Generate.RandomFullName());

            Console.WriteLine(DataGenerator.Generate.RandomStreetAddress());

            Console.WriteLine(DataGenerator.Generate.RandomCity());

            Console.WriteLine(DataGenerator.Generate.RandomStateCode());

            Console.WriteLine(DataGenerator.Generate.RandomZipCode());

            Console.WriteLine(DataGenerator.Generate.RandomCountry());

            Console.WriteLine(DataGenerator.Generate.RandomPhone());

 

Download the full source project (Visual Studio 2010, C# 4.0):

DataGenerator.zip (219.40 kb)


Posted by on Friday, July 30, 2010 5:40 AM
Permalink | Comments (0) | Post RSSRSS comment feed