protected override void Run() { SafeToExit = false; Description = Messages.ACTION_EXPORT_DESCRIPTION_IN_PROGRESS; RelatedTask = XenAPI.Task.create(Session, string.Format(Messages.ACTION_EXPORT_TASK_NAME, VM.Name), string.Format(Messages.ACTION_EXPORT_TASK_DESCRIPTION, VM.Name)); UriBuilder uriBuilder = new UriBuilder(this.Session.Url); uriBuilder.Path = "export"; uriBuilder.Query = string.Format("session_id={0}&uuid={1}&task_id={2}", Uri.EscapeDataString(this.Session.uuid), Uri.EscapeDataString(this.VM.uuid), Uri.EscapeDataString(this.RelatedTask.opaque_ref)); log.DebugFormat("Exporting {0} from {1} to {2}", VM.Name, uriBuilder.ToString(), _filename); // The DownloadFile call will block, so we need a separate thread to poll for task status. Thread taskThread = new Thread((ThreadStart)progressPoll); taskThread.Name = "Progress polling thread for ExportVmAction for " + VM.Name.Ellipsise(20); taskThread.IsBackground = true; taskThread.Start(); // Create the file with a temporary name till it is fully downloaded String tmpFile = _filename + ".tmp"; try { HttpGet(tmpFile, uriBuilder.Uri); } catch (Exception e) { if (XenAPI.Task.get_status(this.Session, this.RelatedTask.opaque_ref) == XenAPI.task_status_type.pending && XenAPI.Task.get_progress(this.Session, this.RelatedTask.opaque_ref) == 0) { // If task is pending and has zero progress, it probably hasn't been started, // which probably means there was an exception in the GUI code before the // action got going. Kill the task so that we don't block forever on // taskThread.Join(). Brought to light by CA-11100. XenAPI.Task.destroy(this.Session, this.RelatedTask.opaque_ref); } // Test for null: don't overwrite a previous exception if (_exception == null) _exception = e; } taskThread.Join(); using (FileStream fs = new FileStream(tmpFile, FileMode.Append)) { // Flush written data to disk if (!Win32.FlushFileBuffers(fs.SafeFileHandle)) { Win32Exception exn = new Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error()); log.ErrorFormat("FlushFileBuffers failed in ExportVmAction.\nNativeErrorCode={0}\nMessage={1}\nToString={2}", exn.NativeErrorCode, exn.Message, exn.ToString()); } } if (verify && _exception == null) { long read = 0; int i = 0; long filesize = new FileInfo(tmpFile).Length / 50; //Div by 50 to save doing the * 50 in the callback Export.verifyCallback callback = new Export.verifyCallback(delegate(uint size) { read += size; i++; //divide number of updates by 10, so as not to spend all out time redrawing the control //but try and send an update every second to keep the timer ticking if (i > 10) { PercentComplete = 50 + (int)(read / filesize); i = 0; } }); try { using (FileStream fs = new FileStream(tmpFile, FileMode.Open, FileAccess.Read)) { log.DebugFormat("Verifying export of {0} in {1}", VM.Name, _filename); this.Description = Messages.ACTION_EXPORT_VERIFY; export = new Export(); export.verify(fs, null, (Export.cancellingCallback)delegate() { return Cancelling; }, callback); } } catch (Exception e) { if (_exception == null) _exception = e; } } if (Cancelling || _exception is CancelledException) { log.InfoFormat("Export of VM {0} cancelled", VM.Name); this.Description = Messages.ACTION_EXPORT_DESCRIPTION_CANCELLED; log.DebugFormat("Deleting {0}", tmpFile); File.Delete(tmpFile); throw new CancelledException(); } else if (_exception != null) { log.Warn(string.Format("Export of VM {0} failed", VM.Name), _exception); if (_exception is HeaderChecksumFailed || _exception is FormatException) this.Description = Messages.ACTION_EXPORT_DESCRIPTION_HEADER_CHECKSUM_FAILED; else if (_exception is BlockChecksumFailed) this.Description = Messages.ACTION_EXPORT_DESCRIPTION_BLOCK_CHECKSUM_FAILED; else if (_exception is IOException && Win32.GetHResult(_exception) == Win32.ERROR_DISK_FULL) this.Description = Messages.ACTION_EXPORT_DESCRIPTION_DISK_FULL; else if (_exception is Failure && ((Failure)_exception).ErrorDescription[0] == Failure.VDI_IN_USE) this.Description = Messages.ACTION_EXPORT_DESCRIPTION_VDI_IN_USE; else this.Description = Messages.ACTION_EXPORT_DESCRIPTION_FAILED; var fi = new FileInfo(tmpFile); log.DebugFormat("Progress of the action until exception: {0}", PercentComplete); log.DebugFormat("Size file exported until exception: {0}", fi.Length); try { using (Stream stream = new FileStream(tmpFile, FileMode.Open, FileAccess.Read)) { ArchiveIterator iterator = ArchiveFactory.Reader(ArchiveFactory.Type.Tar, stream); while (iterator.HasNext()) { log.DebugFormat("Tar entry: {0} {1}", iterator.CurrentFileName(), iterator.CurrentFileSize()); } } } catch (Exception) {} log.DebugFormat("Deleting {0}", tmpFile); File.Delete(tmpFile); throw new Exception(Description); } else { log.InfoFormat("Export of VM {0} successful", VM.Name); this.Description = Messages.ACTION_EXPORT_DESCRIPTION_SUCCESSFUL; log.DebugFormat("Renaming {0} to {1}", tmpFile, _filename); if (File.Exists(_filename)) File.Delete(_filename); File.Move(tmpFile, _filename); } }
public void RemoveVPrinter(string printerName) { var printerProps = PrinterProps.getProps(printerName); //for removal we try to go ahead even if there are some failures //5 - Configure Virtual Port removeVirtualPort(printerProps._monitorName, printerProps.portName); _logHelper.Log("removeVirtualPort Completed"); //4 - Add Printer try { var printerDefaults = new PrinterDefaults { DesiredAccess = PrinterAccess.PrinterAllAccess, //0x000F000C,//PRINTER_ALL_ACCESS pDataType = IntPtr.Zero, pDevMode = IntPtr.Zero }; IntPtr printerHandle; if (!OpenPrinter(printerName, out printerHandle, ref printerDefaults)) throw new Win32Exception(Marshal.GetLastWin32Error()); _logHelper.Log("OpenPrinter Completed"); try { if (!DeletePrinter(printerHandle)) throw new Win32Exception(Marshal.GetLastWin32Error()); _logHelper.Log("DeletePrinter Completed"); } finally { if (IntPtr.Zero != printerHandle) ClosePrinter(printerHandle); } } catch (Exception ex) { _logHelper.Log("Failed to renove printer : " + ex.Message); } //3 - Add Printer Driver if (DeletePrinterDriver(null, null, printerProps.driverName) == 0) { var ex = new Win32Exception(Marshal.GetLastWin32Error()); _logHelper.Log("ERROR in custom action AddDeletePrinterPort : " + ex.ToString()); // } _logHelper.Log("DeletePrinterDriver Completed"); //2 - Add Printer Port try { AddDeletePrinterPort(printerProps.portName, printerProps._monitorName, true); _logHelper.Log("AddDeletePrinterPort Completed"); } catch (Exception ex) { _logHelper.Log("ERROR in custom action AddDeletePrinterPort : " + ex.ToString()); } //1 - Add Printer Monitor RemovePrinterMonitor(printerProps._monitorName); _logHelper.Log("RemovePrinterMonitor Completed"); //6 - Restart Spool Service _logHelper.Log("Restarting Spool Service"); GenericResult restartSpoolResult = RestartSpoolService(); if (restartSpoolResult.Success == false) throw restartSpoolResult.Exception; }