Category Archives: Uncategorized

Using, IDisposable and Such

I was messing with a PDF generating class (PDFSharp, an excellent free .NET PDF Toolkit for creating PDF’s) and had to create a class that will load up some images (logos, watermarks, etc.) and then use those for the PDF. The problem is that these type objects are GDI+ type objects and are unmanaged objects. This became a problem because the logos I created during the PDF generation would remain in an opended state by the PDF generation class. This prevented me from deleting the logo file and just really pissed me off.

So IDisposable to the rescue. This allows me to manually manage the disposal of the unmanaged objects and then I could implement the PDF generation class in a using and viola! I was able to delete the image file with no issues.

Here and Here are a couple of great websites with notes and hints about implementing the IDisposable interface in C#. 

The only part that got me is the Finalizer and realizing that the Finalizer is called when the object is destructed by the GC. This is not safe to assume this is at the same time that the object is being disposed (end of a Using statement). So that is why some of the examples you find will have a Dispose(false) to a Dispose method. This prevents the managed objects from being collected in the destructor as the order is unpredictable. If that makes sense to you, great!

Here is a very simple class implementing the IDisposable interface;

[code:c#]
public class PDFMaker : IDisposable 
{
    // some fields that require cleanup
    private SafeHandle handle;
    // this is the Handle to the GDI+ object     
    private bool disposed = false; 
    // to detect redundant calls      
    public PDFMaker()     
    {         
        this.handle = /*…*/;
        // Cheezy example     
    }
    public void MakePDF()  
    {   
        // Do something cool here and make a PDF    
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                if (handle != null)
                    handle.Dispose();
            }
            disposed = true;
        }
    }
    public void Dispose()
    {
        Dispose(true);
    }
}
[/code]

Enjoy!

A GUID of by any other name?

I was mokeying around today with GUID's and had a time with the durn things returning '00000000-0000-0000-0000-000000000000' as the GUID value.

The code I was using was;

[code:c#]Guid g = new Guid();[/code]

Then that would create a new Guid and set its value to '00000000-0000-0000-0000-000000000000'. Blah.

So instead I find this;

[code:c#]Guid g = Guid.NewGuid();[/code]

This generates a proper Guid value (was '1b6d4d3c-0e6e-4967-a389-281c4fb435d3' in this case).

Geez. You figure that would do what you want, someone smarter than I am about Guid's can leave a comment to clear up the mystery.

Enjoy!

 

Subversion (svn) MonoDevelop on Ubuntu Hardy Heron (8.04.1)

So I tried to get the MonoDevelop release in Subversion to work with Ubuntu Hardy Heron (8.04.1) and had a heck of a time getting it to work.

Finally after much chatting on the IRC channel I did these steps;

  1. Setup badgerports as a repository
  2. Do the the 'ol 'sudo aptitude update && aptitude upgrade' 
  3. Run this; 'sudo apt-get install build-essential mono-mcs mono-gmcs mon-devel libmono-dev lipango1.0-dev libgtk2.0-dev libgtksourceview2.0-cil libgecko2.0-cil monodoc libmono-system-runtime2.0-cil gettext'
  4. Ensure you have 1.9 mono-gmcs installed; 'gmcs –version'
  5. Ensure you have 1.9 mono installed; 'mono –version'
  6. Follow the Subversion setup on the Monodevelop website, all should work now

Enjoy!

 

VirtualBox Clone Not Booting Windows XP

I was playing around with the new 1.6.2 Sun branded VirtualBox and thought I would clone one of my existing VDI's to a new one and then setup a new VM to use that VDI to play with.

So the first thing I did was clone the VDI using the cmd tool that comes with VirtualBox:


C:\Program Files\Sun\xVM VirtualBox\VBoxManage.exe C:\users\steven\.virtualbox\vdi\foo.vdi C:\users\steven\.virtualbox\vdi\bar.vdi

Nifty. Worked like a charm. Then you just go into the VirtualBox Virtual Disk Manager and add the newly cloned bar.vdi and then setup a new VM as usual to use that VDI.

But then of course it didnt want to boot Windows, just a series of lovely BSOD and reboots. Joy.

I trolled around on the forums and found that Innotek (or I guess Sun now) changed the default IDE controller from  PIIX3 to PIIX4 and this change seems to make Windows XP very unhappy. Go into the VM under the Advanced tab change from 'PIIX4' to 'PIIX3'. Now it boots. 

My only real compliant with VirtualBox is, well ok my only two complaints are; 1. Virtual Networking is a real PITA and 2. Why not have a UI for all the awesome options found in the
VBoxManager.exe utility. Ah hell the price is awesome, and I get great
USB support (boo! no USB device support for Virtual PC) and I dont have to download a 125MB download and register (boo! VMWARE).

Enjoy!

Simple Char

Ok so I evidently am not the sharpest knife in the drawer. I was trying to figure out how in the heck you set create and set a char variable.

Example:

[code:c#]char c = new char("s".ToCharArray[0]);[/code]

Yea I know now its as simple as using the single tick to specify the char literal;

[code:c#]char c = new char('s');[/code]

Good grief. Ah well, live and learn.

Reading Gmail with Sup

I wanted a simple mail client that would handle all the mail I receive from various accounts and ran across Sup. Impressivly simple and very nicely done in a console application.

Here are the steps I took to get Sup both reading mail in my Gmail account and sending mail out via my Gmail account on my Arch workstation;

  • Installed  Yaourt
  • Installed Ruby and Rubygems via Yaourt
    • yaourt -Sy ruby rubygems
  • Installed VI via Yaourt
    • yaourt -Sy vim vim-colorstamplerpack
  • Installed sSMTP via Yaort
    • yaourt -Sy ssmtp
  • Setup sSMTP following this Wiki Entry
  • Installed Chronic (a date parser, dependency of Sup) via the Ruby Gems tool
    • sudo gem install chronic
  • Downloaded the latest Tarball of Sup, unpacked it into /tmp and installed it via the Gems
    • sudo gem install sup -y
  • My ~/.sup/sources.yaml file looks like this;
  • 	steven ~/.sup $  cat sources.yaml
    	---
    	- !masanjin.net,2006-10-01/Redwood/IMAP
    	uri: imaps://imap.gmail.com:993
    	username: myaccount@gmail.com
    	password: mygmailpassword
    	cur_offset: 12117761440000842
    	usual: true
    	archived: false
    	id: 1
    	labels:
    	- gmail
    	- !masanjin.net,2006-10-01/Redwood/SentLoader
    	cur_offset: 555
    	- !masanjin.net,2006-10-01/Redwood/DraftLoader
    	cur_offset: 0
    	

I found this guide very helpful for Sup

Enjoy!

ps; Man does posting from this HTML interface suck rocks. Gotta get some sorta MS Live Writer going. 

Flood of log messages about USB over-current

So on my Notebook I noticed I was getting a flood of these frickin' messages;

hub 1-0:1.0: over-current change on port 1

I mean like 5 a second, over and over and … and …

Googl'ed this madness and found no good answer, so I thought I would take an extreme approach and just have Syslog-ng just not log it!

Add this to your destination collection in /etc/syslog-ng.conf;


destination nowhere { file("/dev/null"); };

Then add this to the filter section;


filter f_usb_occ { match("over-current change"); };

Then finally add this to the log section;


log { source(src); filter(f_usb_occ); destination(nowhere); flags(final); );

Restart Syslog-ng and viola! no more logging of that irrating message. woot!

Enjoy!

Not all USB Flash Drives are Bootable?

I was playing around with getting Arch Linux on my EeePC and one of the first steps is to create a bootable USB Flash drive with the Arch Core ISO put on it to boot.

Easy enough done but then I could not get the stinking EeePC to boot from the USB Flash Drive, acted like it did not even have a boot loader loaded in the MBR, curious.

So then I attempted to use another USB Flash drive and found it to work just fine, I did not change a single setting on the EeePC it just seem that the one USB Flash Drive isnt 'able' to boot.

Curioser and Curioser.

It just appears that some USB Flash Drives wont arent able to boot. The one that would not work for me I picked up at MicroCenter for like $15, one of those generic drives they have at the counter. Some details;

 

Bus 002 Device 018: ID 090c:1000 Feiya Technology Corp. Memory Bar
Device Descriptor:
bLength                18
bDescriptorType         1
bcdUSB               2.00
bDeviceClass            0 (Defined at Interface level)
bDeviceSubClass         0 
bDeviceProtocol         0 
bMaxPacketSize0        64
idVendor           0x090c Feiya Technology Corp.
idProduct          0x1000 Memory Bar
bcdDevice           11.00
iManufacturer           1 USB 2.0
iProduct                2 Flash Disk
iSerial                 3 AA00000000000511
bNumConfigurations      1
Configuration Descriptor:
bLength                 9
bDescriptorType         2
wTotalLength           32
bNumInterfaces          1
bConfigurationValue     1
iConfiguration          0 
bmAttributes         0x80
(Bus Powered)
MaxPower              100mA
Interface Descriptor:
bLength                 9
bDescriptorType         4
bInterfaceNumber        0
bAlternateSetting       0
bNumEndpoints           2
bInterfaceClass         8 Mass Storage
bInterfaceSubClass      6 SCSI
bInterfaceProtocol     80 Bulk (Zip)
iInterface              0 
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0x81  EP 1 IN
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0040  1x 64 bytes
bInterval             255
Endpoint Descriptor:
bLength                 7
bDescriptorType         5
bEndpointAddress     0x02  EP 2 OUT
bmAttributes            2
Transfer Type            Bulk
Synch Type               None
Usage Type               Data
wMaxPacketSize     0x0040  1x 64 bytes
bInterval             255
Device Qualifier (for other device speed):
bLength                10
bDescriptorType         6
bcdUSB               2.00
bDeviceClass            0 (Defined at Interface level)
bDeviceSubClass         0 
bDeviceProtocol         0 
bMaxPacketSize0        64
bNumConfigurations      1
Device Status:     0x0000
(Bus Powered)

Ones that I did get to work; 

SanDisk Corp. SDCZ2 Cruzer Mini Flash Drive (thin) 4GB

Hewlett Packard v120w 2GB 

By the way the HP v120w I picked up at MicroCenter for $12, neat little drive.

If you have some details on a USB Flash Drive that you have that you could not get to boot, it would be great if you could comment here with the Make and Model.  

Enjoy!

Coders 4 Charities

Did something different this weekend, hung out with a bunch of geeks and spent something like 30 hours working on a charity website;

Coders 4 Charities 

It was actually alot of fun and I got a chance to play with LINQ in a real world environment. Couple of things I took away with LINQ;

  1. LINQ does not like ALIASES in the SQL for stored procedures. I was not able to get the  DataContext to give me a result until I changed out the 'SELECT p.Firstname from Person P' to a 'SELECT Person.Firstname from Person' in the join clause. Frustrating to figure that one out.
  2. Seems you cant do a join across two DataContext's. If you want you have to include all the tables you want to join together in the same DataContext.

Anyhow my team worked on a bible church and had some challanges getting the membership website all done with VS2008 and using LINQ as the DAL. Good stuff.

Load XML into List Collection

I needed the ability to load a XML file into a selectable list. The problem was really two fold, I had a collection of DAT files (like a single column CSV file) that I needed to first convert to XML (I had another existing collection of XML files, yea I know "consistency, consistency, consistency") as well.ScreenShot014

So I can up with a simple couple of utility methods to convert a single column CSV file (herein referred to as a DAT file) to an XML and then another method to take a XML file and return a list collection. This allows me to first convert the DAT and then load the collection into a ComboBox. 

At first I was worried about performance of reading from the XML files, but then I realized we are talking about a collection of strings around the order of 100. This loads using the XMLTextReader class in about 2/10 of a second. I think that is performance I can live with.

This method takes a plurized DAT file (much like the RoR MVC style) and creates a simple XML (that includes the root attributes that the partner XML read method expects). An example would be using a DAT file name ‘colors.dat’ it would make a XML file with ‘colors’ root node and then a collection of ‘color’ nodes with a single element named ‘name’ that contains the value of each DAT file.

Example DAT file (just for clarity):

red
yellow
orange
pink
blue

Method to convert the DAT to a XML file:

        public void DATToXML(string DATFile, string XMLFile, bool SortList, bool IncludeEmpty, string IncludeAllCaption)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = ("    ");
            settings.Encoding = System.Text.Encoding.UTF8;
            
 
            FileInfo datFileInfo = new FileInfo(DATFile);
            string rootNode = datFileInfo.Name.Replace(datFileInfo.Extension.ToString(), "");
            string childNode = rootNode.Substring(0, rootNode.Length - 1);
 
            using (StreamReader sr = new StreamReader(DATFile))
            {
                string line = string.Empty;
 
                using (XmlWriter writer = XmlWriter.Create(XMLFile, settings))
                {
                        writer.WriteStartElement(rootNode);
                        writer.WriteAttributeString("displaymember", "name");
                        writer.WriteAttributeString("sortlist", SortList.ToString());
                        writer.WriteAttributeString("includeempty", IncludeEmpty.ToString());
                        writer.WriteAttributeString("includeall", IncludeAllCaption);
 
                        while ((line = sr.ReadLine()) != null)
                        {
                            if (!string.IsNullOrEmpty(line))
                            {
                                writer.WriteStartElement(childNode);
                                writer.WriteElementString("name", line);
                                writer.WriteEndElement();
                            }
                        }
                        writer.WriteEndElement();
                        writer.Flush();
                }
            }
        }

 

Now the method to take the newly created XML file and load it into a List<string> collection:

        public List<string> XMLToList(string XMLFile)
        {
            List<string> list = new List<string>();
 
            XmlTextReader xml = new XmlTextReader(XMLFile);
 
            string displayMember = string.Empty;
            bool sortList = false;
            string includeall = string.Empty;
            bool includeempty = false;
 
            while (xml.Read())
            {
                switch (xml.NodeType)
                {
                    case XmlNodeType.Element:
                        while (xml.MoveToNextAttribute())
                        {
                            if (xml.Name == "displaymember")
                                displayMember = xml.Value.ToString();
 
                            if (xml.Name == "sortlist")
                                sortList = bool.Parse(xml.Value.ToString());
 
                            if (xml.Name == "includeall")
                                includeall = xml.Value.ToString();
 
                            if (xml.Name == "includeempty")
                                includeempty = bool.Parse(xml.Value.ToString());
 
                        }
                        while (xml.Read())
                        {
                            if (xml.Name.ToString() == displayMember)
                            {
                                // read next node, the textnode to get value
                                xml.Read();
 
                                if (xml.NodeType != XmlNodeType.Whitespace)
                                    list.Add(xml.Value.ToString());
                            }
                        }
                        break;
                }
            }
 
 
            // If includeall is set then put it at the first of the list
            if (!string.IsNullOrEmpty(includeall))
                list.Insert(0, includeall);
 
            // If sort is set then sort the list before returning it from the method
            if (sortList)
                list.Sort(delegate(string s1, string s2) { return s1.CompareTo(s2); });
 
            // if includeempty is true then put a empty string at the first of the list
            if(includeempty)
                list.Insert(0,string.Empty);
 
            return list;
 
        }

Bit of info on the options:

  • The "displayMember" is the value of the element name to use for the string value (defaults to "name").
  • The "sortList" option is a bool that indicates if the list should be sorted before it is returned.
  • The "includeAll" option is a string value that will be put at the top of the list. Like "- All" or "* Select All *".
  • The "includeEmpty" option is a bool that (if set "true") sets the option to include empty DAT file entries in the string collection.

So put together like this:

        private void Form1_Load(object sender, EventArgs e)
        {
            string DATFile = @"C:\work\zipcodes.csv";
            string XMLFile = @"C:\work\zipcodes.xml";
            
            DATToXML(DATFile, XMLFile, true, false, string.Empty);
 
            Stopwatch sw = new Stopwatch();
 
            sw.Start();
 
            List<string> zipcodes = XMLToList(XMLFile);
 
            sw.Stop();
 
            TimeSpan ts = sw.Elapsed;
 
            this.labelXMLLoadTime.Text = "XML Load Time: " + 
                                         String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
 
            sw.Start();
 
            this.comboBox1.DataSource = zipcodes;
 
            sw.Stop();
 
            ts = sw.Elapsed;
 
            this.labelComboboxLoadTime.Text = "Combobox Load Time: " + 
            String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds);
 
            this.labelCount.Text = "Number Of Items Loaded: " + this.comboBox1.Items.Count.ToString("g");
            
        }

Awesome stuff. Super simple and very fast. I loaded up the entire US Zipcode collection in .223 seconds and then put that into a ComboBox in 2.9 seconds. I realize most people are not going to have 40,000 entries in a selectable ComboBox, my point is that it is zooming fast.

Enjoy!