How to create a file link through windows command and define start in directory for that link?

375 views Asked by At

I need to make a shortcut for my application and the shortcut needs to have the same icon, so no bat files come into consideration instead of the shortcut. I also want a native windows solution or .NET 5.0 solution, not a third party program, I want to be as low to the source as possible.

I've tried mklink but it does not provide an option to set shortcut's "Start in:" directory which is crucial for my app for which I need to make a shortcut.

1

There are 1 answers

0
AudioBubble On BEST ANSWER

This is what I made for myself:

public class DesktopUtility : IDesktopUtility
{
    public void CreateShortcut(string targetPath, string shortcutLinkPath)
    {
        if (!shortcutLinkPath.EndsWith(".lnk"))
            shortcutLinkPath += ".lnk";

        CreateShortcutVBS(targetPath, shortcutLinkPath);
        if (!File.Exists(shortcutLinkPath))
            CreateShortcutPS(targetPath, shortcutLinkPath);
    }

    public void CreateShortcutVBS(string targetPath, string shortcutLinkPath)
    {
        if (!shortcutLinkPath.EndsWith(".lnk"))
            shortcutLinkPath += ".lnk";

        var workingDirectory = Path.GetDirectoryName(targetPath);
        var vbShortcutScript = "Set oWS = WScript.CreateObject(\"WScript.Shell\")\n" +
            $"sLinkFile = \"{shortcutLinkPath}\"\n" +
            "Set oLink = oWS.CreateShortcut(sLinkFile) \n" +
            $"oLink.TargetPath = \"{targetPath}\"\n" +
            $"oLink.WorkingDirectory = \"{workingDirectory}\"\n" +
            "oLink.Save";
        var fileName = Path.GetFileNameWithoutExtension(targetPath);
        var scriptFilePath = Path.Combine(workingDirectory, $"{fileName}.vbs");
        //var wscriptPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), @"System32\wscript.exe");
        try
        {
            using (var file = File.CreateText(scriptFilePath))
                file.Write(vbShortcutScript);
            var psi = new ProcessStartInfo
            {
                FileName = "wscript.exe",
                UseShellExecute = false,
                Arguments= $"/b \"{scriptFilePath}\""
            };
            Process.Start(psi).WaitForExit();
        }
        finally
        {
            if (File.Exists(scriptFilePath))
                File.Delete(scriptFilePath);
        }
    }

    public void CreateShortcutPS(string targetPath, string shortcutLinkPath)
    {
        if (!shortcutLinkPath.EndsWith(".lnk"))
            shortcutLinkPath += ".lnk";

        var workingDirectory = Path.GetDirectoryName(targetPath);

        var psi = new ProcessStartInfo
        {
            FileName = "powershell.exe",
            WindowStyle = ProcessWindowStyle.Hidden
        };
        psi.Arguments =
            "-windowstyle hidden  " +
            "$WshShell=New-Object -comObject WScript.Shell; " +
            $"$LinkPath = \\\"{shortcutLinkPath}\\\"; " +
            $"$Shortcut = $WshShell.CreateShortcut($LinkPath); " +
            $"$Shortcut.TargetPath = \\\"{ targetPath}\\\"; " +
            $"$Shortcut.WorkingDirectory = \\\"{workingDirectory}\\\"; " +
            "$Shortcut.Save();";
        Process.Start(psi).WaitForExit();
    }
}

I don't like the PowerShell method because it briefly shows the window, and I would like to be able to execute vbscript inline, not through file, don't know how.