none
IWshRuntimeLibrary.IWshShortcut shortcut not working with special chars RRS feed

  • Question

  • Hello All,

    We are using IWshRuntimeLibrary.IWshShortcut shortcut to create shorcut. It is working fine with all English characters but errors out for special characters from other languages.

    Is there a way this library can recognize special characters as well?


    Please remember to mark the reply as answer if it has helped.

    Thursday, May 2, 2019 12:00 PM

Answers

  • I got some time to test this and the ShellLinkObjectClass isn't directly creatable which is sort of odd for COM. But I did find a post from years ago on SO that tells how to work around this by creating a dummy link and then updating here. Here's the updated code.

    static void CreateLink ( string sourcePath, string targetPath, string description )
    {
        File.WriteAllBytes(targetPath, new byte[0]);
    
        var shell = new Shell32.ShellClass();
    
        var folder = shell.NameSpace(Path.GetDirectoryName(targetPath));
        var item = folder.Items().Item(Path.GetFileName(targetPath));
    
        var link = item.GetLink as ShellLinkObject;            
    
        link.Path = sourcePath;
        link.Description = description;
    
        link.Save(targetPath);
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, May 2, 2019 2:39 PM
    Moderator
  • I did some research and folks are suggesting to use [STAThread] on Main class. Not sure what would be the impact if you are using multiple threads in your program.

    Generally, COM objects provided by the windows shell are designed to be instantiated in and used from an STA (single threaded apartment).  That is the basis for the [STAThread] recommendation.   Calls to a shell COM object in an STA should ordinarily be made from the same thread that was used to instantiate the COM object.

    Of course, nothing prevents you from using multiple threads in an application for other purposes.

    Thursday, May 2, 2019 4:53 PM
  • WSH is the Windows Scripting Host. It's sole purpose was to providing a way for scripting languages to interact with the shell. If you're not using a scripting language then there is on reason to load the scripting host so it can call the shell on your behalf. Just use the shell directly. 

    WScript, for which WSH supported, was deprecated years ago. While it is not officially removed yet it hasn't been updated in a long time and all the current stuff will recommend PowerShell. So using WSH to get to the shell rather than using the COM interfaces directly is probably not a good investment.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, May 2, 2019 5:37 PM
    Moderator

All replies

  • Sounds like you're trying to use the Windows Script Host Object Model but I wouldn't do that. That is an old COM  object that honestly I thought had been removed. To create a shortcut use the Shell directly. Something along these lines might work but I haven't tested it yet.

    [STAThread]
    static void Main ( string[] args )
    {
        CreateLink(@"C:\temp\test.txt", @"C:\temp\shortcut Link", "Testing");            
    }
    
    static void CreateLink ( string sourcePath, string targetPath, string description )
    {
        var link = new ShellLinkObjectClass();
    
        link.Path = sourcePath;
        link.Description = description;
    
        var file = link as IPersistFile;
        file.Save(targetPath, true);
    }
    To get this to work add a reference to the Microsoft Shell Controls and Automation COM object to your project. Also be sure to set the property for embedding COM to false otherwise it will fail at runtime.

    Note that the Windows API Code pack used to have support for shell links. I don't know that you could create shortcuts with it but it at least has some starter code you can use.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, May 2, 2019 2:15 PM
    Moderator
  • I got some time to test this and the ShellLinkObjectClass isn't directly creatable which is sort of odd for COM. But I did find a post from years ago on SO that tells how to work around this by creating a dummy link and then updating here. Here's the updated code.

    static void CreateLink ( string sourcePath, string targetPath, string description )
    {
        File.WriteAllBytes(targetPath, new byte[0]);
    
        var shell = new Shell32.ShellClass();
    
        var folder = shell.NameSpace(Path.GetDirectoryName(targetPath));
        var item = folder.Items().Item(Path.GetFileName(targetPath));
    
        var link = item.GetLink as ShellLinkObject;            
    
        link.Path = sourcePath;
        link.Description = description;
    
        link.Save(targetPath);
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, May 2, 2019 2:39 PM
    Moderator
  • I had tried this solution earlier and it thrown the error:

    Exception 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.

    I did some research and folks are suggesting to use [STAThread] on Main class. Not sure what would be the impact if you are using multiple threads in your program.


    Please remember to mark the reply as answer if it has helped.

    Thursday, May 2, 2019 4:34 PM
  • Do we have any reference which says that WSH is obsolete and we should use shell32 instead?

    Please remember to mark the reply as answer if it has helped.

    Thursday, May 2, 2019 4:35 PM
  • I did some research and folks are suggesting to use [STAThread] on Main class. Not sure what would be the impact if you are using multiple threads in your program.

    Generally, COM objects provided by the windows shell are designed to be instantiated in and used from an STA (single threaded apartment).  That is the basis for the [STAThread] recommendation.   Calls to a shell COM object in an STA should ordinarily be made from the same thread that was used to instantiate the COM object.

    Of course, nothing prevents you from using multiple threads in an application for other purposes.

    Thursday, May 2, 2019 4:53 PM
  • WSH is the Windows Scripting Host. It's sole purpose was to providing a way for scripting languages to interact with the shell. If you're not using a scripting language then there is on reason to load the scripting host so it can call the shell on your behalf. Just use the shell directly. 

    WScript, for which WSH supported, was deprecated years ago. While it is not officially removed yet it hasn't been updated in a long time and all the current stuff will recommend PowerShell. So using WSH to get to the shell rather than using the COM interfaces directly is probably not a good investment.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, May 2, 2019 5:37 PM
    Moderator
  • Thank you every one.

    Please remember to mark the reply as answer if it has helped.

    Thursday, May 2, 2019 5:41 PM