Is there a way to install YAK packages via RhinoCommon or is the only way using command line? It would be useful to install YAK packages via RhinoCommon (or other .Net library) in order to automatically check for updates and install updated or new packages. It’s a bit cumbersome to use command line commands in C# code for that.
The functionality for managing packages is in Yak.Core.dll but we don’t have any documentation since it isn’t currently part of the SDK for third-parties. That said, I’m not planning to break the public API, so this should give you some ideas…
using Yak;
...
// construct package repos for source(s) set in rhino's advanced settings
var source_strs = Rhino.ApplicationSettings.PackageManagerSettings.Sources.Split(';');
var sources = new List<IPackageRepository>();
foreach (var s in source_strs)
{
// product header value is included in user-agent for requests to yak.rhino3d.com (for analytics only)
sources.Add(PackageRepositoryFactory.Create(s, new ProductHeaderValue("jukka")));
}
// initialise yak client and set package install folder for this version of rhino
var yak = new YakClient(sources.ToArray())
{
PackageFolder = Rhino.Runtime.HostUtils.AutoInstallPlugInFolder(true) // user
};
...
// some examples of ways to interact with the server, get installed packages
// and install/upgrade packages (needs exception handling!)
var packages1 = await yak.Search("foo"); // search for "foo"
var packages2 = await yak.Package.GetAll(); // list all packages on server
var installed = yak.List(); // list installed packages
var versions = await yak.Version.GetAll("bar"); // get available versions for package "bar"
// filter out pre-release versions
versions = versions.Where(v => !v.Prerelease).ToArray();
// filter out versions that can't be installed here
versions = versions.Where(v => v.Distributions.Where(d => d.IsCompatible()).Any()).ToArray();
// download compatible distribution for latest version of "bar"
var tmp_path = await yak.Version.Download("bar", versions[0].Number);
// install downloaded package file (works for upgrades too)
yak.Install(tmp_path);
Rhino needs to be restarted to load new versions of plug-ins.
Hopefully that’ll get you going!
If you’d be happy to share more about the way in which you plan to automate checking for and installing updates for internal (or public) packages, I’d love to hear it. I’d like to support this use-case better in core Rhino, without having to resort to using Yak.Core.
Thanks, this helps a lot! However, I cannot list all the packages on the servers since “yak.Search()” requires an argument and asterisk “*” as an argument is not working.
I created a Rhino plugin with the following features
- check automatically if there are newer versions and notify user about them
- the check is done automatically every time Rhino is opened and it can be done manually
- it is checking packages from private and public servers
- install/update multiple packages at once
- check if specific packages are installed and force to install/update them automatically every time Rhino is opened
Now when it’s written I realized that those should be part of Package Manager. Like installing/updating multiple packages at once and automatically checking updates and notifying user about them and offering a button to update immediately.
Whoops! I’ve update the code above and fixed some more silly typos.
I agree. I’d really like to get update checking and notifications implemented. It’s logged here… https://mcneel.myjetbrains.com/youtrack/issue/RH-49783.
How do you see installing/updating multiple packages at once working?
This one is really interesting! Sort of like a requirements.txt file in a Python project, or components in a .vsconfig file. Logged as RH-63125.
Great, I’ll try that later!
Looking forward to have that included in Package Manager. I made it to use another thread so it does not lock Rhino’s UI.
I just made a basic checklistbox and added some buttons. Perhaps using check boxes for each package in Package Manager and having similar buttons?
I didn’t know it could be done in Visual Studio like that. That’s useful.
Hello,
currently I am trying to do something similar, but updating only one package for a plugin, this post has helped a lot. I wanted to ask if are you giving any feedback to the user of the installation of the packages. The issue is that the YakClient.Install doesn’t return, is there a way of knowing if the package was installed correctly?
To be honest, I have not checked if the package was installed or not. I just assumed that it will throw an exception if installation was not succeed.
I just found that there is an event “Yak.YakClient.PackageInstalled” which is probably raised when the package is installed. I have not tested that event yet. So you could implement own code for that event.
Something like this
private static YakClient GetYakClient()
{
YakClient yak = null;
try
{
// Construct package repos for source(s) set in Rhino's advanced settings
string[] yakSources = Rhino.ApplicationSettings.PackageManagerSettings.Sources.Split(';');
List<IPackageRepository> yakRepos = new List<IPackageRepository>();
foreach (string yakSource in yakSources)
{
// Product header value is included in user-agent for requests to yak.rhino3d.com (for analytics only)
yakRepos.Add(PackageRepositoryFactory.Create(yakSource, new ProductHeaderValue("jukka")));
}
// Initialise Yak client and set package install folder for this version of Rhino
yak = new YakClient(yakRepos.ToArray())
{
PackageFolder = Rhino.Runtime.HostUtils.AutoInstallPlugInFolder(true) // user
};
yak.PackageInstalled += Yak_PackageInstalled;
}
catch (Exception ex)
{
RhinoApp.WriteLine(_name + ": " + ex.ToString());
}
return yak;
}
private static void Yak_PackageInstalled(object sender, PackageInstalledEventArgs e)
{
// Implement something here to notify about package installation
throw new NotImplementedException();
}
This assumption is correct! The PackageInstalled
event is not necessary for this and may change.