Search code examples
powershellwindows-runtime

powershell : comma and parameters inside a class brackets?


i saw that script somewhere :

[Windows.Globalization.Calendar,Windows.Globalization,ContentType=WindowsRuntime]::New().GetTimeZone()

And i was wondering what is the 2 parameters that was write after Windows.Globalization.Calendar ?

Also, if you know it, could you give me the C# equivalent of this [Class, ???, ???]::new()?


Solution

  • Answer 1

    It's some undocumented trick. The syntax isn't defined anywhere. The first two components in [Windows.Globalization.Calendar, Windows.Globalization, ContentType=WindowsRuntime] can be easily deduced: these are full name of the class and its namespace. BTW, namespace seems redundant here. [Windows.Globalization.Calendar, $Null, ContentType=WindowsRuntime] works for me as well.

    The third component apparently hints at Windows Runtime. Its format looks like a magic constant – it's hard to be more definite as Windows PowerShell is closed-source. One can find this string in the names of Windows Runtime assemblies:

    PS > [Windows.Globalization.Calendar, $Null, ContentType=WindowsRuntime].Assembly.FullName
    Windows.Globalization, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime
    
    PS > [Windows.Globalization.Calendar, $Null, ContentType=WindowsRuntime].AssemblyQualifiedName
    Windows.Globalization.Calendar, Windows.Globalization, Version=255.255.255.255, Culture=neutral, PublicKeyToken=null, ContentType=WindowsRuntime
    

    I suppose that upon encountering ContentType=WindowsRuntime PowerShell (or .NET Framework on its behalf) tries to resolve the given class name as a Windows Runtime type. OS-wide metadata for Windows Runtime reside in %SystemRoot%\system32\WinMetadata. Metadata for particular namespace can be located using WindowsRuntimeMetadata class:

    PS > [System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMetadata]:: `
         ResolveNamespace('Windows.Globalization', $Null)
    C:\WINDOWS\system32\WinMetadata\Windows.Globalization.winmd
    

    It also should be noted that this syntax won't work starting with PowerShell 7.1/.NET 5.0. You would need to add the type in a conventional way

    Add-Type -AssemblyName Microsoft.Windows.SDK.NET.dll
    

    and then just use [Windows.Globalization.Calendar].

    For reference also see What is powershell syntax doing something like Assembly::LoadWithPartialName?.

    Answer 2

    That will be

    new Windows.Globalization.Calendar()
    

    Using Windows.Globalization namespace requires a reference to Microsoft.Windows.SDK.NET.dll