Hello,
I do the same thing but a different way - all users get a simple addin installed during vault upgrades which checks for updates and loads the main extension so that way I don't have to push to all user individually, I just have to update one server location that the extension reads from.
For vault and inventor, instead of writing them as a normal addin, I load the main content and pass the API methods to it. Here is a sample of my loader vault extension.
The downside to this method, is that the user cannot easily unload the extension from inventor (vault cannot unload anyways), but that is not an issue for me.
The other tricky part is updating the loader extension if needed, but that is a separate matter, and should not really need to happen.
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Threading;
using Autodesk.Connectivity.Explorer.Extensibility;
using Autodesk.Connectivity.Extensibility.Framework;
[assembly: ApiVersion("18.0")] //15=vault2022, 16=vault 2023, 18 = vault 2025
[assembly: ExtensionId("da91ef70-50cd-48d2-a38a-5ccc8415493f")]
namespace VaultExtension
{
public class VaultExtension : IExplorerExtension
{
public VaultExtension()
{
Debug.Print("Vault extension loading");
}
public IExplorerExtension content;
public void OnStartup(IApplication application)
{
//Directory structure is
// VaultExtension
// VaultExtension.dll
// VaultExtensionContent
// VaultExtensionContent.dll
string loc = GetType().Assembly.Location; // gets the addin dll path
string sourceDirectory = Path.GetDirectoryName(loc);
string targetDirectory = Path.Combine(sourceDirectory, "VaultExtensionContent");
string targetDll = Path.Combine(targetDirectory, "VaultExtensionContent.dll");
var vltprocs = Process.GetProcessesByName("Connectivity.VaultPro");
if(vltprocs.Length == 1)
{
//update the content assembly from the server or whatever.
//if more than 1 vault instance is running, then we won't be able to update as the dll will be locked. We can just wait until next time.
}
try
{
if(System.IO.File.Exists(targetDll))
{
var contentAssembly = Assembly.LoadFrom(targetDll); // loadfrom will load dependency dlls that are in the same dir, loadfile does not
content = (IExplorerExtension)contentAssembly.CreateInstance("VaultExtension.VaultExtensionContent", true, default, default, new object[] { application }, CultureInfo.CurrentCulture, default);
content?.OnStartup(application);
}
}
catch
{
System.Threading.ThreadPool.QueueUserWorkItem(_ => MessageBox.Show("Could Not Load VaultExtension Content Assembly!", "VaultExtension Load Error", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly));
return;
}
}
//pass all the extension methods to the content assembly
public void OnLogOn(IApplication application)
{
content?.OnLogOn(application);
}
public IEnumerable<CommandSite> CommandSites()
{
return content?.CommandSites();
}
public IEnumerable<string> HiddenCommands()
{
return content?.HiddenCommands();
}
public void OnShutdown(IApplication application)
{
content?.OnShutdown(application);
}
public void OnLogOff(IApplication application)
{
content?.OnLogOff(application);
}
public IEnumerable<DetailPaneTab> DetailTabs()
{
return content?.DetailTabs();
}
public IEnumerable<CustomEntityHandler> CustomEntityHandlers()
{
return content?.CustomEntityHandlers();
}
}
}