Skip to content

Instantly share code, notes, and snippets.

@imAliAsad
Created April 1, 2018 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imAliAsad/c4914af1aeb3f8e495718258cc6ffaff to your computer and use it in GitHub Desktop.
Save imAliAsad/c4914af1aeb3f8e495718258cc6ffaff to your computer and use it in GitHub Desktop.
Window service that will copy all updated files from a network drive and paste it into a local drive
public static class Configuration
{
public static readonly string ArchcorpAddinFolderPath = @"O:\IT\4th Door\Ali Asad\Projects\Revit Addins\Test Archcorp Addins\";
public static readonly string AutodeskRevitAddinFolderPath = $"C:\\Users\\{Environment.UserName}\\AppData\\Roaming\\Autodesk\\Revit\\Addins\\";
public static readonly List<string> AutodeskVersion = new List<string> { @"2015\", @"2017\", @"2018\", @"2019\" };
public static readonly string DeleteAddinNamePrefix = "delete_";
}
public static class RevidAddinController
{
private static NetworkDrive _activNetworkDrive;
private static NetworkDrive ActivateNetworkDrive
{
get
{
if (_activNetworkDrive == null)
{
_activNetworkDrive = Util.ActivateNetworkDrive();
}
return _activNetworkDrive;
}
}
public static IEnumerable<AddinStatus> Update_AutodeskAddinFolder_With_ArchcorpUpdatedAddinFiles(List<string> autoDeskVersion, string addinInstallationPath)
{
var networkDrive = ActivateNetworkDrive;
var allAutodeskVersionPath = Util.GetAllAutodeskAddinLibraryFolderPaths(autoDeskVersion, addinInstallationPath);
List<FileData> latestArchcorpAddins = new List<FileData>();
foreach (var autodeskAddinFolder in allAutodeskVersionPath)
{
var archorpAddinFiles = Util.GetAllExternalRevitAddinFilesFromArchcorpAddinFolderPath(Configuration.ArchcorpAddinFolderPath);
var autodeskAddinFiles = Util.GetAllExternalRevitAddinFilesLocationFromAutodeskAddinFolderPath(autodeskAddinFolder);
var latestAddins = Util.GetUpdatedRevitAddinFromArchcorpFolderPath(autodeskAddinFolder, archorpAddinFiles, autodeskAddinFiles)
.Where(addin => !addin.FileName.Contains(Configuration.DeleteAddinNamePrefix));
latestArchcorpAddins.AddRange(latestAddins);
}
List<AddinStatus> addinCopyStatus = new List<AddinStatus>();
foreach (var autodeskAddinPath in allAutodeskVersionPath)
{
foreach (var newArchcorpAddin in latestArchcorpAddins)
{
addinCopyStatus.Add(Util.InstallNewAddinFile(newArchcorpAddin, autodeskAddinPath));
}
}
return addinCopyStatus;
}
public static IEnumerable<AddinStatus> Delete_OnlyThose_AutodeskAddinFiles_WhichAreNamedAsDelete_InArchcorpFolder(List<string> autoDeskVersion, string addinInstallationPath)
{
var archorpAddinFiles = Util.GetAllExternalRevitAddinFilesFromArchcorpAddinFolderPath(Configuration.ArchcorpAddinFolderPath);
var deletedAddinFiles = Util.GetDeleteAbleRevitAddinFilesFromArchcorpFolderPath(archorpAddinFiles);
var allAutodeskVersionPath = Util.GetAllAutodeskAddinLibraryFolderPaths(autoDeskVersion, addinInstallationPath);
var deletedFileStatus = new List<AddinStatus>();
foreach (var autodeskAddinPath in allAutodeskVersionPath)
{
foreach (var fileTobeDeleted in deletedAddinFiles)
{
deletedFileStatus.Add(Util.DeleteAddinFile(fileTobeDeleted, autodeskAddinPath));
}
}
return deletedFileStatus;
}
}
public partial class Service1 : ServiceBase
{
private Timer _timer;
private System.Threading.Thread _thread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
DoWork();
_thread = new System.Threading.Thread(()=>{});
// run the empty work in background
_thread.Start();
}
catch (Exception e)
{
WriteErrorLog(e);
}
}
private void DoWork()
{
_timer = new Timer();
_timer.Interval = 5000;
_timer.Enabled = true;
_timer.Elapsed += _timer_Elapsed;
Update();
}
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
Update();
}
protected override void OnStop()
{
// do nothing
}
private void Update()
{
RevidAddinController.Update_AutodeskAddinFolder_With_ArchcorpUpdatedAddinFiles(Configuration.AutodeskVersion, Configuration.AutodeskRevitAddinFolderPath);
RevidAddinController.Delete_OnlyThose_AutodeskAddinFiles_WhichAreNamedAsDelete_InArchcorpFolder(Configuration.AutodeskVersion, Configuration.AutodeskRevitAddinFolderPath);
}
private void WriteErrorLog(Exception ex)
{
StreamWriter sw = null;
try
{
sw = new StreamWriter(AppDomain.CurrentDomain.BaseDirectory + "\\Logfile.txt", true);
sw.WriteLine(DateTime.Now.ToString() + " ; " + ex.Source.ToString().Trim() + "; " + ex.Message.ToString().Trim());
sw.Flush();
sw.Close();
}
catch
{
}
}
}
public static class Util
{
/// <summary>
/// Return all the Autodesk Revit version path where the addin will be installed
/// </summary>
/// <param name="autodeskVersions">list of possible autodesk revit version that user maybe uses</param>
/// <param name="autodeskAddinFolderPath">the path where revit.exe read the external addin files</param>
/// <returns>Return the list of available autodesk revit version path for addins</returns>
public static IEnumerable<string> GetAllAutodeskAddinLibraryFolderPaths(List<string> autodeskVersions, string autodeskAddinFolderPath)
{
// return the folder path
var autodeskVersionPath = autodeskVersions.Select(version => autodeskAddinFolderPath + version)
.Where(path => System.IO.Directory.Exists(path) == true)
.Select(path => path);
return autodeskVersionPath;
}
/// <summary>
/// Return all the addin files that archcorp has developed
/// And, these files will then be installed to Revit
/// </summary>
/// <param name="archcorpAddinFolderPath">
/// the path where Archcorp has stored their external revit addins.
/// For example, O:\IT\4th Door\Ali Asad\Projects\Revit Addin\@archcorp addin
/// </param>
/// <returns>Return the list of all Archcorp's addin files (along their modify date)</returns>
public static IEnumerable<FileData> GetAllExternalRevitAddinFilesFromArchcorpAddinFolderPath(string archcorpAddinFolderPath)
{
var archcorpAddinFiles = System.IO.Directory.GetFiles(archcorpAddinFolderPath)
.Select(path => new FileData(path));
return archcorpAddinFiles;
}
/// <summary>
/// Return all the installed external autodesk revit addin files along with their modify dates
/// </summary>
/// <param name="autodeskAddinFolderPath"></param>
/// <returns></returns>
public static IEnumerable<FileData> GetAllExternalRevitAddinFilesLocationFromAutodeskAddinFolderPath(string autodeskAddinFolderPath)
{
var externalAutodeskRevitAddinnFiles = System.IO.Directory.GetFiles(autodeskAddinFolderPath).Where(path => !path.Contains(Configuration.DeleteAddinNamePrefix))
.Select(path => new FileData(path));
return externalAutodeskRevitAddinnFiles;
}
/// <summary>
/// Return the list of all latest/updated revision of revit addins
/// </summary>
/// <param name="autodeskAddinFolderPath">Folder path from where Autodesk Revit read their external addin files</param>
/// <param name="allAutodeskAddinFiles">List of all installed external autodesk revit addins files</param>
/// <param name="allArchcorpAddinFiles">List of all archcorp external addin files</param>
/// <returns></returns>
public static IEnumerable<FileData> GetUpdatedRevitAddinFromArchcorpFolderPath(string autodeskAddinFolderPath, IEnumerable<FileData> allArchcorpAddinFiles, IEnumerable<FileData> allAutodeskAddinFiles)
{
if (!Directory.Exists(autodeskAddinFolderPath)) return null;
else if (!allArchcorpAddinFiles.Any()) return null;
else if (!allArchcorpAddinFiles.Any()) return null;
// -------Check if the archcorpAddin folder has the latest addins by comparing it with the autodeskAddin folder--------//
List<FileData> latestAddins = new List<FileData>();
foreach (var archcorpFile in allArchcorpAddinFiles)
{
bool isLatest = true;
foreach (var autodeskFile in allAutodeskAddinFiles)
{
if (archcorpFile.FileName.Contains(autodeskFile.FileName))
{
// if the file exist already, check if it is the latest by comparing the modify date of autodesk and archcorp file
// and the file name doesn't have 'delete word'
isLatest = DateTime.Compare(archcorpFile.ModifiedDate, autodeskFile.ModifiedDate) > 0 && !archcorpFile.FileName.ToLower().Contains("_delete");
break;
}
}
// add, if archcorp has the latest or updated revision of addin
if (isLatest)
{
latestAddins.Add(archcorpFile);
}
}
// return the latest/updated revit addin files
return latestAddins;
}
/// <summary>
/// Tells if the Revit is runing or not
/// </summary>
/// <returns>True/False</returns>
public static bool IsRevitRuning()
{
Process[] pname = Process.GetProcessesByName("Revit");
return pname.Length > 0;
}
/// <summary>
/// Write code to copy and replace updated revit addin files
/// </summary>
/// <param name="fileTobeInstall">The addin file to be copyed/install</param>
/// <param name="autodeskAddinFolder">The autodesk addin library path, where the addin will be copyied/install</param>
/// <returns></returns>
public static AddinStatus InstallNewAddinFile(FileData fileTobeInstall, string autodeskAddinFolder)
{
AddinStatus addinStatus = new AddinStatus();
addinStatus.FileName = fileTobeInstall.FileName;
// Map the addin file to the autodesk addin library path.
string autodeskFileTobeInstalledPath = autodeskAddinFolder + "\\" + fileTobeInstall.FileName;
// File can't be copiyed when revit is runing, make sure the copy process won't start if the revit is runing.
if (IsRevitRuning())
{
addinStatus.Message = "Couldn't install because revit is runing.";
addinStatus.Status = Status.Failed;
return addinStatus;
}
// if the addin file already exist in the autodesk addin library
if (System.IO.File.Exists(autodeskFileTobeInstalledPath))
{
// Delete the old file
System.IO.File.Delete(autodeskFileTobeInstalledPath);
// Copy the updated addin to the autodesk library
System.IO.File.Copy(fileTobeInstall.FilePath, autodeskFileTobeInstalledPath);
addinStatus.Status = Status.Replaced;
addinStatus.Message = "Succuss!";
}
// if the addin file is not in the autodesk addin library, it means its a new file
else
{
// then simply copy the new addin file to the autodesk addin library
System.IO.File.Copy(fileTobeInstall.FilePath, autodeskFileTobeInstalledPath);
addinStatus.Status = Status.Copied;
addinStatus.Message = "Succuss!";
}
// Cross check If file wasn't able to copied to the autodesk addin library
if(!System.IO.File.Exists(autodeskFileTobeInstalledPath))
{
addinStatus.Status = Status.Failed;
// check if it wasn't able to copiyed because the Revit is runing
if (IsRevitRuning())
{
addinStatus.Message = "Couldn't install because revit is runing.";
}
// or the addin wasn't able to copiyed due to an unknown error
else
{
addinStatus.Message = "Unknown error has accured while replacing the " + fileTobeInstall.FileName;
}
}
return addinStatus;
}
/// <summary>
/// Return the list of all addin-files to be deleted from Archcorp addin folder
/// </summary>
/// <param name="allArchcorpAddinFiles">List of all archcorp external addin files</param>
/// <returns></returns>
public static IEnumerable<FileData> GetDeleteAbleRevitAddinFilesFromArchcorpFolderPath(IEnumerable<FileData> allArchcorpAddinFiles)
{
List<FileData> filesTobeDeleted = new List<FileData>();
if (!allArchcorpAddinFiles.Any()) return filesTobeDeleted;
// -------Check if the archcorpAddin folder has the addins files to be deleted by checking their prefix name with 'Delete_'--------//
foreach (var archcorpFile in allArchcorpAddinFiles)
{
bool isLatest = true;
bool isDeletedFile = archcorpFile.FileName.ToLower().Contains(Configuration.DeleteAddinNamePrefix);
// add, if archcorp has the addin-files to be deleted
if (isDeletedFile)
{
filesTobeDeleted.Add(archcorpFile);
}
}
// return the addin-files to be deleted
return filesTobeDeleted;
}
/// <summary>
/// Delete those addinfile from autodesk addin library, whose archcorp's addin file name starts with 'Delete_' prefix
/// </summary>
/// <param name="fileTobeDelete">file to be deleted</param>
/// <param name="autodeskAddinFolder">path of the autodesk addin library</param>
/// <returns></returns>
public static AddinStatus DeleteAddinFile(FileData fileTobeDelete, string autodeskAddinFolder)
{
AddinStatus addinStatus = new AddinStatus();
addinStatus.FileName = fileTobeDelete.FileName;
// Map the addin file to the autodesk addin library path.
string autodeskFileTobeInstalledPath = autodeskAddinFolder + "\\" + fileTobeDelete.FileName.Replace(Configuration.DeleteAddinNamePrefix, "");
// File can't be deleted when revit is runing, make sure the delete process won't start if the revit is runing.
if (IsRevitRuning())
{
addinStatus.Message = "Couldn't delete the addin-file because revit is runing.";
addinStatus.Status = Status.Failed;
return addinStatus;
}
// delete if the addin file already exist in the autodesk addin library
if (System.IO.File.Exists(autodeskFileTobeInstalledPath))
{
// Delete the addin-file
System.IO.File.Delete(autodeskFileTobeInstalledPath);
addinStatus.Status = Status.Deleted;
addinStatus.Message = "Delete Succussfully!";
}
// if the addin file is not in the autodesk addin library, it means the addin-file can't be deleted
else
{
// then simply log the error message that the file can't be deleted because its not available in the autodesk library
addinStatus.Status = Status.Failed;
addinStatus.Message = "Delete Failed. Because files isn't in the autodesk library!";
}
// Cross check If the file wasn't able to delete
if (System.IO.File.Exists(autodeskFileTobeInstalledPath))
{
addinStatus.Status = Status.Failed;
// check if it was due to revit is runing
if (IsRevitRuning())
{
addinStatus.Message = "Couldn't delete the addin-file because revit is runing.";
}
// or the addin wasn't able to delete due to an unknown error
else
{
addinStatus.Message = "Unknown error has accured while deleting the " + fileTobeDelete.FileName;
}
}
return addinStatus;
}
/// <summary>
/// Get the network drive path
/// </summary>
/// <returns></returns>
public static NetworkDrive ActivateNetworkDrive()
{
NetworkDrive oNetDrive = new aejw.Network.NetworkDrive();
try
{
oNetDrive.LocalDrive = "O:";
oNetDrive.ShareName = @"\\acdxbfs1\Organisation";
oNetDrive.Force = true;
oNetDrive.Persistent = true;
oNetDrive.MapDrive();
}
catch (Exception err)
{
throw err;
}
return oNetDrive;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment