0

i want to find out that mspaint shortcut exist in desktop or no? if its exist, user score is 7 else its 0. i use this code:

  string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
  if (Directory.Exist (path + @"\mspaint.exe"))
  {
      Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
  }
  else
  {
      Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
  }

but anyway the result is "0".but this code works for directory and folders and return 7. also i try "File.Exist" but it has same problem.

How can i check a shortcut of specific program exist in desktop or no?

    if (questionNumber == 2)
        {


            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var list = Directory.EnumerateFiles(path);
            foreach (var v in list)
            {
                var extension = Path.GetExtension(v);
                if (extension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
                {
                    WshShell shell = new WshShell();
                    IWshShortcut link = (IWshShortcut)shell.CreateShortcut(v);
                    if (Path.GetFileName(link.TargetPath).Equals("mspaint.exe", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
                    }
                    else
                    {
                        Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
                    }
                }
            }



        }

when i use this, its ok, but it returns 0 for not exist and return both of 0 and 7 for exist

Ali
  • 98
  • 2
  • 14
  • 3
    The reason this doesn't work is because a shortcut is a special kind of file, it contains data which points to a location (for example mspaint.exe), but that doesn't mean it needs to be named the same as the exe it's pointing to. So it can have a name of "HappyPaint.lnk" and point to "mspaint.exe". I'd suggest modifying the question to be "how do i read a shortcuts destination". – BatteryBackupUnit Mar 13 '16 at 07:43

3 Answers3

6

Shortcut is just another type of files, as MSDN says:

When the user creates a shortcut to an object by choosing the Create Shortcut command from the object's shortcut menu, Windows stores the information it needs to access the object in a link file—a binary file that has the .lnk file name extension.

It mean that you should refer exactly to shortcut: with exact name and .lnk extension.

You need to check shortcut for example like this:

File.Exist(Path.Combine(path, "Paint.lnk"))

But in my opinion right solution is to get all shortcuts from desktop and examine target path for each one for mspaint.exe path.

For reading shortcut information read this SO post: Get target of shortcut folder

Community
  • 1
  • 1
bot_insane
  • 2,545
  • 18
  • 40
  • thanks, would you please explain about get all shortcuts from desktop and examine target path for each one for mspaint.exe path? – Ali Mar 13 '16 at 09:54
  • i tried to replace "Directory.Exists (Path.Combine(path + @"\p.lnk"))" but it has same problem and returns 0 – Ali Mar 13 '16 at 09:58
  • @Ali Do you have `p.lnk` file on your desktop(shortcut with name "p")? Also pay attention at this line: `Directory.Exist(Path.Combine(path, @"\Paint.lnk"))` – bot_insane Mar 13 '16 at 18:33
  • Change `Directory.Exist` to `File.Exist`. – bot_insane Mar 13 '16 at 19:45
  • `static void Main(string[] args) { string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); var combinedPath = Path.Combine(desktopPath, @"p.lnk"); var isShortcut = File.Exists(combinedPath); }` This is tested, working example. – bot_insane Mar 14 '16 at 12:30
  • Thank you SO MUCH! it solved my problem in a simple and easy way. you are great! – Ali Mar 14 '16 at 14:34
2

This needs explicit coding and you cannot look for names of the file in deskTop since it can be changed to anything because its just a short cut,

Include the COM addin reference Windows Script Host Object Model - Interop.IWshRuntimeLibrary

using IWshRuntimeLibrary;

public string test()
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            var list = Directory.EnumerateFiles(path);
            foreach(var v in list)
            {
                var extension = Path.GetExtension(v);
                if (extension.Equals(".lnk", StringComparison.InvariantCultureIgnoreCase))
                {
                    WshShell shell = new WshShell(); 
                    IWshShortcut link = (IWshShortcut) shell.CreateShortcut(v);
                    if (Path.GetFileName(link.TargetPath).Equals("mspaint.exe", StringComparison.InvariantCultureIgnoreCase))
                    {
                        return link.TargetPath;
                    }
                }
            }
            return null;
        }
  • hey thank you, i use your code and its working fine, but there is only a problem(update my question), when shortcut is not exist, it returns 0 but if it is exist, it returns 7 and then 0. so when it exist, i have two record in my table for this – Ali Mar 13 '16 at 18:35
  • Can you clarify what exactly you mean by "it returns 0 but if it is exist, it returns 7 and then 0" ? – Emmanuel Ponnudurai Mar 13 '16 at 19:52
  • this is for a test, if shortcut eist, the mark 7 must be submit in database, else mark 0 will be submited. but now the problem is when shortcut exist, 2record will added to table,bith of 0 and 7. but when not exist its ok and just add a record with mark 0 – Ali Mar 14 '16 at 11:53
  • @Ali You need to debug and see if there are redundant calls going to the same method. Code either goes to if OR else within a given call, it cannot execute both so it could be that the entire method is being called twice may be. Please debug Or add some logging to see what exactly is the problem. – Emmanuel Ponnudurai Mar 14 '16 at 15:25
2

A Shortcut is a special kind of file

A shortcut is a special kind of file. It contains data which points to a location (for example mspaint.exe), but that doesn't mean it needs to be named the same as the exe it's pointing to. For example, it can have a name of "HappyPaint.lnk" and point to "mspaint.exe".

Reading Shortcut Destination

Therefore you need to look for all "*.lnk" files on the desktop and read their destination paths. Here's how you can go about it:

First, add a reference to Microsoft Shell Controls And Automation: enter image description here

Second, add some code along the lines of:

string desktopDirectoryPath = Environment.GetFolderPath(
    Environment.SpecialFolder.DesktopDirectory);

string msPaintPath = Environment.ExpandEnvironmentVariables(
    @"%windir%\system32\mspaint.exe");

// add reference to COM --> Microsoft Shell controls and Automation
Shell shell = new Shell();
Folder folder = shell.NameSpace(desktopDirectoryPath);

var shortcutFilePaths = Directory.GetFiles(desktopDirectoryPath, "*.lnk");

bool msPaintShortcutExists = false;

foreach (string shortcutFilePath in shortcutFilePaths)
{
    FolderItem folderItem = folder.ParseName(Path.GetFileName(shortcutFilePath));
    Shell32.ShellLinkObject link = (Shell32.ShellLinkObject) folderItem.GetLink;
    var shortcutDestination = Environment.ExpandEnvironmentVariables(link.Path);

    if (string.Compare(
            msPaintPath, shortcutDestination, StringComparison.OrdinalIgnoreCase) == 0)
    {
        msPaintShortcutExists = true;
        break;
    }
}

if (msPaintShortcutExists)
{
    Controller.ExamController.AddExam(1, n, 7, time, Session.currentUserId);
}
else
{
    Controller.ExamController.AddExam(1, n, 0, time, Session.currentUserId);
}

Needs to be run in an STAThread

Note: In case an InvalidCastException with a message

Unable to cast COM object of type 'System.__ComObject' to interface type 'Shell32.Shell'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{286E6F1B-7113-4355-9562-96B7E9D64C54}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

occurs on new Shell(); you're not running the code in an STAThread but it needs to be run in an STAThread. An easy work around is to add the following method:

private static void ExecuteInStaThread(Action a)
{
    var thread = new Thread(() => a());
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    if (!thread.Join(TimeSpan.FromSeconds(30)))
    {
        thread.Abort();
    }
}

and wrap the code in a call to it:

ExecuteInStaThread(() =>
{
    string desktopDirectoryPath = ...
    ...
});
BatteryBackupUnit
  • 12,934
  • 1
  • 42
  • 68
  • thanks, but i have an error in this line: "msPaintShortcutExists.Should().BeTrue();" the error is:" Error 1 'bool' does not contain a definition for 'Should' and no extension method 'Should' accepting a first argument of type 'bool' could be found (are you missing a using directive or an assembly reference?) " – Ali Mar 13 '16 at 17:59
  • @Ali Ups sorry. That line was just for "unit-testing" purposes. That's how i verified the code. You can safely remove it (i've removed it from the answer, too). – BatteryBackupUnit Mar 14 '16 at 05:07