Tuesday, February 12, 2008

A new feature of Visual Studio 2008 and it's C# 3.0 is Object Initalizers.  This compiler feature can be used to set the values of properties without the need to create a special constructors. Even though you must have 2008 to use this feature, you don't have to target the 3.0 or 3.5 framework as it works just fine with the 2.0 framework.

The following demonstrates an Object Initalizers' use:

   1:             FooClass BandMember = new FooClass { FirstName = "John" , LastName = "Plant", Instrument = "Computer" };

Notice the syntax is very similar to an array's syntax and as long as the variable is strongly typed, you can initialize the properties in any order.  You can also initalize any collection that implements ICollection<T> in the same manner. 

   1:  using System;
   2:  using System.Collections.Generic;
   3:   
   4:  namespace ObjectInitializer
   5:  {
   6:      class FooClass
   7:      {
   8:          public string LastName { get; set; }
   9:          public string FirstName { get; set; }
  10:          public string Instrument { get; set; }
  11:      }
  12:   
  13:      class Program
  14:      {
  15:          static void Main(string[] args)
  16:          {
  17:              FooClass BandMember = new FooClass { FirstName = "John" , 
  18:                                                   LastName = "Plant", 
  19:                                                   Instrument = "Computer" };
  20:              
  21:              List<FooClass> FooFighters = new List<FooClass>
  22:              {
  23:                  new FooClass { FirstName = "Dave", LastName = "Grohl", Instrument = "Vocals" },
  24:                  new FooClass { FirstName = "Nate", LastName = "Mendel", Instrument = "Bass" },
  25:                  new FooClass { FirstName = "Taylor", LastName = "Hawkins" , Instrument= "Drums" },
  26:                  new FooClass { LastName = "Shiflett", FirstName = "Chris",  Instrument = "Guitar" },
  27:                  BandMember
  28:              };
  29:   
  30:              foreach (FooClass p in FooFighters )
  31:              {
  32:                  Console.WriteLine("{0},{1} on {2}", p.LastName, p.FirstName, p.Instrument);   
  33:              }
  34:   
  35:              Console.ReadLine();
  36:          }
  37:      }
  38:  }

This new feature may not be a world changer, but combined with automatic properties can be a time saver and will help you produce cleaner code.

kick it on DotNetKicks.com
posted on Tuesday, February 12, 2008 3:05:46 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]


 Saturday, February 09, 2008

dnrtv_2 In Part 1 of this series I went over the creation of a Windows Service and it's remote client. For this installment, I will be covering the use of "LINQ to XML" to gather the feed, and the saving and loading of the XML configuration files. I'll also show some code to download and unzip the videos using SharpZipLib from ic#code.

The first bit of code we are going to need is a class to hold our feed data. We will be using a List<dnrFeedList> to query against.  Here the code for the class. Nothing strange here, just a datetime field and four strings.

   1:    public class dnrFeedList
   2:      {
   3:          public string Title { get; set; }
   4:          public DateTime Published { get; set; }
   5:          public string Enclosure { get; set; }
   6:          public string Description { get; set; }
   7:          public string GUID { get; set; }
   8:      }

Let's make a few changes to our service. First we need to change our services' timer elapsed event. We want to download the feed list and loop through each show we have not already downloaded. After each download we want to update our XML file in case the program is shutdown. After all shows are downloaded for that day, we will update the last checked date.

   1:   void PollTimer_Elapsed(object sender, ElapsedEventArgs e)
   2:          {
   3:              if (Feed.LastCheckDate < DateTime.Now)
   4:              {
   5:                  foreach (dnrFeedList f in Feed.GetList())
   6:                  {
   7:                      Feed.DownloadFile(f);
   8:                      Feed.SaveXML();
   9:                  }
  10:                  // Add a day to our last check date. 
  11:                  Feed.LastCheckDate = Feed.LastCheckDate.AddDays(1);
  12:                  Feed.SaveXML();
  13:              }
  14:          }

Now we want to pull down the feed from DNRTV. The following LINQ to XML code has been posted online several times over on blogs such as Scott Guthrie. The only addition I made was to the where clause to filter out the videos that have already been downloaded. We will it in a generic called Episode List. This list is a List<String> that contains the shows GUID.  After each successful downloaded, we add that shows GUID to this list.

Also needed was a DateTimeZone class to parse in and correct the time zone issue ( ex. "-0500" instead of "EST" ).  I won't post that code here, but it will be included in the final download.

   1:  public List<dnrFeedList> GetList()
   2:          {
   3:   
   4:              XDocument x = XDocument.Load(URL);
   5:              var feeds = from feed in x.Descendants("item")
   6:                          orderby DateTimeZone.ParseDateTime(feed.Element("pubDate").Value.ToString()) descending
   7:                          where EpisodeList.Contains(feed.Element("guid").Value) == false
   8:                          select new dnrFeedList
   9:                          {
  10:                              Title = feed.Element("title").Value.ToString(),
  11:                              Published = DateTimeZone.ParseDateTime(feed.Element("pubDate").Value.ToString()),
  12:                              Enclosure = feed.Element("enclosure").Attribute("url").Value.ToString(),
  13:                              Description = feed.Element("description").Value.ToString(),
  14:                              GUID = feed.Element("guid").Value
  15:                          };
  16:   
  17:              return feeds.ToList();
  18:          }

Now that we have our feed list, we loop through each show and do our download using a generic TEMP.ZIP filename for each download. Afterward, we unzip the video into the video directory, add the GUID to our Episode List  and delete the TEMP.ZIP.

   1:  public void DownloadFile(dnrFeedList uri)
   2:          {
   3:              // Download ZIP file with TEMP.ZIP as the filename. 
   4:              // It will be deleted after it is unzipped. 
   5:              string filename = this.VideoDirectory + @"TEMP.ZIP";
   6:          
   7:              WebClient web = new WebClient();
   8:              web.DownloadFile(uri.Enclosure.ToString(), filename);
   9:   
  10:              const int bufferSize = 4096;
  11:              byte[] buffer = new byte[bufferSize];
  12:              int count = 0;
  13:   
  14:              // Here we are using the SharpZipLib from ic#code.
  15:              ZipInputStream s = new ZipInputStream(File.OpenRead(filename));
  16:              ZipEntry f;
  17:   
  18:              while ((f = s.GetNextEntry()) != null)
  19:              {
  20:                  string out_filename = this.VideoDirectory + string.Format("{0}", f.Name);
  21:                  if (!File.Exists(out_filename))
  22:                  {
  23:                      FileStream sw = new FileStream(out_filename, FileMode.Create, FileAccess.Write, FileShare.None);
  24:   
  25:                      while (true)
  26:                      {
  27:                          count = s.Read(buffer, 0, bufferSize);
  28:                          if (count > 0)
  29:                          {
  30:                              sw.Write(buffer, 0, bufferSize);
  31:                          }
  32:                          else break;
  33:                      }
  34:                      sw.Close();
  35:                  }
  36:              }
  37:   
  38:              // We need to the GUID for this show to our already downloaded
  39:              // episode list. Delete the Temp.zip afterward.
  40:              EpisodeList.Add(uri.GUID.ToString());
  41:              File.Delete(filename);
  42:          }

The final parts of the code I want to go over are the loading and saving of the configuration XML file. This file contains the last date checked and a list of already downloaded shows. It amazes me that this file can be created in two statements. It is longer than two lines, but it is still just two statements, a constructor and a save method. Notice the LINQ to Generic query for the show list section. Pretty cool.

   1:   public void SaveXML()
   2:          {
   3:   
   4:              XDocument doc = new XDocument(
   5:                  new XDeclaration("1.0", "utf-8", "yes"),
   6:                  new XComment("dnrTv Aggregator Configuration"),
   7:                  new XElement("Aggregator",
   8:                      new XElement("Configuration", new XElement("LastCheckDate", DateTime.Now.ToShortDateString())),
   9:                      new XElement("ShowList", from s in EpisodeList
  10:                                               select new XElement("Show", new XElement("GUID", s.ToString()))
  11:                              )));
  12:   
  13:              doc.Save(path);
  14:          }

Loading the file back in is just about as simple. In fact, there is likely a cooler way of doing this that I just have not discovered yet. Drop me a comment if you have one. Now we use LINQ to XML to pull the data and load it into our previous downloaded show list.

   1:    private void LoadXML()
   2:          {
   3:              if (File.Exists(path))
   4:              {
   5:                  XElement doc = XElement.Load(path);
   6:   
   7:                  LastCheckDate = DateTime.Parse(doc.Element("Configuration").Element("LastCheckDate").Value);
   8:                  var SavedList = from d in doc.Element("ShowList").Elements("Show")
   9:                                  select (string)d.Element("GUID");
  10:   
  11:                  foreach (string s in SavedList)
  12:                  {
  13:                      EpisodeList.Add(s);
  14:                  }
  15:   
  16:              }
  17:          }

I have this code up and running on my Homer Server. It is checking daily for new shows and then downloads them to a shared video directory. My next step will be to rewrite my client application to use WCF has it communication protocol and to fancy up it's features. At that point I will be posting the full code for download.

Code Updated 2-10-2008

kick it on DotNetKicks.com

posted on Saturday, February 09, 2008 1:27:27 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]


 Wednesday, February 06, 2008

 My previous job required a bit of multimedia programming and involved the use of a lot of different graphics techniques. One day we ran across a bit of code to give drawn text either an outerglow or an outline around it. It turns outs to be much simpler to do than I previously thought and only goes to show that you can always learn a new trick. The original project can be downloaded from FancyText.

The basic concept here is drawing the text multiple times in slightly different locations in one color with the alpha channel set to around 15 to 25. Next you print the original text centered back over the glowing text. The results look excellent. When I get the time I will create a label style control based on this code and post it. 

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.ComponentModel;
   4:  using System.Data;
   5:  using System.Drawing;
   6:  using System.Text;
   7:  using System.Windows.Forms;
   8:  using System.Drawing.Drawing2D;
   9:  using System.Drawing.Text;
  10:   
  11:  namespace OutGlowText
  12:  {
  13:      public partial class MainForm : Form
  14:      {
  15:          string OutStr = "Glowing Text";
  16:          int BlurAmt = 9;
  17:   
  18:          public MainForm()
  19:          {
  20:              InitializeComponent();
  21:          }
  22:   
  23:          private void MainForm_Load(object sender, EventArgs e)
  24:          {
  25:              this.BackColor = Color.Black;
  26:          }
  27:   
  28:          protected override void OnPaint(PaintEventArgs e)
  29:          {
  30:              Graphics g = e.Graphics;
  31:              Brush br = new SolidBrush(Color.FromArgb(15, Color.White));
  32:   
  33:              g.SmoothingMode = SmoothingMode.HighQuality;
  34:              g.InterpolationMode = InterpolationMode.HighQualityBilinear;
  35:              g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
  36:   
  37:              for (int x = 0; x <= BlurAmt; x++)
  38:              {
  39:                  for (int y = 0; y <= BlurAmt; y++)
  40:                  {
  41:                      g.DrawString(OutStr, new Font("Arial", 48,FontStyle.Bold),br, new Point(x, y));
  42:                  }
  43:              }
  44:              
  45:              g.DrawString(OutStr, 
  46:                           new Font("Arial", 48,FontStyle.Bold ), 
  47:                           Brushes.Blue, 
  48:                           new Point(BlurAmt /2, BlurAmt/2));
  49:   
  50:              base.OnPaint(e);
  51:          }
  52:   
  53:      }
  54:  }
 
kick it on DotNetKicks.com
posted on Wednesday, February 06, 2008 6:32:42 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]


 Thursday, January 31, 2008

dnrtv It is time for another personal project for me and this time I thought I would put together a dnrTV feed aggregator. Rather than watch each episode on my home computer, I prefer to watch them on the big screen TV in the living room. They are very viewable and I can sit in my lazy boy with the remote, a beer and maybe the laptop. ( mostly the remote and a beer )

In order to make this happen, I download each show to my Home Server and watch it via my Xbox 360 in the living room. The Xbox 360 acts as a media extender for any movie, music or picture I have stored on my network.

Basically, this software should run as a windows service on my Home Server and check the feed about once a week, download the show, unzip it,  and place the in the proper shared video directory. In order to change settings and monitor the health of the application, I want to create a winform application that will reside on my personal computer's system tray and communicate via some means to the service. Right now, I am leaning towards named pipes.  Our first Step is to create a Windows Service Project.

 

sshot-5

Next we will rename our service to 'dnrTVService' and then we will need to add an Installer Project to our solution. Let's name it 'dnrTVInstaller' and add the following code:

 

   1:  using System.ComponentModel;
   2:  using System.Configuration.Install;
   3:  using System.ServiceProcess;
   4:   
   5:  namespace dnrTVAggregator
   6:  {
   7:      [RunInstaller(true)]
   8:      public partial class dnrTVInstaller : Installer
   9:      {
  10:          public dnrTVInstaller()
  11:          {
  12:              InitializeComponent();
  13:   
  14:              ServiceProcessInstaller ProcessInstaller = new ServiceProcessInstaller();
  15:              ServiceInstaller Installer = new ServiceInstaller();
  16:   
  17:              ProcessInstaller.Account = ServiceAccount.LocalSystem;
  18:              ProcessInstaller.Username = null;
  19:              ProcessInstaller.Password = null;
  20:   
  21:              Installer.ServiceName = "dnrTV_Service";
  22:              Installer.Description = "Service to download new episodes of dnrTv to my Home Server";
  23:              Installer.StartType = ServiceStartMode.Manual;
  24:              Installer.DisplayName = "dnrTv Aggregator Service";
  25:   
  26:              this.Installers.Add(ProcessInstaller);
  27:              this.Installers.Add(Installer);
  28:          }
  29:      }
  30:  }

 

Here we setup the name of our service, it's description and display name. We also decide whether or not it will start manually or automatically. Without this installer project, you will not be able to use INSTALLUTL.EXE to install your service.  Next, let's go back to our service and make it do something. For the time being, let's just have it report the current date and time via a named pipe. We will use a System.Timer and throw an event every 10 seconds. 

 

   1:  using System;
   2:  using System.Diagnostics;
   3:  using System.IO;
   4:  using System.IO.Pipes;
   5:  using System.ServiceProcess;
   6:  using System.Timers;
   7:   
   8:  namespace dnrTVAggregator
   9:  {
  10:      public partial class dnrTVService : ServiceBase
  11:      {
  12:          Timer MyTimer = new Timer(10000);
  13:          public dnrTVService()
  14:          {
  15:              InitializeComponent();
  16:              MyTimer.AutoReset = true;
  17:              MyTimer.Elapsed += new ElapsedEventHandler(MyTimer_Elapsed);
  18:          }
  19:   
  20:          void MyTimer_Elapsed(object sender, ElapsedEventArgs e)
  21:          {
  22:              NamedPipeClientStream  np = new NamedPipeClientStream(".", "test_pipe", PipeDirection.InOut);
  23:              np.Connect();
  24:              
  25:              using (StreamWriter w = new StreamWriter(np))
  26:              {
  27:                  w.AutoFlush = true;
  28:                  w.WriteLine(String.Format("TIME IS {0}", DateTime.Now));
  29:              }
  30:              np.Close();
  31:          }
  32:   
  33:          protected override void OnStart(string[] args)
  34:          {
  35:              MyTimer.Start();
  36:          }
  37:   
  38:          protected override void OnStop()
  39:          {
  40:              MyTimer.Stop();
  41:          }
  42:      }
  43:  }

 

The OnStart and OnStop Event will start and end the timer and the MyTimer_Elaspsed will execute the needed code. As I said early, I'm just using some test code to demonstrate it's use. We will add our aggregation code in another post, but for now, let's keep it simple. Once you have compiled your service, you can install it using INSTALLUTIL /I dnrTVService.exe.

sshot-6

Our next step is to create the client winform application. We will drop three buttons on it, a start button, a stop button and a connect button. Also, we'll be needing a list box to report the time back too. Two additional controls we will be using will be the ServiceController to start and stop our service and a BackgroundWorker process.

 

sshot-7

The following code in our winform application will start up a background worker thread and wait for the service to contact us. Yes, I know it is sort of backwards, but it will have to do for now. I'll see about reversing the client/server role in my next post.

 

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.ComponentModel;
   4:  using System.Data;
   5:  using System.Drawing;
   6:  using System.Linq;
   7:  using System.Text;
   8:  using System.Windows.Forms;
   9:  using System.IO.Pipes;
  10:  using System.IO;
  11:   
  12:  namespace dnrTVClient
  13:  {
  14:      public partial class MainForm : Form
  15:      {
  16:          public MainForm()
  17:          {
  18:              InitializeComponent();
  19:          }
  20:   
  21:          private void StartButton_Click(object sender, EventArgs e)
  22:          {
  23:              dnrTVController.Start();
  24:          }
  25:   
  26:          private void StopButton_Click(object sender, EventArgs e)
  27:          {
  28:              dnrTVController.Stop();
  29:          }
  30:   
  31:          private void dnrTVProcessWorker_DoWork(object sender, DoWorkEventArgs e)
  32:          {
  33:              while (true)
  34:              {
  35:                  NamedPipeServerStream np = new NamedPipeServerStream("test_pipe", PipeDirection.InOut);
  36:   
  37:                  np.WaitForConnection();
  38:                  StreamReader r = new StreamReader(np);
  39:                  dnrTVProcessWorker.ReportProgress(0, r.ReadLine());
  40:   
  41:                  np.Close();
  42:              }
  43:          }
  44:   
  45:          private void ConnectButton_Click(object sender, EventArgs e)
  46:          {
  47:              dnrTVProcessWorker.RunWorkerAsync();
  48:          }
  49:   
  50:          private void dnrTVProcessWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  51:          {
  52:              LogListBox.Items.Add(e.UserState.ToString());
  53:          }
  54:      }
  55:  }
 
Assuming we already compiled and installed our service, it is time to compile and run out client application. The output for the should look something like this.
 
sshot-8
 
Things look like they are going pretty good. For my next post in this series, I will add the aggregation code to pull the feed, download the show, unzip it and update a configuration XML file.
 
 
kick it on DotNetKicks.com
posted on Thursday, January 31, 2008 5:13:23 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]


 Wednesday, January 30, 2008

Looks like the "Day 1" or the first comic from the Heroes Happen Here series has been released. This comic was released by Microsoft and Seagate so make sure and signup for the RSS Feed to receive the comic everyday of the working week.

 

DailyComic_Full

posted on Wednesday, January 30, 2008 3:28:47 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]


 Thursday, January 24, 2008

imageSo you just got done prototyping that new Winform or WPF application and the interface is a bit lacking. You are a programmer, not an artist after all. Well, never fear, free icons are here (wow that really rhymed). All kidding aside, most of us are not good at drawing images and icons, so we need some resources for these items.

Our journey starts with Visual Studio 2005. If you recall, it  had  a zip file called VS2005ImageLibrary located at Program Files\Microsoft Visual Studio 8\Common7\VS2005ImageLibrary\. This file contained a nice collection of icons, animations, buttons and a variety or other objects that you could use within your application. Here are the instructions on how and where to extract the images.

After installing Visual Studio 2008, I checked to see if this library was still available and was happily surprised to find it still located at Program Files\Microsoft Visual Studio 9.0\Common7\VS2008ImageLibrary\1033\VS2008ImageLibrary\.   Here you will find images taken from Microsoft programs such as Office and Vista, along with some cool animations for your progress displays.

 

HTML_Webpage Dialogs_XP X's 

 

Our next stop is online, where there are plenty of resources to find images. I ran across an excellent one the other day on Damen Guard's Blog. This collection, Silk Companion #1, looked to be over a 450+ top quality 16x16 icons in PNG format. These were mostly derived from a larger collection at FAMFAMFAM. Here you find over the original 1000+ icons that can be used under the Creative Commons Attribution 2.5 License.

 

image

I also stopped by Icon Factory, but their freeware icons and images were not licensed for redistribution and can only be use as desktop icons. Not much good for a us programmers.

My next step will be to start compiling a list of the best of the best graphical resources, targeted for us, the programmers. If anyone has any suggestions, please feel free drop me a note.

 

kick it on DotNetKicks.com

posted on Thursday, January 24, 2008 1:49:33 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]


 Saturday, January 19, 2008

It is launch time again for Microsoft, and this time it is for Windows Server 2008, Visual Studio 2008 and SQL Server 2008. The one here in Tampa is not until May 8, but as soon as I can register for it I will.  You can get more information and register on their launch web site, Heroes happen {here}. They also have a RSS feed for a new comic series about IT professionals and Developers. Oh, did I mention that all attendees will being get free copies of all three products. Pretty Sweet !! Make sure and sign up for one in your area.

hero_event

 

kick it on DotNetKicks.com

posted on Saturday, January 19, 2008 2:18:51 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]


 Friday, January 18, 2008

I wrote some code last year to create an Microsoft Access Database, fill in some data and email it out. It never made it out to production so I thought I would share part of it here. Let's focus on creating the database in this post.

The first thing you need to do is get a COM reference to the Microsoft ADO Ext. X.X for DDL and Security. The X.X represents whatever version you happen to have on your machine. Mine used to be version 2.7, but with Visual Studio 2008, it was updated to 6.0.

AddReference

Once you have added the reference, ADOX will be added to the using section of your code.

 Using

Next you will want to create the catalog for the database. Insert the filename you wish into the following string and pass it to the CatalogClass.

   1:              CatalogClass cat = new CatalogClass();
   2:   
   3:              string tmpStr;
   4:              string filename = "Sample.MDB";
   5:              
   6:              tmpStr = "Provider=Microsoft.Jet.OLEDB.4.0;";
   7:              tmpStr += "Data Source=" + filename + ";Jet OLEDB:Engine Type=5";
   8:   
   9:              cat.Create(tmpStr);

The next step is to create the table and columns for your database. This is a pretty straight forward operation as shown in the example below.

   1:              Table nTable = new Table();
   2:              nTable.Name = "PersonData";
   3:                 
   4:              nTable.Columns.Append("LastName", DataTypeEnum.adVarWChar, 25);
   5:              nTable.Columns.Append("FirstName", DataTypeEnum.adVarWChar, 25);
   6:              nTable.Columns.Append("Address 1", DataTypeEnum.adVarWChar, 45);
   7:              nTable.Columns.Append("Address 2", DataTypeEnum.adVarWChar, 45);
   8:              nTable.Columns.Append("City", DataTypeEnum.adVarWChar, 25);
   9:              nTable.Columns.Append("State", DataTypeEnum.adVarWChar, 2);
  10:              nTable.Columns.Append("Zip", DataTypeEnum.adVarWChar, 9);
  11:    
  12:              cat.Tables.Append(nTable);
 

The final step is very important or you will get error when you close your application. Once the all the tables and columns have been added, you will need to release the com objects properly and in the proper order.

   1:              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(nTable);
   2:              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.Tables); 
   3:              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat.ActiveConnection); 
   4:              System.Runtime.InteropServices.Marshal.FinalReleaseComObject(cat);
 
That is it. You should now have a Access Database that you can write to. Hope this helps.
 
kick it on DotNetKicks.com
posted on Friday, January 18, 2008 3:11:18 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]