Script iTunes Playlist and Fullscreen using Powershell

by Gary Gagnon 2. July 2012 12:34

Here is a powershell script to run iTunes, play a playlist, and put iTunes in fullscreen.

 

 

#Author: Gary Gagnon
#Action: Start iTunes Playlist and Fullscreen
##############################################
#      Name of playlist you want to start    #
##############################################
$playlist = "wat"
#########################################################################################
#							DO NOT EDIT BELOW THIS LINE									#
#########################################################################################
add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms
$iTunes = New-Object -ComObject iTunes.Application
$libraryName = $iTunes.LibraryPlaylist.Name
$myPlaylist = $iTunes.Sources.ItemByName($libraryName).Playlists.ItemByName($playlist)
$myPlaylist.PlayFirstTrack()
[Microsoft.VisualBasic.Interaction]::AppActivate("iTunes")
[System.Windows.Forms.SendKeys]::SendWait("^{f}")

Tags: , , , ,

SMTP Console Tester with POP3 Support

by Gary Gagnon 14. February 2012 19:48

I have update the SMTP Console Tester with a POP3 option.

Here's the code (hacked together and not great at all but here it is)

It uses the OpenPop library which is embedded in the exe using ilmerge.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;
using OpenPop.Pop3;

namespace SMTPTester
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("########################################");
                Console.WriteLine("# Welcome to Gary's world class smtp   #");
                Console.WriteLine("# tester. Select your option.          #");
                Console.WriteLine("# 1. Unathenticated SMTP               #");
                Console.WriteLine("# 2. Authenticated SMTP                #");
                Console.WriteLine("# 3. Authenticated SMTP with TLS (SSL) #");
                Console.WriteLine("# 4. Test POP Mailbox                  #");
                Console.WriteLine("# 5. Exit program                      #");
                Console.WriteLine("########################################");
                Console.Write("#/> ");
                var selectedOption = Console.ReadLine();
                if (selectedOption == "5")
                {
                    break;
                }
                if (selectedOption != "4")
                {
                    Console.WriteLine("Enter the SMTP server");
                    Console.Write("#/> ");
                    var smtpServer = Console.ReadLine();
                    Console.WriteLine("Enter the SMTP port (default 25)");
                    Console.Write("#/> ");
                    var smtpPort = 25;
                    Int32.TryParse(Console.ReadLine(), out smtpPort);
                    Console.WriteLine("Enter the FROM address");
                    Console.Write("#/> ");
                    var mailFrom = Console.ReadLine();
                    Console.WriteLine("Enter the TO address");
                    Console.Write("#/> ");
                    var mailTo = Console.ReadLine();
                    Console.WriteLine("Enter the message subject");
                    Console.Write("#/> ");
                    var subject = Console.ReadLine();
                    Console.WriteLine("Enter the message body");
                    Console.Write("#/> ");
                    var body = Console.ReadLine();
                    switch (selectedOption)
                    {
                        case "1":
                            Console.WriteLine("Attempting to send mail");
                            var message = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body);
                            Console.WriteLine(message);
                            break;
                        case "2":
                            Console.WriteLine("Please enter your username");
                            Console.Write("#/> ");
                            var username = Console.ReadLine();
                            Console.WriteLine("Please enter your password");
                            Console.Write("#/> ");
                            var password = Console.ReadLine();
                            Console.WriteLine("Attempting to send mail");
                            var authMessage = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body, true, username, password);
                            Console.WriteLine(authMessage);
                            break;
                        case "3":
                            Console.WriteLine("Please enter your username");
                            Console.Write("#/> ");
                            var authUsername = Console.ReadLine();
                            Console.WriteLine("Please enter your password");
                            Console.Write("#/> ");
                            var authPassword = Console.ReadLine();
                            Console.WriteLine("Attempting to send mail");
                            var authSecureMessage = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body, true, authUsername, authPassword, true);
                            Console.WriteLine(authSecureMessage);
                            break;
                        default:
                            Console.WriteLine("Incorrect option!");
                            break;
                    }
                }

                if (selectedOption == "4")
                {
                    Console.WriteLine("Enter POP Server");
                    Console.Write("#/> ");
                    var popServer = Console.ReadLine();
                    Console.WriteLine("Enter POP Port");
                    Console.Write("#/> ");
                    var port = Int32.Parse(Console.ReadLine());
                    Console.WriteLine("Is SSL? (y/n)");
                    Console.Write("#/> ");
                    var isSSL = Console.ReadLine();
                    Console.WriteLine("Enter Username");
                    Console.Write("#/> ");
                    var username = Console.ReadLine();
                    Console.WriteLine("Enter Password");
                    Console.Write("#/> ");
                    var password = Console.ReadLine();
                    var client = new Pop3Client();

                    bool useSsl = false;
                    if (isSSL.ToLower() == "y") useSsl = true;
                    client.Connect(popServer, port, useSsl);
                    if (client.Connected)
                    {
                        bool authenticated = false;

                        if (client.ApopSupported)
                        {
                            try
                            {
                                client.Authenticate(username, password, AuthenticationMethod.Apop);
                                authenticated = true;
                            }
                            catch (Exception ex) 
                            {
                                if(client.Connected)
                                    try
                                    {
                                        client.Disconnect();
                                    }
                                    catch (Exception e) { }
                            }
                        }

                        if (!authenticated)
                        {
                            try
                            {
                                client.Connect(popServer, port, useSsl);
                                client.Authenticate(username, password, AuthenticationMethod.UsernameAndPassword);
                                authenticated = true;
                            }
                            catch (Exception ex) 
                            {
                                if (client.Connected)
                                    try
                                    {
                                        client.Disconnect();
                                    }
                                    catch (Exception e) { }
                            }
                        }

                        if (!authenticated)
                        {
                            try
                            {
                                client.Connect(popServer, port, useSsl);
                                client.Authenticate(username, password);
                                authenticated = true;
                            }
                            catch(Exception ex)
                            {
                                if (client.Connected)
                                    try
                                    {
                                        client.Disconnect();
                                    }
                                    catch (Exception e) { }
                                Console.WriteLine(ex.Message);
                            }
                        }

                        if (authenticated)
                        {
                            var messageCount = client.GetMessageCount();

                            Console.WriteLine(String.Format("There are {0} messages in the mailbox.", messageCount));

                            client.Disconnect();
                        }
                        else
                        {
                            Console.WriteLine("Unable to authenticate. No really!");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Could not connect");
                    }
                }

                Console.WriteLine("Press a key to continue...");
                Console.ReadLine();
                Console.Clear();
            }
        }

        private static string SendEmail(string server, int port, string from, string to, string subject, string body, bool authenticate = false, string user = null, string password = null, bool secure = false)
        {
            var smtpClient = new SmtpClient(server, port);
            var message = new MailMessage(from, to, subject, body);
            if (authenticate)
            {
                var credentials = new NetworkCredential(user, password);
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = credentials;

                if (secure)
                {
                    smtpClient.EnableSsl = true;
                }
            }

            try
            {
                smtpClient.Send(message);
                return "Message sent successfully";
            }
            catch (SmtpException ex)
            {
                return String.Format("There was an error. {0}", ex.Message);
            }
        }
    }
}

 

Download The Below

SMTPTester.zip (25.90 kb)

Tags:

ASP.Net

SMTP Console Tester

by Gary Gagnon 16. January 2012 16:32

I recently wrote a console application to test various modes of SMTP. It's very basic and simple and I may expand it later.

It should be self-explanitory and only used as a basic testing utility.

This utility will NOT record any information entered. If you feel uncomfortable entering settings into some website or unknown app then this might work for you.

SMTPTester.zip (3.00 kb)

Here's the source code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using System.Net;

namespace SMTPTester
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("########################################");
                Console.WriteLine("# Welcome to Gary's world class smtp   #");
                Console.WriteLine("# tester. Select your option.          #");
                Console.WriteLine("# 1. Unathenticated SMTP               #");
                Console.WriteLine("# 2. Authenticated SMTP                #");
                Console.WriteLine("# 3. Authenticated SMTP with TLS (SSL) #");
                Console.WriteLine("# 4. Exit program                      #");
                Console.WriteLine("########################################");
                Console.Write("#/> ");
                var selectedOption = Console.ReadLine();
                if (selectedOption == "4")
                {
                    break;
                }
                Console.WriteLine("Enter the SMTP server");
                Console.Write("#/> ");
                var smtpServer = Console.ReadLine();
                Console.WriteLine("Enter the SMTP port (default 25)");
                Console.Write("#/> ");
                var smtpPort = 25;
                Int32.TryParse(Console.ReadLine(), out smtpPort);
                Console.WriteLine("Enter the FROM address");
                Console.Write("#/> ");
                var mailFrom = Console.ReadLine();
                Console.WriteLine("Enter the TO address");
                Console.Write("#/> ");
                var mailTo = Console.ReadLine();
                Console.WriteLine("Enter the message subject");
                Console.Write("#/> ");
                var subject = Console.ReadLine();
                Console.WriteLine("Enter the message body");
                Console.Write("#/> ");
                var body = Console.ReadLine();
                switch (selectedOption)
                {
                    case "1":
                        Console.WriteLine("Attempting to send mail");
                        var message = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body);
                        Console.WriteLine(message);
                        break;
                    case "2":
                        Console.WriteLine("Please enter your username");
                        Console.Write("#/> ");
                        var username = Console.ReadLine();
                        Console.WriteLine("Please enter your password");
                        Console.Write("#/> ");
                        var password = Console.ReadLine();
                        Console.WriteLine("Attempting to send mail");
                        var authMessage = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body, true, username, password);
                        Console.WriteLine(authMessage);
                        break;
                    case "3":
                        Console.WriteLine("Please enter your username");
                        Console.Write("#/> ");
                        var authUsername = Console.ReadLine();
                        Console.WriteLine("Please enter your password");
                        Console.Write("#/> ");
                        var authPassword = Console.ReadLine();
                        Console.WriteLine("Attempting to send mail");
                        var authSecureMessage = SendEmail(smtpServer, smtpPort, mailFrom, mailTo, subject, body, true, authUsername, authPassword, true);
                        Console.WriteLine(authSecureMessage);
                        break;
                    default:
                        Console.WriteLine("Incorrect option!");
                        break;
                }

                Console.WriteLine("Press a key to continue...");
                Console.ReadLine();
                Console.Clear();
            }
        }

        private static string SendEmail(string server, int port, string from, string to, string subject, string body, bool authenticate = false, string user = null, string password = null, bool secure = false)
        {
            var smtpClient = new SmtpClient(server, port);
            var message = new MailMessage(from, to, subject, body);
            if (authenticate)
            {
                var credentials = new NetworkCredential(user, password);
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = credentials;

                if (secure)
                {
                    smtpClient.EnableSsl = true;
                }
            }

            try
            {
                smtpClient.Send(message);
                return "Message sent successfully";
            }
            catch (SmtpException ex)
            {
                return String.Format("There was an error. {0}", ex.Message);
            }
        }
    }
}

 

All stuff is as-is, no guarentee, blah blah blah, contact me for things.

Tags: , ,

ASP.Net

Windows 7 x64 AHCI To RAID with Network Backup Restore

by Gary Gagnon 29. December 2011 00:12

Recently I decided to go through the process of going from a single SSD to two SSD's in RAID 0.

On my first try I used an external hard drive to store the backup and created the Restore Disc using the Backup Utility Wizard.

When I switched my drive configuration from AHCI to Intel Matrix RAID, setup RAID 0, then restored my backup I was unable to boot Windows 7. I couldn't even fix it using the various utilities the backup disc provided.

I then went through the process detailed below to get it to work.

==============================================================

I went through the process of using the built-in Windows 7 Backup Utility to create a system image of my computer to a network location.

After this completed I went ahead and created the Windows 7 x64 Restore Disc that the Backup Utility Wizard will create for you.

I then rebooted my computer and changed my drive configuration in my BIOS from AHCI to RAID.

After that I went into the Intel Matrix RAID configuration and setup RAID 0 on my two SSD's. 

I then booted off of the Restore Disc to restore the network backup.

At first when I tried to access the share I kept getting an error concerning the network. Upon realizing Windows 7 wouldn't have network drivers for a newer motherboard I added the network driver for my motherboard when the wizard gives me the option.

After I was able to discover the backup I selected it.

I then loaded the Intel Matrix RAID drivers for my motherboard when the wizard gives me the option to load drivers.

After that I initiated the restore and was able to successfully boot into Windows.

==============================================================

Upon looking into this further an associate and I went through the process of testing a theory that only concerns the Intel Matrix RAID.

The theory was Windows 7 already has a driver for Intel Matrix RAID, AHCI, and Legacy IDE.

When the OS is installed it will turn on the necessary driver (AHCI or  Intel Matrix RAID).

AHCI and Intel Matrix RAID can be turned on by editing these registry entries:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\iaStorV

Set REG_DWORD Value of "Start" to Decimal Value "0"

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\msahci

Set REG_DWORD Value of "Start" to Decimal Value "0"

By having all of these set to "0" you can switch between AHCI,  Intel Matrix RAID, and Legacy IDE at will.

The way tested this is detailed below:

We had a machine with Windows 7 already installed and configured for AHCI mode with the BIOS set to AHCI.

We went into the BIOS, changed it to RAID and tried to boot into Windows 7 and it failed to boot.

We then changed the machine back to AHCI in the BIOS then successfully booted into Windows 7.

In Windows 7 regedit we then changed the value of  REG_DWORD "Start" to be Decimal Value of "0" in key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\iaStorV.

We then rebooted the computer, went into the BIOS, changed the drive configuration to RAID and booted into Windows 7 successfully.

 

The theory detailed above will only work for the Intel Matrix RAID controller built-in on all Intel Motherboards since the 3-Series Chipset.

The method detailed above this theory concerning restoring a Windows System Image from a Network location should work for all RAID controllers.

For any questions please use the "Contact" page.

Tags: , , , , ,

Windows 7 | Network Backup | AHCI | RAID

Silverlight 4 Chart Bar Series Fullscreen with INotifyPropertyChanged class using WCF Service

by Gary Gagnon 27. December 2011 17:55

I recently setup a project with a Silverlight Project, a Web Project, and a WCF Service. I built the service to get data from a remote web service and return it to a Silverlight front-end.

The Silverlight front-end included a Chart from the Silverlight Toolkit. The front-end is meant to be run in fullscreen mode in Silverlight but I found a very specific issue concerning updating the chart while in fullscreen mode at a specific time the application is put into fullscreen mode.

The chart gets updated once with the list of bar names (IndependentValue) using the WCF Service, then the bar values (DependentValue) get updated periodically using the WCF Service.

When you start the Silverlight application and immediatly go into fullscreen mode the bar names and the bar values get updated and animate the way I meant for them.

When you start the Silverlight application, wait for the bar names to show up, then go into fullscreen the chart will not update and animate the bars. Then when you go out of fullscreen the bars show that changes happened while you were in fullscreen.

I do not know why this is happening.

I've included a sample of my project below and you can view it for yourself.

Please contact me by clicking the link above if you have any idea what's going on.

BarSeriesFullscreenTest.zip (2.42 mb)

Tags: , , , , ,

Silverlight

TeamLab Version 3 Timer Update

by Gary Gagnon 16. August 2011 01:12

I have completed my update for the timer I created a while back for TeamLab 2.2. Here is the timer with full documentation contained in the download linked below for the latest version of TeamLab v3.1.21013.

I have documented the steps for adding this feature in the README.txt file included with the source files but to reiterate BACKUP YOUR DATA before doing this update. One of the updates is to a DB3 file (shown in the README) and I wouldn't want to be responsible for overwritting your data. I also included an SQL command for SQLite to update the database if you are adding this feature to an existing instance of TeamLab.

If you are a developer looking to impliment this feature I would recommend using your favorite text-comparison application to review the changes line by line and make sure they don't conflict with features you've implimented. I've included a file change list in the README for easy review.

If there's issues/bugs/complaints please let me know at gary@hazardbrick.com.

TeamLabV3TimerUpdate.zip (49.04 kb)

Tags: , , , ,

ASP.Net | TeamLab

Silverlight Catastrophic Failure

by Gary Gagnon 26. April 2011 12:29

Had a Silverlight issue this morning.

Onoez, it's a catastrophy! Lol at Silverlight.

Tags:

Silverlight

ASP.Net 4.0 C# Facebook Login Integration with Application Services Template

by Gary Gagnon 6. April 2011 22:26

This is a follow up with one of my previous posts concerning Facebook in ASP.Net 4.0 and C#. I have created a template site that will be improved upon as time passes. For now I have made the source available here. If there are any improvements to be made please let me know.

All I did was create the site using the default site created by Visual Studio 2010 when you choose a Web Application project and setup a database on my local instance of Microsoft SQL Express 2008 R2. I'm sure the code is not the greatest at the moment but it seems to be working pretty well. I tried my best to follow the second diagram found here http://developers.facebook.com/docs/user_registration/flows/.

Here is the source.

FacebookASPNetUserAccounts.zip (602.36 kb)

View the sample site at http://facebook.hazardbrick.com

(Project created in Visual Studio 2010 and uses a dll from here http://json.codeplex.com/)

Once again contact me at gary@hazardbrick.com with questions, concerns, rants, interests, or any other thing.

EDIT:

Fixed issue with Facebook login window being blocked as a popup. Also fixed issue with being asked for a password when registering with Facebook.

Tags: , , , ,

ASP.Net | Facebook

Facebook Login Registration signed_request Base64 problems in ASP.Net C#

by Gary Gagnon 5. April 2011 20:32

Recently I've been building a site that has a Facebook login integrated with it. I got to the point where I wanted to pull the data for the signed_request variable and verify that it came from Facebook. I basically translated this page http://developers.facebook.com/docs/plugins/registration/ in the "PHP Example reading signed_request" section to ASP.Net C#. I am also using the assembly Newtonsoft.Json.Net35 for the JObject found here http://json.codeplex.com/.

Here's the problem I ran into. In the PHP example Facebook gives you they do an explode on the '.' (period or dot) character and the first item is supposed to be the signature that you verify with your Application Secret. It's also supposed to be a Base64 encoded string. The problem I found is that it was 43 characters long and a Base64 string is supposed to have a character count divisible by four. You can see in my code where I do a .Split('.') on the signed_request string that you pass in from wherever your Facebook request is happening (in my case on the registration page then I call the DecodeFacebookRequest method).

For whatever reason Facebook was only giving me 43 characters. In order to figure out what the signature was actually supposed to look like I went one step further in my code (later omitted after I figured out what was going on) where I did a Convert.ToBase64String(hmacsha256.Hash) in order to see what the Base64 string was actually supposed to look like. Everything looked completely the same except the Base64 string I was getting from Facebook was missing the '=' (equals character) at the end. I then modified my Base64_Url_Decode method to append an equals character to the end of the string before using the Convert.FromBase64String method but only if the length of the string from Facebook is less than 44. That way I can still use the same method for the second part of the signed_request from Facebook without getting an Invalid Base64 String error.

Here is my code. It may not be the best way to do this but it's the way according to Facebook translated from PHP to C#.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Security.Cryptography;
using System.Configuration;

namespace ClientSite.Classes
{
    public class Facebook
    {
        public static JObject DecodeFacebookRequest(string signed_request, string secret)
        {
            var facebookData = new Dictionary<string, string>();

            var requestArray = signed_request.Split('.');

            var sig = Base64_Url_Decode(requestArray[0]);

            var dataString = Base64_Url_Decode(requestArray[1]);

            var data = JObject.Parse(dataString);

            var algo = data["algorithm"].ToString().Replace("\"", "");

            if (algo != "HMAC-SHA256")
            {
                return null;
            }

            var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
            hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(requestArray[1]));

            var expected_sig = Encoding.UTF8.GetString(hmacsha256.Hash);

            if (sig != expected_sig)
            {
                return null;
            }

            return data;
        }

        public static string Base64_Url_Decode(string input)
        {
            var fixedString = string.Empty;
            var fixedDashString = input.Replace('-', '+');
            var fixedUnderscoreString = fixedDashString.Replace('_', '/');
            if (fixedUnderscoreString.Length % 4 != 0)
            {
                fixedString = String.Format("{0}", fixedUnderscoreString);
                int paddingCount = fixedString.Length % 4;
                while (paddingCount % 4 != 0)
                {
                    fixedString += '=';
                    paddingCount++;
                }
            }
            else
            {
                fixedString = fixedUnderscoreString;
            }
            var inputBytes = Convert.FromBase64String(fixedString);
            return Encoding.UTF8.GetString(inputBytes);
        }
    }
}

I really am unsure why Facebook decided to omit the '=' at the end for padding. Perhaps the base64_decode method in PHP automatically handles that and does it for you? I'm thinking that's it and since all the examples on Facebook for anything server side is in PHP they don't really care about anything else. In any case there's my code, I hope it helps anybody trying to accomplish a page registration in an ASP.Net site using Facebook.

 

EDIT:

Changed the Base64_Url_Decode method to handle the string length a little better. After looking at the facebook documentation the variable name is $encoded_sig so I guess that gives you some clue as to the fact you need to replace invalid Base64 characters and add padding. It just isn't really documented in their documention.

Tags: , , , , ,

Facebook

TeamLab & QuickBooks Integration with Timer

by Gary Gagnon 25. March 2011 14:11

I have now completed adding a new report for our Time data so that we may easily import the time into Quickbooks. There is still one more feature left that I need to add to the Timer I created in TeamLab for the Service Item in QuickBooks. This should be completed by next week.

Here is a screenshot of the QuickBooks settings I have made available in the Management.aspx page in TeamLab. I've determined that these settings are the only specific settings you need to make the report work for the import in QuickBooks.

 

 

These settings above are needed to create a proper header in the IIF file so QuickBooks will accept it.

After creating those settings I've added a new button to my report page for the user to easily download the report they've generated as an IIF file that can be imported into QuickBooks.

Here it is shown below.

 

Upon clicking the link shown above an IIF file will be downloaded to your PC ready for import. Upon entering QuickBooks you can go to File > Utilities > Import > Timer Activities and import the time file. This is nearly seamless and should require no manual editing of time entries (once I add the Service Items). The only issue at the moment is importing time from a day of time that has already been imported. For some reason QuickBooks isn't resolving this and is just adding duplicate time entries so you have to be carefull on the date you choose for reporting. Luckily in my report on TeamLab I made sure you can pick specific days (same as the "Other" dropdown in the Time Spent report).

 

Here is the XSLT I'm using to generate the IIF file called GaryReport1_0.IIF.xsl

 

 

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" xmlns:utils="urn:my-scripts">
    <xsl:param name="VER"></xsl:param>
    <xsl:param name="REL"></xsl:param>
    <xsl:param name="COMPANYNAME"></xsl:param>
    <xsl:param name="IMPORTEDBEFORE"></xsl:param>
    <xsl:param name="FROMTIMER"></xsl:param>
    <xsl:param name="COMPANYCREATETIME"></xsl:param>
    <msxsl:script language="C#" implements-prefix="utils">
        <msxsl:assembly name="System.Web"/>
        <msxsl:using namespace="System.Web"/>
        <![CDATA[
            public string GetShortDate()
            {
                return DateTime.Now.ToShortDateString();
            }
        ]]>
    </msxsl:script>
    <xsl:output method="text" encoding="utf-8" />
    <xsl:key name="users" match="r" use="@c0" />
    <xsl:template match="*">
        <xsl:text>!TIMERHDR</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>VER</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>REL</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>COMPANYNAME</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>IMPORTEDBEFORE</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>FROMTIMER</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>COMPANYCREATETIME</xsl:text>
        <xsl:text>&#10;</xsl:text>
        
        
        
        <xsl:text>TIMERHDR</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$VER"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$REL"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$COMPANYNAME"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$IMPORTEDBEFORE"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$FROMTIMER"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="$COMPANYCREATETIME"/>
        <xsl:text>&#10;</xsl:text>
        
        
        <xsl:text>!HDR</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>PROD</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>VER</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>REL</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>IIFVER</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>DATE</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>TIME</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>ACCNTNT</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>ACCNTNTSPLITTIME</xsl:text>
        <xsl:text>&#10;</xsl:text>
        
        
        
        <xsl:text>HDR</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>QuickBooks Pro for Windows</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>Version 7.0D</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>Release R5P</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>1</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="utils:GetShortDate()"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>1300994602</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>N</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>0</xsl:text>
        <xsl:text>&#10;</xsl:text>
        
        
        
        <xsl:text>!TIMEACT</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>DATE</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>JOB</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>EMP</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>ITEM</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>PITEM</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>DURATION</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>PROJ</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>NOTE</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>BILLINGSTATUS</xsl:text>
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="r[(key('users', @c0))]"/>
    </xsl:template>
    <xsl:template match="r">
        <xsl:text>TIMEACT</xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="@c7"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="@c3"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:if test="@c9 != ''">
            <xsl:value-of select="@c8" />
            <xsl:text> </xsl:text>
            <xsl:value-of select="@c9" />
            <xsl:text> </xsl:text>
            <xsl:value-of select="@c10" />
        </xsl:if>
        <xsl:if test="@c9 = ''">
            <xsl:value-of select="@c8" />
            <xsl:text> </xsl:text>
            <xsl:value-of select="@c10" />
        </xsl:if>
        <xsl:text>&#09;</xsl:text>
        <xsl:text></xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="@c12"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="@c13"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:text></xsl:text>
        <xsl:text>&#09;</xsl:text>
        <xsl:value-of select="@c5"/>
        <xsl:text>---</xsl:text>
        <xsl:value-of select="@c2"/>
        <xsl:text>&#09;</xsl:text>
        <xsl:text>1</xsl:text>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

 

 

Here is a snippet of our IIF file generated for our company

 

 

!TIMERHDR	VER	REL	COMPANYNAME	IMPORTEDBEFORE	FROMTIMER	COMPANYCREATETIME
TIMERHDR	8	0	Wind-Up Studios	N	Y	1286922161
!HDR	PROD	VER	REL	IIFVER	DATE	TIME	ACCNTNT	ACCNTNTSPLITTIME
HDR	QuickBooks Pro for Windows	Version 7.0D	Release R5P	1	3/25/2011	1300994602	N	0
!TIMEACT	DATE	JOB	EMP	ITEM	PITEM	DURATION	PROJ	NOTE	BILLINGSTATUS
TIMEACT	3/21/2011	Wind-Up Website	Daniel Grillot		Salary	2:00		Build WindUp Website---Fixed some bugs.	1

 

 

The thing to keep in mind is the IIF file is nothing special, it's just TAB delimited text.

Another thing I did was add a Middle Initial and a Payroll Item to the Profile Page for employees because in QuickBooks your name will appear as it does on a W9 (usually with a middle initial) and it requires you to have a Payroll Item (shown as PITEM in the report template). The IIF file headers and data MUST match the same as what they're called in QuickBooks or it will either not import properly or not import at all. QuickBooks will just create new names for things if they don't already exists so you must make sure to setup your employees properly. Once that's done it should be easy for your employees to track time and easier for management to import time into QuickBooks.

If anybody has any interest in the back-end code or wants any other information email me at gary@hazardbrick.com.

Tags: , ,

QuickBooks | TeamLab