Search

Archives

Categories

blog swap (16) books [non-technology] (4) books [technology] (2) code [.net] (10) code [t-sql] (3) code [vbscript] (2) coding (21) dogs (4) funnies (31) links (7) microsoft (100) one liners (19) parenthood (16) ramblings (114) sports (9) technology (68) testing (2) video games (24) workplace (1)

Subscribe

Email or RSS 1.0, RSS 2.0 & Atom

Ignore

growled on Saturday, October 13, 2007 8:41:35 AM (Pacific Standard Time, UTC-08:00)
barked at code [.net]

Just the other day, I wanted to detect if an application is running on 32 or 64 bit (x86 versus x64) Windows operating system so I could display it in a label control.  I thought to myself "ok that should be easy with a registry key or a file version of a system file," but I didn't know a definitive source so off I go to the wild, wild web.  A few searches [1, 2, 3] yielded no useful results for doing this programmatically [and yes, I tried Google too ;-)]. 

So I turned to my brother who has been working with operating system deployments in our data centers for the past 10 years [probably what I should have done in the first place].  Just as I thought, there is a registry key that gives you this information. Since I couldn't find it easily online, I'll add it here.

HKLM\System\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE

Adding this to a .NET C# application is only a few lines of code (using Microsoft.Win32 namespace):

private string GetProcessorArchitecture()
{
    RegistryKey environmentKey = Registry.LocalMachine;  // points to HKLM hive
    environmentKey = environmentKey.OpenSubKey
        (@"System\CurrentControlSet\Control\Session Manager\Environment", false);
    string strEnvironment = 
        environmentKey.GetValue("PROCESSOR_ARCHITECTURE").ToString();
    return strEnvironment;
}

So there you go...how to determine whether the architecture of the operating system is 32-bit or 64-bit.

~tod

growled on Wednesday, June 06, 2007 9:06:11 PM (Pacific Standard Time, UTC-08:00)
barked at code [.net]

It's been awhile since I wrote a how to post, so here goes one taken from my latest little side project.

How to find the date a picture was taken [DateTimeOriginal] from the EXIF1 metadata using C#.

I discovered that the EXIF data is a bit of work to get to. It's not just a matter of instantiating an object off of the picture (jpg, bmp, etc.) and picking out the property you want based on the name. Oh no, that would be way too easy. :-\ There are some hoops to jump through.

Actually, the EXIF values are stored in the Image.PropertyItems collection, but the properties are all stored based on an ID without any immediate reference to the name. So you have to know the ID of the tag you're looking for. I found this list mapping tag ID to property name. The DateTimeOriginal property ID is 0x9003. Um yeah, that's a hexadecimal value, meanwhile the PropertyItems ID property uses an integer value. That means you have to convert the hex value to an integer, like so [must remove the 0x prefix]:

int id = int.Parse("9003", System.Globalization.NumberStyles.AllowHexSpecifier);

Now that we have the integer representation, we can grab the PropertyItem out of the collection:

PropertyItem prop = img.GetPropertyItem(id);

Here's another interesting little twist... The PropertyItem.Value is stored as a byte array. So now you have to convert that byte array in to something useful. I chose to first convert it to a string from which I could later manipulate it into a DateTime object. Fortunately, .NET provides the Encoding class with the ASCII property that makes this a trivial thing to do [thanks Sahil!]:

byte[] asciiBytes = prop.Value;
string strDate = System.Text.Encoding.ASCII.GetString(asciiBytes);

Now we encounter another little twist. The string comes out in a format like "YYYY:MM:DD HH:MM:SS" which would be "2007:06:06 19:43:31". Notice that the year, month and day are separated by a colon [":"] instead of a dash ["-"] or forward slash ["/"]. That means we have to first replace those colons with forward slashes before we can convert it to a DateTime object:

DateTime dateCreated = new DateTime();

// Pull out the year, month, day and time individually from the string
string dateYear = date.Substring(0, 4);
string dateMonth = date.Substring(5, 2);
string dateDay = date.Substring(8, 2);
string dateHourMinSec = date.Substring(11, 8);

// Create a stringbuilder that is formatted for conversion to DateTime
StringBuilder sbDateCreated = new StringBuilder();
sbDateCreated.Append(dateMonth + "/");
sbDateCreated.Append(dateDay + "/");
sbDateCreated.Append(dateYear + " ");
sbDateCreated.Append(dateHourMinSec);

// Convert the string to DateTime
dateCreated = Convert.ToDateTime(sbDateCreated.ToString());

VoilĂ , you now have a DateTime object that represents the date and time the picture was originally taken. :-) And here is a class for a console application if you want to see it all put together [and even compile it yourself]: GetDateTaken.cs.txt [right-click -> save target as...]

While working on this I came across Reading EXIF Tags From JPEG Files  at VBAccelerator.com which goes into quite a bit more depth and also provides some nice sample code in the downloadable project.

Hope that helps!

~tod 

DISCLAIMER: As usual, my standard code disclaimer applies and I welcome all suggestions for improvement.

1EXIF (exchangeable image file format) is a specification for the image file format used by digital cameras that stores the properties of an image such as date/time taken, ISO speed, camera manufacturer, camera model, flash, resolution and many, many others.

growled on Friday, February 16, 2007 12:54:40 PM (Pacific Standard Time, UTC-08:00)
barked at code [.net]

It's been a long time since I wrote my last how2 post, but this interesting little question was brought up to me recently and I figured why not throw it up here. How would you programmatically search a string to see if it contains another string? Of course I'm doing this in C#, but the logic would be applicable to any language.

[NOTE: If you just want the quick way to do this then scroll to the bottom.]

Here's a visual of what I mean...  We're looking to see if string1 (lookingFor) is contained anywhere within string2 (lookingIn). For example:

    lookingFor = abcd

    lookingIn = abcd OR efgh OR eabcdf OR eabfcd OR abceabfabcdghi

You can see that of all the options for lookingIn, lookingFor is found in #1, #3 and #5. Each of those options are of varying difficulty to traverse though.

    abcd : Easy enough, the strings are exactly the same.

    efgh : Easy enough, the string is nowhere to be found.

    eabcdf : Now lookingFor is present, but it's surrounded by other letters.

    eabfcd : A little more complicated...the individual letters from lookingFor are present, but the exact string is not present as there is another character between b and c.

    abceabfabcdghi : Ok, now we're getting really complicated. At first we get all the way to the 3rd character from lookingFor [c] before being faced with an incorrect character. Then we start over again and get to the 2nd character. Finally, we find the full string towards the end of lookingIn.

As you can see, the cases quickly go from simple to complicated. We have to handle multiple failures while traversing the string, lookingIn, and make sure that we're finding the whole of the string, lookingFor, not just bits and pieces.

Let's see if I can explain the logic behind the code below. First of all, we want to iterate through the string we are searching through (lookingIn) to see if we can match the first letter of the string we are looking for (lookingFor). If we find the first letter then we will increase a counter [integer j below] to denote how many characters in lookingFor we have found. We then check to see if the counter is equal to the number of characters in lookingFor [the .length property].  If so, then we have found the full string and break out of the for loop. If not, then we add 1 to the counter [integer j below] and continue on to the next character in the string, lookingIn, trying to match it to the next character in lookingFor. Here's the kicker, if at any point in time the current character from lookingIn does not equal the character at the position [integer j below] in lookingFor then we reset the counter to 0 so that we start over.  This is what allows case #5 above to work. It increases the counter by 1 for a, b and c then resets it to 0 when it reaches e.

Here's the full code for a console app [so you can copy/paste into your compiler and play with it]: 

using System;
using System.Collections;
using System.Text;

namespace StringInString
{
    class Program
    {
        static void Main(string[] args)
        {
            bool isContained = FindString(args[0].ToLower(), args[1].ToLower());
            Console.WriteLine(isContained.ToString());
        }

        static bool FindString(string lookingFor, string lookingIn)
        {
            int j = 0;
            for (int i = 0; i < lookingIn.Length; i++)
            {
                if (lookingIn[i].Equals(lookingFor[j]))
                {
                    j++;
                    if (j.Equals(lookingFor.Length))
                        break;
                }
                else
                {
                    j = 0;
                }
            }
            if (!j.Equals(0))
                return true;
            else
                return false;
        } 
    }
}

Now having gone through that exercise in logic, here are two quick ways built in to .NET ;-) :

1. Regular Expressions.  Use the Regex.IsMatch method to determine if string1 is contained in string2. This method returns a boolean value. It would look like this [remember to add the using statement to the beginning of your class for System.Text.RegularExpressions]:

    bool isContained = Regex.IsMatch(lookingIn, lookingFor);
2. Strings have a property called IndexOf() that will search the string for the string2 provided and return the index of where string2 starts or -1 if it isn't found.
    int indexFound = lookingIn.IndexOf(lookingFor);

Given the choice, I'll pick either of the methods built into the .NET framework every single day of the week! Why try to rebuild the wheel, especially when theirs is probably optimized for speed, efficiency and to avoid memory overflows. But, it's still interesting to work through the logic and see how the functions work.

~tod

growled on Thursday, September 07, 2006 9:50:30 PM (Pacific Standard Time, UTC-08:00)
barked at code [.net]

HttpRequest.QueryString can be a pretty useful and powerful tool for a .NET web site. I hadn't used this property in almost a year and was recently reintroduced to it due to a request from a co-worker. I wrote an application [shortLink] last November ('05) that takes really long URLs and shortens them to something manageable, very similar to TinyURL. The reason I even did this was because I wanted this functionality on our corporate network and it didn't exist. That's the beauty of working at Microsoft...if something doesn't exist and you want to create it, then by all means...do it. Anyway, a co-worker emailed me yesterday and asked if there was a bookmarklet he could use that would take any page he was currently viewing and submit it to shortLink for conversion. I had wanted to do this, but hadn't gotten around to it yet. Backburner and all that. ;-)

Admittedly, I had a brainfart at first and couldn't remember how the heck to do this. I remembered something about the ? after the .aspx denoting a string, but for the life of me I just couldn't pull the information out of the dark recesses of my brain. So I started searching online and after 30 minutes of fruitless searches [using "parsing a url in .net", "how to read the string after .aspx?", "what comes after a url formatted like .aspx?", etc.] I eventually landed here. Then my d'oh meter went off and I smacked myself upside the head, because it is so simple. :-S

Anyway, you probably made it here through some search query [better formatted than mine I hope] so let's get on with it. Here's a short description of the HttpRequest.QueryString collection and a quick tutorial how to use it to pass a string to an ASP.NET page and then manipulate it.

Here's a summary description from the sitepoint article:

In case you're not familiar with query strings, the basic idea is to tack on a set of variables to the end of the URL that appears in the browser's Address field. For example, if there were a page on your site with URL http://www.yoursite.com/welcome.asp, then you could send that page my first and last name by adding a query string to the address as follows:

http://www.yoursite.com/welcome.asp?firstname=Kevin&lastname=Yank

The portion of the URL thats in bold is the query string. A query string always begins with a question mark (?), which marks the end of the standard URL. The query string, which follows the question mark, is a series of one or more name/value pairs separated by ampersands (&). In this case, we have two such pairs. The variable name firstname is given a value of Kevin, and the variable name lastname is given a value of Yank.

These values are passed into the HttpRequest.QueryString collection and we can then access them with something as simple as: string firstName = Request.QuerySting["firstname"]. The string firstName then has the value of Kevin (assuming the example above). Like any NameValueCollection you, can also reference the the name-value pairs by the index number. In the above example, Request.QueryString[0] would give you the firstname value and Request.QueryString[1] would give you the lastname value.

It might be worth noting here that although the QueryString property is a member of the HttpRequest class, you access the QueryString collection by using the Request property of the Page class which gets the HttpRequest object for the requested page. Make sense? If not, don't worry too much about it...just know that you use Request.QueryString to access the name-value collection.

So what did I do in my implementation? Well, here's the code I slung together:

   1:  private void CheckQueryString()
   2:          {
   3:              if (!Request.QueryString.Count.Equals(0))
   4:              {
   5:                  if (Request.QueryString.AllKeys[0].ToLower().Equals("linktoshorten"))
   6:                  {
   7:                      textBoxLongUrl.Text = Request.QueryString["linktoshorten"];
   8:                      SubmitLongUrl();
   9:                  }
  10:              }
  11:          }

I created a method [CheckQueryString()] to be called during the default.aspx's Page_Load to do the following:

  1. Line 3 - See if a QueryString collection was provided. If not, then do nothing else.
  2. Line 5 - See if the first pair had a name equal to "linktoshorten" in which case I knew that I wanted to process it.
    • Line 7 & 8 - If yes, then set the text of my TextBox with the value provided in the QueryString and kick off SubmitLongUrl, the method that creates a new shortLink from a long URL (with all sorts of checks and balances in place).
    • If no, then do nothing else and simply display the default page.

Easy as pie, right? :-) Perhaps it's not the most elegant solution to the issue of reading in string values from a URL, but it works. One of the cool things about the QueryString collection is that can easily be used to pass strings from one page/site to another.

~tod

DISCLAIMER: As usual, my standard code disclaimer applies and I welcome all suggestions for improvement.

growled on Thursday, July 13, 2006 7:40:30 AM (Pacific Standard Time, UTC-08:00)
barked at code [.net]

About a month ago I flattened and rebuilt the OS on my primary PC at work [the one I use for development]. Things were starting to act a bit odd and I like to do this every once in awhile anyway to keep things fresh. Yesterday I found myself needing to do some web UI work on our application for the first time since rebuilding my box. I loaded up and built the solution in Visual Studio [of course, after resolving some issues with missing references :-S]. I got this error when loading the local page in IE7:

Description: The application attempted to perform an operation not allowed by the security policy. To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: Requested registry access is not allowed.

Security Exception

In January, I described how to enable event logging for an ASP.NET application on a Windows 2003 server using IIS6. This was my first thought, but then it occurred to me that I'm running Windows XP SP2 with IIS5. Hmm. Something else was bumping around in the back of my head, but I couldn't quite put my finger on it so I did what I always do in that case...turned to mi compadre and asked. :-) Luckily, she remembered running into this problem several months ago and it's a very simple reason and fix.

According to KB article # 329291, this error message occurs when an ASP.NET application tries to write a new event source in the EventLog. So the quick fix is to create the new event source in the registry under the key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application. You can also do this programmatically using the EventLogInstaller class. The detailed instructions for both methods are available in the KB article.

Update (7.19.2006): Reduced the size of the picture as it was overlapping with the sidebar and just looked ugly. Click on it to see the full size image. :-)

~tod

Page 1 of 2 in the code [.net] category Next Page