jmgibbo
jmgibbo

Reputation: 97

How can I get the start menu name of running applications using c#?

I am able to get the process name using the below code but how do I get the application name that an end user is familiar with i.e. instead of getting WinWord I would like to display Word 2013 as shown in the start menu.

foreach (var p in Process.GetProcesses())
{
   try
   {
     if (!String.IsNullOrEmpty(p.MainWindowTitle))
       {
         Console.WriteLine(String.Format("Process Name: " + p.ProcessName.ToString()));
       }
     }
   catch
   {
   }
}

Upvotes: 2

Views: 452

Answers (1)

Tomer
Tomer

Reputation: 1704

I couldn't find the "start menu" name anywhere in the executable file description. For example, the file WINWORD.EXE has Product Name "Microsoft Office 2016" and File Description "Microsoft Word", when viewing the executable details in the file explorer.

This leads me to think that in order to find the "start menu" name, we should actually look at the start menu. We can do it by enumerating all the lnk files in it, and keeping a mapping between the "start menu" name (which is simply the file name of the lnk file) and the executable it links to.

One we have this mapping, we can query it for the processes we get from GetProcesses().

Example code (add Windows Script Host Object Model as a COM reference):

public static string GetShortcutTargetFile(string shortcutFilename)
{
    if (File.Exists(shortcutFilename))
    {
        var shell = new WshShell();
        var link = (IWshShortcut)shell.CreateShortcut(shortcutFilename);

        return link.TargetPath;
    }

    return string.Empty;
}

public static Dictionary<string, string> CreateDictionary(string path)
{
    var dictionary = new Dictionary<string, string>();

    foreach (var filePath in Directory.EnumerateFiles(path, "*.lnk", SearchOption.AllDirectories))
    {
        var lnkPath = GetShortcutTargetFile(filePath);
        if (lnkPath.Length > 0 && !dictionary.ContainsKey(lnkPath))
        {
            dictionary.Add(lnkPath, Path.GetFileNameWithoutExtension(filePath));
        }
    }

    return dictionary;
}

static void Main()
{
    var startMenuLocation = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu);
    var dictionary = CreateDictionary(startMenuLocation);

    foreach (var p in Process.GetProcesses())
    {
        try
        {
            if (!string.IsNullOrEmpty(p.MainWindowTitle))
            {
                var pair = dictionary.FirstOrDefault(entry => entry.Key.Contains(p.ProcessName));
                var prettyName = pair.Value;
                Console.WriteLine(string.Format("Process Name: " + prettyName));
            }
        }
        catch
        {
        }
    }
}

As ReneA pointed out in the comments, the code only enumerates the shared start menu folder. One might want to enumerate the users' start menu folders as well.

This code is not thoroughly tested or guarded against corner cases. Use at your own risk.

Upvotes: 2

Related Questions