FleetingPlugins

public static class FleetingPlugins
Tracks plugins which were installed only so that one particular file could be opened, and which are to be removed again once they have served that purpose.

Two things happen to a fleeting plugin. It is loaded like any other plugin, because a document cannot be read without it, but its objects are kept out of the icon panels and out of search — the user asked for a file, not for a new set of components. And the package behind it is deleted from disk again.

The deletion cannot happen while Grasshopper runs. .NET offers no way to unload an assembly from the process, so the earliest a package can go is at shutdown, and on Windows not even then, since the file is still mapped. So the packages to delete are written to a ledger in the settings folder, that ledger is worked through at every startup before any plugin is scoped, and entries survive there until the deletion actually succeeds. A session which crashes therefore still cleans up after itself on the next launch.

Properties

All

#
public static IEnumerable<FleetingPlugin> All { get; }
Enumerate over every plugin which is fleeting in this session.

Any

#
public static bool Any { get; }
Gets whether any plugin in this session is fleeting. Checked on the hot path of every proxy enumeration, so it is deliberately cheap.

Methods

FlushOnShutdown

#
public static void FlushOnShutdown()
Attempt to delete every fleeting package right now. Call this while Rhino is closing. On macOS the delete generally succeeds even though the assemblies are loaded, because unlinking an open file is permitted there. On Windows it will not, and the ledger carries the work over to the next startup instead.

IsFleeting

#
public static bool IsFleeting(Guid pluginId)
Gets whether a plugin is fleeting, and its objects therefore hidden.
pluginId (Guid)Id of the plugin to test.

IsFleetingLocation

#
public static bool IsFleetingLocation(string location)
Gets whether a file sits inside a package which was installed fleetingly.

This exists for the moments before a plugin is loaded, when there is no Plugin to read an id from and a file path is all there is — scoping, most notably, which happens first and would otherwise leave the plugin listed as pending in the plugin viewer.

location (string)File to test.

Promote

#
public static bool Promote(Guid pluginId)
Stop treating a plugin as fleeting, because the user decided to keep it. Its objects reappear in the panels and its package stays on disk.

A package can hold several plugins, and keeping it keeps all of them. Promoting one therefore promotes every plugin which came out of the same folder — the alternative would leave a sibling marked fleeting while the folder it lives in is never scheduled for deletion again, so its objects would stay hidden for the rest of the session for no reason.

pluginId (Guid)Id of a plugin in the package to keep.
True if the plugin was fleeting and now is not.

ReconcileLedger

#
public static (int removed, int retained) ReconcileLedger()
Work through the removal ledger, deleting every package folder still listed in it and keeping the ones which would not go. Call this at startup, before any plugin is scoped, so that a package left behind by an earlier session is gone before this session can find and load it.
A tuple with the number of folders deleted and the number which resisted deletion and remain on the ledger.

Register

#
public static bool Register(Guid pluginId, string packageName, string versionFolder)
Record a plugin as fleeting and add its package to the removal ledger.

The ledger entry is written before the plugin is ever used, not when the session ends, so that a crash cannot leave the package installed forever.

pluginId (Guid)Id of the plugin which was loaded.
packageName (string)Name of the Yak package it came from.
versionFolder (string)The package version folder which was created by the installation, and which is the only thing that may be deleted.
True if the plugin was newly recorded.

ScheduleRemoval

#
public static bool ScheduleRemoval(string versionFolder)
Delete a package version folder if it will go, and put it on the removal ledger if it will not, so that the next startup tries again.

Fleeting installations are not the only reason a package needs deleting — a user uninstalling a Yak plugin from the plugin viewer runs into exactly the same wall, that a loaded assembly cannot be deleted on Windows. The ledger is the answer in both cases, so it is offered here rather than duplicated.

versionFolder (string)Package version folder to be rid of.
True if the folder is already gone, false if it has been left on the ledger for a later session to deal with.

Events

Changed

#
public static event EventHandler Changed
Raised whenever a plugin becomes fleeting or stops being fleeting. Anything displaying object proxies should rebuild itself in response, since the set of visible proxies has just changed.