/// <summary> /// Сopy the directory with the embedded files and directories /// </summary> /// <param name="sourcePath">Path to the source directory</param> /// <param name="destinationPath">Path to the destination directory</param> protected virtual void CopyDirectory(string sourcePath, string destinationPath) { var existingFiles = _fileProvider.GetFiles(sourcePath); var existingDirectories = _fileProvider.GetDirectories(sourcePath); if (!_fileProvider.DirectoryExists(destinationPath)) { _fileProvider.CreateDirectory(destinationPath); } foreach (var file in existingFiles) { var filePath = _fileProvider.Combine(destinationPath, _fileProvider.GetFileName(file)); if (!_fileProvider.FileExists(filePath)) { _fileProvider.FileCopy(file, filePath); } } foreach (var directory in existingDirectories) { var directoryPath = _fileProvider.Combine(destinationPath, _fileProvider.GetDirectoryName(directory)); CopyDirectory(directory, directoryPath); } }
/// <summary> /// Copy the plugin file to shadow copy directory /// </summary> /// <param name="pluginFilePath">Plugin file path</param> /// <param name="shadowCopyPlugFolder">Path to shadow copy folder</param> /// <returns>File path to shadow copy of plugin file</returns> protected static string ShadowCopyFile(string pluginFilePath, string shadowCopyPlugFolder) { var shouldCopy = true; var shadowCopiedPlug = _fileProvider.Combine(shadowCopyPlugFolder, _fileProvider.GetFileName(pluginFilePath)); //check if a shadow copied file already exists and if it does, check if it's updated, if not don't copy if (_fileProvider.FileExists(shadowCopiedPlug)) { //it's better to use LastWriteTimeUTC, but not all file systems have this property //maybe it is better to compare file hash? var areFilesIdentical = _fileProvider.GetCreationTime(shadowCopiedPlug).ToUniversalTime().Ticks >= _fileProvider.GetCreationTime(pluginFilePath).ToUniversalTime().Ticks; if (areFilesIdentical) { Debug.WriteLine("Not copying; files appear identical: '{0}'", _fileProvider.GetFileName(shadowCopiedPlug)); shouldCopy = false; } else { //delete an existing file //More info: https://www.nopcommerce.com/boards/t/11511/access-error-nopplugindiscountrulesbillingcountrydll.aspx?p=4#60838 Debug.WriteLine("New plugin found; Deleting the old file: '{0}'", _fileProvider.GetFileName(shadowCopiedPlug)); _fileProvider.DeleteFile(shadowCopiedPlug); } } if (!shouldCopy) { return(shadowCopiedPlug); } try { _fileProvider.FileCopy(pluginFilePath, shadowCopiedPlug, true); } catch (IOException) { Debug.WriteLine(shadowCopiedPlug + " is locked, attempting to rename"); //this occurs when the files are locked, //for some reason devenv locks plugin files some times and for another crazy reason you are allowed to rename them //which releases the lock, so that it what we are doing here, once it's renamed, we can re-shadow copy try { var oldFile = shadowCopiedPlug + Guid.NewGuid().ToString("N") + ".old"; _fileProvider.FileMove(shadowCopiedPlug, oldFile); } catch (IOException exc) { throw new IOException(shadowCopiedPlug + " rename failed, cannot initialize plugin", exc); } //OK, we've made it this far, now retry the shadow copy _fileProvider.FileCopy(pluginFilePath, shadowCopiedPlug, true); } return(shadowCopiedPlug); }