1

using PowerShell and the iCal.Net package, I want to read an .ics file.

# install ical.net dependencies
Install-Package NodaTime -Force

# install ical.net package
Install-Package iCal.Net -Force

# variables
$icsfile = "C:\Users\Windows\Desktop\ical\caalendar.ical"
$icsurl = "https://url_to_download/basic.ics"

# download ics file
Invoke-WebRequest $icsurl -OutFile $icsfile

# create new calendar object
$calendar = New-Object Ical.Net.Calendar

While creating the new calendar object I get a message saying

New-Object : Cannot find type [Ical.Net.Calendar]: verify that the assembly containing this type is loaded.
At line:1 char:13
+ $calendar = New-Object Ical.Net.Calendar
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidType: (:) [New-Object], PSArgumentException
    + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand

My guess is that even though the ical.net package is installed, it also has to be loaded. While researching on how to do this, I found that I need to provide the path to a specific .dll file.

How can I find out where this .ddl is located, and how can I load it?

mklement0
  • 382,024
  • 64
  • 607
  • 775
aristosv
  • 75
  • 1
  • 15

1 Answers1

3

Indeed:

  • While Install-Package lets you install general-purpose NuGet packages (containing .NET assemblies for use with any .NET language), there is no direct PowerShell integration for their use, as of version v1.4.8.1 of the PackageManagement module.

    • GitHub issue #6724 suggests making the use of NuGet packages in PowerShell easier by extending Add-Type

    • Note: If Install-Package fails to find a NuGet package you know to exist, you may have to upgrade PowerShell's package-management modules first, from an elevated session (you don't need elevation if you install only for the current user, with -Scope CurrentUser):

      Install-Module -Scope AllUsers PowerShellGet -Force
      
  • You must inded:

    • locate the appropriate .dll file inside the package

    • and load it via Add-Type -LiteralPath, as shown below.

  • The caveat is:

    • Manually loading an assembly from a NuGet package installed with Install-Package does not (always) also automatically load its dependencies.
      However, it does appear to work with ICal.Net.

    • If the method below doesn't work for a given package, you'll need to install it with a more cumbersome approach that involves an auxiliary .NET SDK project, as detailed in this answer.


Manually loading the relevant assembly from the Ical.Net NuGet package:

  • Inspecting the package via the online NuGet Package Explorer reveals that there's a .NET Standard 2.0 Ical.Net.dll assembly in subdirectory lib\netstandard2.0. .NET Standard 2.0 assemblies are compatible with both Windows PowerShell and PowerShell (Core) 7+.

  • You can infer the local installation directory of a package installed with Install-Package from the .Source property of the package-information objects returned by Get-Package

Therefore:

Add-Type -LiteralPath (Join-Path (Split-Path -Parent (Get-Package ICal.Net).Source) lib\netstandard2.0\Ical.Net.dll)
mklement0
  • 382,024
  • 64
  • 607
  • 775