0

I am working on creating a revit addin and I want to have it automatically pull a copy ofthe .dll and.addin files at shutdown using a batch file. By themselves the code and the batch file routines work correctly but when I have them running with each other I get a have a sharing violation for copying the .dll file. Can anyone tell me how I can get around the sharing violation? The purpose is to deploy these two files to all users and copy the file updates to their computer when they shut down Revit.

public Result OnShutdown(UIControlledApplication application)
{
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo.FileName = "S:\\Revit 2015\\Addins\\Revit Tabs\\2015_RevitTab.bat";
    proc.StartInfo.WorkingDirectory = "S:\\Revit 2015\\Addins\\Revit Tabs\\";
    proc.Start();
    return Result.Succeeded;
}

And here is the copy syntax

xcopy "S:\Revit 2015\Addins\Revit Tabs\Revit Tabs.addin" "C:\ProgramData\Autodesk\Revit\Addins\2015" /y

xcopy "S:\Revit 2015\Addins\Revit Tabs\Revit Tabs\bin\Debug\Revit Tabs.dll" "C:\ProgramData\Autodesk\Revit\Addins\2015" /y 
YSC
  • 38,212
  • 9
  • 96
  • 149
blkscrpn5
  • 11
  • 5
  • is this for debug only? or are you planing a auto-update after deployment? – Augusto Goncalves Jan 29 '16 at 16:22
  • 1
    Possible duplicate of [How to copy "in use" files through batch file in Windows 7](http://stackoverflow.com/questions/7647701/how-to-copy-in-use-files-through-batch-file-in-windows-7) –  Jan 29 '16 at 16:43
  • The idea is to use this as auto update the addin after deployment. I believe I had the same issue when I tried copying it in the addin coding. – blkscrpn5 Jan 29 '16 at 17:16

2 Answers2

1

You could add a call to your own stand-alone utility exe that monitors whether the current Revit process is still alive, and thenexecutes the add-in DLL copy process once Revit really is gone.

Jeremy Tammik
  • 7,333
  • 2
  • 12
  • 17
0

I wanted to same auto-update process and after a bit of trial and error I found some code that worked for me. Hopefully, you can use it or improve it.

I have ribbon.addin, ribbon.dll ("Ribbon") and commands.dll ("Commands") files. All files are installed as part of the deployment into the "%appdata%\Autodesk\Revit\Addins\2016" folder ("Local"). It's important that these are installed in the "%appdata%" folder and not the "%programdata%\Autodesk\Revit\Addins\2016" folder because of write protection issues!

The Ribbon addin is only for checking which version of the Commands is currently in the Local folder and if that's out-of-date from the Commands file I have in a shared network folder ("Shared"). Because of security, I can't read the AssemblyVersion of the Local DLL or the Shared DLL. To get around this I have a TXT file in the Local folder that has the AssemblyVersion as the first line and, in the Shared folder I have another TXT file (where I actually have the "About" information of the Commands addin) which has the Shared Commands AssemblyVersion as the first line.

So my Ribbon OnStartup(UIControlledApplication a) code checks the TXT files using System.IO.StreamReader. If the Local file is out-of-date it updates the Local TXT and DLL files with this :

try
{
    string AddinsDir = a.ControlledApplication.CurrentUserAddinsLocation + @"\";
    string tempDir = System.IO.Path.GetTempPath();
    StreamWriter myStream = new StreamWriter(tempDir + "Commands.txt", false, System.Text.Encoding.Default);
    myStream.WriteLine(AssemblyVersion);
      //AssemblyVersion is the first line of the Shared Commands TXT file we read
    myStream.Close();

    File.Copy(tempDir + "Commands.txt", AddinsDir + "Commands.txt", true);
    File.Delete(tempDir + "Commands.txt");

    File.Delete(AddinsDir + "Commands.dll");
    File.Copy(SharedPath + "Commands.dll", AddinsDir + "Commands.dll", true);
      //SharedPath is the Shared folder
}
catch (Exception e)
{
    TaskDialog.Show("Error Loading Ribbon", "There was an error loading the Ribbon.  Please contact the BIM Manager for assistance.\n\n" + e.Message);
    return Result.Failed;
}

If, at this point the code is still running the file is up-to-date and it's time to load it:

Assembly Commands = Assembly.LoadFrom(AddinsDir + "Commands.dll");
Type type = Commands.GetType("Commands.App");
  //Commands.App is my class where my Ribbon is created and Events are registered
object instanceOfCommands = Activator.CreateInstance(type, new object[] { a });
return Result.Succeeded;

My plan for Revit 2017 deployment is to create my custom Ribbon in the Ribbon.dll so I can have my "About" button there and accessible at all times. Then, I'll add a button in the "About" dialog box that would manually update the Local Commands DLL.

I hope that helps!!