Pester TestDrive issue with Com objects

Tagged: ,

This topic contains 5 replies, has 2 voices, and was last updated by Profile photo of Dave Wyatt Dave Wyatt 9 months ago.

  • Author
    Posts
  • #36433
    Profile photo of Michael Willis
    Michael Willis
    Participant

    I made a simple test example from a larger test I've been working on.
    http://pastebin.com/cqDzaJiM

    In this example I'm trying to get two tests to pass. The first being that the file has been created to the testdrive, and the second being that the target path of the .lnk file is correct.

    I'm not having any luck getting the second test `Has the correct targetPath` to pass.

    Any ideas?

  • #36434
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    It's a common oversight in PowerShell cmdlets / functions to pass PSPaths on to .NET or COM methods (which know nothing about PowerShell drives / etc). In this case, your Get-Target function is passing its $ShortcutPath parameter straight to $WshShell.CreateShortcut, without resolving it to a file system path that the WScript.Shell object will understand.

    You can modify your code to use the same (Resolve-Path $ShortcutPath).ProviderPath method that you're using in your BeforeAll block, but personally, I prefer to make my function an advanced function and use the $PSCmdlet.GetUnresolvedProviderPathFromPSPath() method. (The reason being that Resolve-Path will throw an error if the file / directory doesn't exist, and the latter method will just translate the path without caring whether the item exists or not.)

    function Set-Shortcut
    {
        [CmdletBinding()]
        param (
            [string] $ShortcutPath,
            [string] $Target
        )
    
        $WshShell = New-Object -ComObject WScript.Shell
        $Shortcut = $WshShell.CreateShortcut($PSCmdlet.GetUnresolvedProviderPathFromPSPath($ShortcutPath))
        $Shortcut.TargetPath = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Target)
        $Shortcut.Save()
    }
    
    function Get-Target
    {
        [CmdletBinding()]
        param (
            [string] $ShortcutPath
        )
    
        $WshShell = New-Object -ComObject WScript.Shell
        $Shortcut = $WshShell.CreateShortcut($PSCmdlet.GetUnresolvedProviderPathFromPSPath($ShortcutPath))
        return $Shortcut.TargetPath
    }
    
  • #36436
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    In testing the code, it also appears that the shortcut paths aren't saving. Not sure why. If you set a breakpoint on the $Shortcut.Save() line, you'll see what I mean; $Shortcut.TargetPath is blank, even though it was just assigned on the previous line.

  • #36439
    Profile photo of Michael Willis
    Michael Willis
    Participant

    Thanks Dave I got it worked out now!

    I added a gist example of the full test:

    Your support has been invaluable for getting me up to date with DSC and Powershell.

  • #36443
    Profile photo of Michael Willis
    Michael Willis
    Participant

    ![pester-shortcut-path](https://cloud.githubusercontent.com/assets/11132362/13714805/744188de-e796-11e5-9ac9-7f26d8e49986.png)

    Dave, it looks like it's working for me from that Gist. I updated the Gist, I was using $TargetPath and you were using $Target, perhaps that was the issue?

  • #36444
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Yep, I copied and pasted your code and it worked fine. I had already closed my ISE window from before, so I'm not sure what's different from when I was seeing problems.

You must be logged in to reply to this topic.