Jonas Stawski

Everything .NET and More

Home Made Digital Picture Frame and Live Mesh

A couple of months back I had decided to turn an old laptop into a digital picture frame (DPF). This post is not about how to turn the laptop into a DPF, but rather how I integrated the DPF with Live Mesh. There are plenty of articles and blogs on how to create your own DPF here. My overall architecture of the project:

Old Laptop running Windows XP.

Windows Slide Show pointing to a Live Mesh Folder.

Custom written code to restart the slide show.

Scheduled task to hibernate and wake up the computer (to save energy).

The Build

I’m not going to go over the details on how I built the picture frame because each laptop and frame is different for details on how to do it you can search the web. I got a picture frame from Michaels and some thick cardboard to fill the gaps between the laptop and the frame. I got rid of all the unnecessary hardware that made the laptop heavier, such as the CD-ROM, keyboard, mouse, battery, screws, extra plastic, etc. I kept the wireless antennas so I can connect remotely just in case I need to perform some maintenance on it and so it can have internet connection. I then removed all the unnecessary programs from the computer.

IMG_1703 IMG_1706 IMG_1707 IMG_1708 IMG_1709

The Show

My next step was to set up the slide show to show the pictures. I went through a couple of options, but I decided the best and simplest option was to use the Windows XP “My Picture Slideshow” screen saver.

ScreenSaver

The settings are pretty straight forward and it allows you to set how fast the picture should change, how big should the picture be, the folder where to get the pictures from, whether to use transition effects, and a few other options. I also set the screen saver to pop up after a minute of idleness.

Adding New Images

I originally created a folder and shared it through my home network. I set the screen saver to read the images of the shared folder. It worked wonderfully and for WAF (Wife Acceptance Factor), as Scott H likes to say, I mapped a drive on her computer and taught her to simply drag and drop the images she wants to display in the DPF to that folder. That worked perfectly, but it had a limitation: we had to be inside the home network to update the pictures displayed on the frame.

Then came Live Mesh. I decided to create a folder specifically for the Digital Picture Frame. I installed the Live Mesh client on the DPF and on all the other computers where I wanted to control it from. I then changed the folder of the screen saver to point to this new Live Mesh folder. Now I can easily move files from any computer that has internet access, even my new HTC Touch Pro. The best thing is the DPF doesn’t have to be on, once it turns on it will synchronize automatically with Live Mesh. It works like a charm, but there is one catch, when the screen saver loads it caches all the images in memory so if new images are added while the screen saver is running they won’t show until the next run. So it was time for some custom coding.

LiveMesh

Refreshing the Screen Saver

I decided to write a console application that runs at start up and takes 2 parameters: a path to watch for activity and what to execute if something changes. This case was screaming for a Windows Service rather than a Console App, but they are hard to debug and a pain in the *** to create and install. It is running Windows XP anyway and it needs a logged in user to run so either way it works.

The app simply listens for any change on a folder (the Live Mesh folder) and if anything changes it runs a batch file that contains the following line:

C:\Windows\System32\ssmypics.scr /s

That line simply tells windows to start the Slideshow Screen Saver.

So whenever a new file is added, deleted, changed, or renamed the screen saver is restarted and the modification are shown immediately.

Desktop

Here’s the code for the console app:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
 
namespace DirectoryWatcher
{
    class Program
    {
        static string folder;
        static string argument;
        static void Main(string[] args)
        {
            //Get and Verify the arguments
            if (args.Length != 2)
            {
                Console.WriteLine("Invalid Arguments");
                return;
            }
            foreach (string arg in args)
            {
                if (arg.Contains("--f="))
                    folder = arg.Replace("--f=", "");
                else if (arg.Contains("--a="))
                    argument = arg.Replace("--a=", "");
 
            }
            if (String.IsNullOrEmpty(folder) || string.IsNullOrEmpty(argument))
            {
                Console.WriteLine("Invalid Arguments");
                return;
            }
            if (!Directory.Exists(folder))
            {
                Console.WriteLine("Invalid Directory!");
                return;
            }
            FileSystemWatcher fs = new FileSystemWatcher();
            fs.Path = folder;
            fs.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                | NotifyFilters.FileName | NotifyFilters.DirectoryName;
 
            fs.Changed += new FileSystemEventHandler(fs_Changed);
            fs.Changed += new FileSystemEventHandler(fs_Changed);
            fs.Created += new FileSystemEventHandler(fs_Changed);
            fs.Deleted += new FileSystemEventHandler(fs_Changed);
            fs.Renamed += new RenamedEventHandler(fs_Changed);
 
 
            fs.IncludeSubdirectories = true;
            fs.Filter = "*.*";
            fs.EnableRaisingEvents = true;
 
            Console.WriteLine("Watching " + folder);
            Console.ReadLine();
 
        }
 
        static void fs_Changed(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine(String.Format("{0} - {1}", e.Name, e.ChangeType.ToString()));
            Process p = Process.Start(argument);
            p.WaitForExit(30000);
            if (!p.HasExited)
            {
                p.Kill();
            }
        }
    }
}

Warning: this code is a great example of “Works On My Machine” Certification Program and it certainly needs some more work such as ignoring some changes to some files like the Desktop.ini file.

Conclusion

If you don’t know what to do with an old laptop, don’t want to spend hundreds of dollars on a small digital picture frame, and are very handy then I recommend taking on this project. It feels great to show off your very own Home Made Digital Picture Frame.

IMG_1710 IMG_1712 IMG_1711

Happy Framing!

Comments (3) -

That's a nice simple solution that works great.  For a "fancier" solution that may be possible in the future, check out this video that shows a digital picture frame, a printer, and more, all tied into a Mesh as devices.
http://channel9.msdn.com/pdc2008/BB35/

Reply

Hey Now Jonas,
Nice Post pretty neat concept.

Thx,
Catto

Reply

An added hurdle is use of the Windows Event Log. The .net framework provides the System.Diagnostics.EventLog  classes to enable you to easily write (and read) events. Merrily you scatter log events throughout your code;

Reply

Add comment

biuquote
Loading