PowerShell / PowerShell/PowerShell

"Unable to cast PathInfo to String" when assigning to shell shortcut property

Open
#16,926 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue-Bug KeepOpen WG-Engine
Dominant language
C#
Stars
55.5k
Forks
8.5k
Avg merge
1d 2h
Merged PRs (30d)
88

Description

Prerequisites
Steps to reproduce

The following function creates a new shortcut (.lnk) using a Shell COM object, and then attempts to set the working directory property (without saving the shortcut).

function fn([switch]$Resolve) {
    $WorkingDirectory = if ($Resolve) {Resolve-Path "."} else {"."}
    $Shell = (New-Object -ComObject "WScript.Shell")
    # the shortcut is not actually created
    $Shortcut = $Shell.CreateShortcut("C:\shortcut.lnk")
    $Shortcut.WorkingDirectory = $WorkingDirectory
}

If you add this function into a fresh pwsh session, and then run the following 2 invocations, everything works correctly:

> fn -Resolve
> fn

However, if you run the commands in the opposite order (again in a fresh pwsh session), a type error is thrown:

> fn
> fn -Resolve
OperationStopped:
Line |
   6 |      $Shortcut.WorkingDirectory = $WorkingDirectory
     |      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Unable to cast object of type 'System.Management.Automation.PathInfo' to type 'System.String'.

My hypothesis: PowerShell somehow remembers the first type that is assigned into a property of a COM object, and then refuses any other type (even if the second type can be normally implicitly casted to the first type). However, this only works in one direction (when the first type is a String, which matches the expected type of the property), but not in the other (when the first type is something that can be implicitly casted to the correct type (String in this case)). No idea why, quite curious. :)

Expected behavior

Both invocations should succeed, independent of the order.

Actual behavior

A type error is thrown if the first assignment assigns a String, and the second assignment assigns a different type, even if has an implicit cast to String.

Error details
Exception             :
    Type       : System.InvalidCastException
    TargetSite :
        Name          : ChkCast_Helper
        DeclaringType : System.Runtime.CompilerServices.CastHelpers, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e
        MemberType    : Method
        Module        : System.Private.CoreLib.dll
    Message    : Unable to cast object of type 'System.Management.Automation.PathInfo' to type 'System.String'.
    Data       : System.Collections.ListDictionaryInternal
    Source     : System.Private.CoreLib
    HResult    : -2147467262
    StackTrace :
   at CallSite.Target(Closure , CallSite , ComObject , Object )
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
   at System.Management.Automation.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
CategoryInfo          : OperationStopped: (:) [], InvalidCastException
FullyQualifiedErrorId : System.InvalidCastException
InvocationInfo        :
    ScriptLineNumber : 6
    OffsetInLine     : 5
    HistoryId        : -1
    Line             :     $Shortcut.WorkingDirectory = $WorkingDirectory

    PositionMessage  : At line:6 char:5
                       +     $Shortcut.WorkingDirectory = $WorkingDirectory
                       +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at fn, <No file>: line 6
                        at <ScriptBlock>, <No file>: line 1
Environment data
Name                           Value
----                           -----
PSVersion                      7.3.0-preview.1
PSEdition                      Core
GitCommitId                    7.3.0-preview.1
OS                             Microsoft Windows 10.0.19044
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Visuals

image

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the COM shortcut assignment in a fresh pwsh session using the function and both invocation orders shown in the issue. Trace the PowerShell COM property-assignment path responsible for the cast, then verify that assigning a string and a PathInfo succeeds in either order without the reported InvalidCastException.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, powershell
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.