Introduction
If you have a lot of applications installed on your computer your "start->All Programs->.." folder is probably packed with all sorts of links. Searching for a particular application to start may not be a pleasant experience when you don't really remember the path to the application or when the folder contains too many links.
Wouldn't it be great if you could just type the name of the application (or part of it) and have the computer provide you with all the apps matching that name and then in one key-press launch it?
This small 'Starter' application does just that. It works in Windows XP and uses the .NET 2.0 Framework.
Type the application name or part of it and press enter:
Now select the application you want to run from the filtered matching list using the up/down arrows and hit enter to launch it:
Note that Windows Vista provides similar functionality in its core operating system start menu. Now we can do it in Windows XP as well.
Configuration Options
Right click the icon to the left of the combo box to open the context menu. Then select Advanced Settings in order to view the Settings form.
Additional customization can be made here, e.g. indicating the folder where you would seek the shortcut file.
Recommendation: Configure Starter to Always Popup on Alt+Cntl+L
The 'Starter' is a single instance application. If someone attempts to start a new instance of the Starter application while another instance already exists, the focus will shift to the existing 'Starter' application without creating a new instance.
It helps a lot to create a shortcut to the starter application and assign a keyboard key to it (I used Alt+Cntl+L), so that whatever you do with your computer you can always enter Alt+Cntl+L and have the focus switched to the starter application.
Before I had this application, I used the 'Quick Launch' Toolbar extensively, but since I have this program I removed the Quick Launch shortcuts and am only using this tool to launch my applications. It is quicker, and my taskbar area is cleaner and better utilized.
How Does It Work?
Upon startup, the application scans all shortcut (*.lnk) file names and attributes under the Start --> All Program menu. It will also lookup shortcut files in other folders specified in the custom configuration section (as mentioned in the configuration options section). The shortcut file names and attributes are stored in a DataTable
object. A DataView
object is used to filter the content based on the user input.
When the user types a string in the combo box and hits the Enter key, the combo box is populated with all the program files that contain this string. If the user hits Enter while a selected application is highlighted the application will be launched. So just type the application name (or part of it), hit enter to get the list of matching applications and enter again to launch the application you want. Easy.
The application is a very small form with no borders and it is configured by default to be Top-most located in the upper right corner (just below a title bar of a potential maximized window). You can move the application by dragging its left icon. To view additional options, right-click the left icon and a popup menu shows.
The code segment for seeking and storing the shortcut file names is as follows:
private void ProcessFolder(string folderName) {
if (!System.IO.Directory.Exists(folderName))
return;
DirectoryInfo d = new DirectoryInfo(folderName);
foreach (FileInfo f in d.GetFiles()) {
if (f.Extension.ToLower() == ".lnk")
ProcessShortcutFile(f);
}
foreach (DirectoryInfo di in d.GetDirectories())
ProcessFolder(di.FullName);
}
private void ProcessShortcutFile(FileInfo f) {
FileInfo fi;
if (System.IO.File.Exists(f.FullName)) {
WshShortcut theShortcut = (WshShortcut)theShell.CreateShortcut(f.FullName);
if (System.IO.File.Exists(theShortcut.TargetPath)) {
fi = new FileInfo(theShortcut.TargetPath);
if (mExtentions.Contains(fi.Extension.ToLower())) {
string name;
name = f.Name.Substring(0, f.Name.Length - 4);
if (name.Contains("Shortcut to ")) {
if (name.IndexOf("Shortcut to ") == 0) {
name = name.Replace("Shortcut to ", "");
}
}
mRowArgs[0] = name;
mRowArgs[1] = ReplaceEnvVar(theShortcut.TargetPath);
mRowArgs[2] = ReplaceEnvVar(theShortcut.WorkingDirectory);
mRowArgs[3] = theShortcut.Arguments;
mRowArgs[4] = ReplaceEnvVar(theShortcut.IconLocation);
mRowArgs[5] = ReplaceEnvVar(f.FullName);
if (mRowArgs[4].Split(',')[0] == "") {
mRowArgs[4] = mRowArgs[1] + mRowArgs[4];
}
if (Properties.Settings.Default.SelectDistinctShortcutFiles) {
if (!mAllTargetFilesAndArguments.Contains(mRowArgs[1] +
" " + mRowArgs[3])) {
mAllTargetFilesAndArguments.Add(mRowArgs[1] + " " + mRowArgs[3]);
mDataTable.Rows.Add(mRowArgs);
}
} else {
mDataTable.Rows.Add(mRowArgs);
}
}
}
}
}
Scanning the Shortcut Files
I'm using the DirectoryInfo
and FileInfo
classes in the System.IO
namespace to iterate through all the shortcut files within the specified folders. Then I'm using the WshShortcut
COM object to get the TargetPath
, Arguments
, WorkingDirectory
, and IconLocation
properties of the shortcut file. If you know of a pure .NET object I could use to gather the information in the shortcut file, please let me know.
Extracting the Icons from the Applications
The started application uses an owner drawn combo box that shows the icons of the applications along with their shortcut file names. To extract the Icons from the applications, I'm using the IconExtractor
class which in turn uses the ExtractIconExW
from the Shell32.dll.
Populating the List-box
When the user enters a string
(3 characters long at least) and then presses Enter, the PopulateComboItems()
method is called. Then the DataView
gets filtered and returned to the MainForm
.
Here are the relevant code segments. cmb
is the ComboBox
object. dvComboDataSource
is the DataView
object.
private void PopulateComboItems() {
dvComboDataSource = sStartApps.GetMatchingLinks(cmb.Text);
cmb.DataSource = dvComboDataSource;
cmb.DisplayMember = "ShortcutName";
}
Here is the method which retrieves the filtered DataView
:
public DataView GetMatchingLinks(string s) {
s = s.Trim();
if (s.Length > 2) {
mDataView.RowFilter = @"ShortcutName like '%" + s + @"%'";
return mDataView;
} else {
return null;
}
}
Launching the Application
When the user hits Enter upon selected list box item, the cmb_KeyDown
event is responsible for detecting the Enter key and launching the appropriate application based on the dvComboDataSource
object.
void cmb_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
switch (e.KeyCode) {
case Keys.Enter:
if (cmb.SelectedIndex >= 0) {
cmb.Cursor = System.Windows.Forms.Cursors.AppStarting;
e.SuppressKeyPress = true;
p.BackColor = Color.LightGreen;
p.Invalidate();
System.Diagnostics.Process.Start(SelectedItem("ShortcutFullName"));
cmb.Cursor = System.Windows.Forms.Cursors.Default;
} else {
. . .
. . .
. . .
}
private string SelectedItem(string itemName) {
return ((DataRowView)cmb.SelectedItem)[itemName].ToString();
}
Starter is a Single Instance Application
The code below checks all the system processors upon the Starter application startup. If another instance of the Starter application is already running, then it just switches to it. We use the AppActivate()
method of the WshShellClass
COM object.
[STAThread]
static void Main() {
System.Diagnostics.Process p;
if (OtherInstanceExists(out p)) {
IWshRuntimeLibrary.WshShellClass shell =
new IWshRuntimeLibrary.WshShellClass();
object p1 = (object)p.Id;
object p2 = (object)null;
shell.AppActivate(ref p1, ref p2);
} else {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
static bool OtherInstanceExists(out Process proc) {
Process[] p = Process.GetProcessesByName(
Process.GetCurrentProcess().ProcessName);
proc = null;
if (p.Length > 0) {
if (p.Length == 1) {
if (p[0].Id==Process.GetCurrentProcess().Id) {
return false;
} else {
proc = p[0];
return true;
}
} else {
foreach (Process pr in p) {
if (pr.Id != Process.GetCurrentProcess().Id) {
proc = pr;
}
}
return true;
}
} else {
return false;
}
}
Remarks
- Shortcut files which point to URLs (*.url) are not added to the
DataTable
. If you want to have URLs included, just add a shortcut for Internet Explorer and provide the URL you're interested in as its argument.
- The application uses COM interop for three types of operations:
- Evaluating the content of the shortcut files (what is the target file, working directory, arguments, etc.)
- Making Starter a single instance application
- Extracting Icons from the target files.
If you know a pure .NET way of doing any one of these tasks, please let me know.
- The search
string
must be at least 3 characters long or else no search results will be returned.
History
- 3rd March, 2007: Initial post