0

In my program I want to give the user the ability to create a shortcut.

I tried using the IWshRuntimeLibrary, but it doesn't support Unicode character, and therefore fails.

I have found this answer, and it works when I copy it exactly like it is, but doesn't work when I put it in a function and use variables.

This is the code I use:

public static void CreateShortcut(string shortcutName, string shortcutPath, string targetFileLocation, string description = "", string args = "")
{
    // Create empty .lnk file
    string path = System.IO.Path.Combine(shortcutPath, $"{shortcutName}.lnk");
    System.IO.File.WriteAllBytes(path, new byte[0]);
    // Create a ShellLinkObject that references the .lnk file
    Shell32.Shell shl = new Shell32.Shell();
    Shell32.Folder dir = shl.NameSpace(shortcutPath);
    Shell32.FolderItem itm = dir.Items().Item(shortcutName);
    Shell32.ShellLinkObject lnk = (Shell32.ShellLinkObject)itm.GetLink;
    // Set the .lnk file properties
    lnk.Path = targetFileLocation;
    lnk.Description = description;
    lnk.Arguments = args;
    lnk.WorkingDirectory = Path.GetDirectoryName(targetFileLocation);
    lnk.Save(path);
}

As you can see, it is the same exact code. The only difference is the use of variables instead of hard-coded values.

I call the function like so: Utils.CreateShortcut("Name", @"D:\Desktop", "notepad.exe", args: "Demo.txt");

And I get a System.NullReferenceException for the line Shell32.ShellLinkObject lnk = (Shell32.ShellLinkObject)itm.GetLink; because itm is null.

SagiZiv
  • 932
  • 1
  • 16
  • 38
  • I didn't downvote, but the the possible reasons for which downvotes _should_ be given are available - hover your mouse over the downvote button on any questions and a summary of the most common reasons appears. There's also more info at https://stackoverflow.com/help/privileges/vote-down . Of course that doesn't stop people mis-using the feature, but the wisdom of crowds will generally prevail - if one person mis-uses it, then other will generally vote up to compensate. – ADyson Dec 06 '20 at 20:41
  • Anyway have you tried working out _why_ `itm` is null in your version? What debugging have you done? – ADyson Dec 06 '20 at 20:42
  • Thanks for the downvote tip I didn't know about it. I tried to use hard coded values instead of variables and it works, I can't find any reason that switching to variables would break the code. The strings are equal and the path is valid – SagiZiv Dec 06 '20 at 20:54
  • For absolute clarity for us, show us the hard-coded version, using your values and code (not just the tutorial's), which you say works for you. – ADyson Dec 06 '20 at 20:58
  • Also please respond to my query about debugging. Have you attempted to work out where things start to go wrong, leading to `itm` being null? – ADyson Dec 06 '20 at 20:58
  • I tried to check what dir.Items() returns but it looks fine. The problem is that I can't see any of the inside variables of this object so I can't tell exactly what goes wrong – SagiZiv Dec 06 '20 at 21:13
  • 1
    Thanks for the edit...but if you found the solution it should go in the Answers section, not in the question! Then people can vote on it if they find it useful. – ADyson Dec 06 '20 at 21:46
  • 1
    I've rolled back your edit. It is not appropriate to add the solution to the question. If you found a solution and want to share, do so by writing an answer in the space provided below for that purpose. See [Can I answer my own question?](http://stackoverflow.com/help/self-answer) – Ken White Dec 07 '20 at 02:23

1 Answers1

1

I have found the problem.

This line: System.IO.Path.Combine(shortcutPath, $"{shortcutName}.lnk");

I add the ".lnk" extension to the file name, but when I search for it with dir.Items().Item(shortcutName); it doesn't have the extension.

The solution: Write at the beginning of the function shortcutName += ".lnk";

And get the path like so: System.IO.Path.Combine(shortcutPath, shortcutName);

SagiZiv
  • 932
  • 1
  • 16
  • 38