/// <summary> /// Publish a WebDeploy package zip file to a web site. /// </summary> /// <param name="websiteName">The name of the web site.</param> /// <param name="slot">The name of the slot.</param> /// <param name="package">The WebDeploy package zip file.</param> /// <param name="connectionStrings">The connection strings to overwrite the ones in the Web.config file.</param> /// <param name="skipAppData">Skip app data</param> /// <param name="doNotDelete">Do not delete files at destination</param> private void PublishWebProjectFromPackageFile(string websiteName, string slot, string package, Hashtable connectionStrings, bool skipAppData, bool doNotDelete) { DeploymentBaseOptions remoteBaseOptions = CreateRemoteDeploymentBaseOptions(websiteName, slot); DeploymentBaseOptions localBaseOptions = new DeploymentBaseOptions(); SetWebDeployToSkipAppData(skipAppData, localBaseOptions, remoteBaseOptions); DeploymentProviderOptions remoteProviderOptions = new DeploymentProviderOptions(DeploymentWellKnownProvider.Auto); using (var deployment = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, package, localBaseOptions)) { DeploymentSyncParameter providerPathParameter = new DeploymentSyncParameter( "Provider Path Parameter", "Provider Path Parameter", SetWebsiteNameForWebDeploy(websiteName, slot), null); DeploymentSyncParameterEntry iisAppEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.IisApp.ToString(), ".*", null); DeploymentSyncParameterEntry setAclEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.SetAcl.ToString(), ".*", null); providerPathParameter.Add(iisAppEntry); providerPathParameter.Add(setAclEntry); deployment.SyncParameters.Add(providerPathParameter); // Replace the connection strings in Web.config with the ones user specifies from the cmdlet. ReplaceConnectionStrings(deployment, connectionStrings); DeploymentSyncOptions syncOptions = new DeploymentSyncOptions { DoNotDelete = doNotDelete }; deployment.SyncTo(remoteProviderOptions, remoteBaseOptions, syncOptions); } }
private void Publish(object unusedState) { Operation operation = null; try { lock (_pendingPublishOperations) { operation = _pendingPublishOperations.Dequeue(); } if (operation == null) { PublishHelper.LogVerboseInformation("Publish: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId); return; } // This was not required earlier but now that every site will be synced twice for every incoming publish (Look at the postsync override in publishextender), // there are chances that same operation might get scheduled in concurrent threads which is not a supported web deploy scenario. bool canContinue = true; lock (_operationsInProgress) { if (_operationsInProgress.Contains(operation.SiteName)) { PublishHelper.LogVerboseInformation("Publish: An operation for {0} is already in progress. Thread {1} will mark it as not started to be scheduled later.", operation.SiteName, Thread.CurrentThread.ManagedThreadId); operation.Status = PublishOperationStatus.NotStarted; canContinue = false; } else { _operationsInProgress.Add(operation.SiteName); } } if (!canContinue) { lock (_completedOperations) { _completedOperations.Enqueue(operation); } return; } operation.ThreadID = Thread.CurrentThread.ManagedThreadId; operation.Status = PublishOperationStatus.Error; DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions(); AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName); using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, PublishHelper.GetPublishManifest(operation.PhysicalPath), srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; string modifiedPhysicalPath = operation.PhysicalPath; string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath); var fileServerIPParameter = new DeploymentSyncParameter( FileServerIPParameterName, FileServerIPParameterDescription, ipDefaultValue, string.Empty); var fileServerIPEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); fileServerIPParameter.Add(fileServerIPEntry); var contentPathParameter = new DeploymentSyncParameter( ContentPathParameterName, ContentPathParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.PhysicalPath.ToString()); var contentParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); contentPathParameter.Add(contentParamEntry); var setAclParameter = new DeploymentSyncParameter( SetAclParameterName, SetAclParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.SetAcl.ToString()); var setAclParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.SetAcl.ToString(), string.Empty, string.Empty); setAclParameter.Add(setAclParamEntry); depObj.SyncParameters.Add(fileServerIPParameter); depObj.SyncParameters.Add(contentPathParameter); depObj.SyncParameters.Add(setAclParameter); destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; destBaseOptions.Trace += new EventHandler<DeploymentTraceEventArgs>(WebDeployPublishTrace); destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose; depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions()); operation.Status = PublishOperationStatus.Completed; AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName); } catch (Exception e) { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); } } } catch (Exception e) { if ((e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) || e is WebHostingObjectNotFoundException) { operation.Status = PublishOperationStatus.SourceOrDestinationInvalid; } AntaresEventProvider.EventWritePublishFailOverServiceFailedToGetSourceSite(operation.SiteName, e.ToString()); } finally { lock (_completedOperations) { PublishHelper.LogVerboseInformation("Publish: Thread {0} qeuing completed operation for site: {1}", operation.ThreadID, operation.SiteName); _completedOperations.Enqueue(operation); } lock (_operationsInProgress) { _operationsInProgress.Remove(operation.SiteName); } _continueEvent.Set(); PublishHelper.LogVerboseInformation("Publish: Thread {0} exiting", Thread.CurrentThread.ManagedThreadId); } }
/// <summary> /// Add a connection string parameter to the deployment. /// </summary> /// <param name="deployment">The deployment object.</param> /// <param name="name">Connection string name.</param> /// <param name="value">Connection string value.</param> private void AddConnectionString(DeploymentObject deployment, string name, string value) { var deploymentSyncParameterName = string.Format("Connection String {0} Parameter", name); DeploymentSyncParameter connectionStringParameter = new DeploymentSyncParameter( deploymentSyncParameterName, deploymentSyncParameterName, value, null); DeploymentSyncParameterEntry connectionStringEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.XmlFile, @"\\web.config$", string.Format(@"//connectionStrings/add[@name='{0}']/@connectionString", name), null); connectionStringParameter.Add(connectionStringEntry); deployment.SyncParameters.Add(connectionStringParameter); }
/// <summary> /// Web Deploy does not parameterize or run any rules (parameterization is one of the rules) when deletion is used. /// So to work around that deletecontent does a simple publish of empty content to the server and gets the IP that is hosting the volume. /// After finding the IP the deletion is called on that content path. This will effectively delete "\\someipaddress\volumename\guidfolder" /// </summary> /// <param name="unusedState">This is not used. This is the signature for the waitcallback expected by threadpool.</param> private void DeleteContent(object unusedState) { Operation operation = null; try { lock (_pendingDeleteOperations) { operation = _pendingDeleteOperations.Dequeue(); } if (operation == null) { PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId); return; } operation.ThreadID = Thread.CurrentThread.ManagedThreadId; operation.Status = PublishOperationStatus.Error; DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions(); AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName); string remoteIP = string.Empty; bool errorOcurred = false; using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.ContentPath, Path.GetTempPath(), srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; string modifiedPhysicalPath = operation.PhysicalPath; string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath); var queryServerIPParameter = new DeploymentSyncParameter( QueryServerIPParameterName, QueryServerIPParameterDescription, string.Empty, DeploymentWellKnownTag.PhysicalPath.ToString()); var queryServerIPParameterEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); queryServerIPParameter.Add(queryServerIPParameterEntry); var contentPathParameter = new DeploymentSyncParameter( ContentPathParameterName, ContentPathParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.PhysicalPath.ToString()); var contentParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); contentPathParameter.Add(contentParamEntry); depObj.SyncParameters.Add(contentPathParameter); depObj.SyncParameters.Add(queryServerIPParameter); destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions()); } catch (Exception e) { bool unhandledException = false; // In cases where the site was deleted on the source before it was ever synced to the destination // mark as the destination invalid and set the status so that its never attempted again. if (e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.ERROR_INVALID_PATH) { string[] messageArray = e.Message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (messageArray.Length > 0) { remoteIP = messageArray[0]; } else { errorOcurred = true; } } else if (e is DeploymentException) { errorOcurred = true; } else { // its not a deployment exception. This is an exception not handled by web deploy such as duplicate key exception. // This needs to be retried. unhandledException = true; errorOcurred = true; } if (errorOcurred) { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); operation.Status = unhandledException ? PublishOperationStatus.Error : PublishOperationStatus.SourceOrDestinationInvalid; } } } if (!errorOcurred) { string[] pathParts = operation.PhysicalPath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); string remotePath = string.Concat(@"\\", remoteIP, @"\", pathParts[1], @"\", pathParts[2]); using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Auto, string.Empty, srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; destBaseOptions.Trace += new EventHandler<DeploymentTraceEventArgs>(WebDeployPublishTrace); destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose; var syncOptions = new DeploymentSyncOptions(); syncOptions.DeleteDestination = true; depObj.SyncTo(DeploymentWellKnownProvider.ContentPath, remotePath, destBaseOptions, syncOptions); operation.Status = PublishOperationStatus.Completed; AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName); } catch (Exception e) { var ex = e as DeploymentDetailedException; if (ex != null && ex.ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) { operation.Status = PublishOperationStatus.SourceOrDestinationInvalid; } else { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); } } } } } finally { lock (_completedOperations) { PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} queuing completed operation for site: {1}", operation.ThreadID, operation.SiteName); _completedOperations.Enqueue(operation); } _continueEvent.Set(); PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} exiting.", Thread.CurrentThread.ManagedThreadId); } }
public override bool Publish(bool setSize) { var sourceBaseOptions = new DeploymentBaseOptions(); var destBaseOptions = new DeploymentBaseOptions(); if (!setSize) { sourceBaseOptions.Trace += TraceEventHandler; sourceBaseOptions.TraceLevel = TraceLevel.Verbose; destBaseOptions.Trace += TraceEventHandler; destBaseOptions.TraceLevel = TraceLevel.Verbose; } destBaseOptions.ComputerName = _publishSettings.ComputerName; destBaseOptions.UserName = _publishSettings.Username; destBaseOptions.Password = _publishSettings.Password; LogTrace("Publishing as {0}", destBaseOptions.UserName); destBaseOptions.AuthenticationType = "basic"; bool publishSucceeded = true; #region Publish Content try { using (var sourceObject = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: true), sourceBaseOptions)) { var syncOptions = new DeploymentSyncOptions() { DoNotDelete = true, }; if (!setSize) { LogTrace("Started content publish for: {0}", _localSite.SiteName); if (HasDatabase) { var connectionStringParameter = new DeploymentSyncParameter( "ConnectionStringParam", // Name "DBConnectionString Param", // Description _publishSettings.SqlDBConnectionString.ConnectionString, // Default Value to set null); // Tag var entry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.XmlFile, // Kind @"\\web\.config$", // Scope connectionStringXPath, // Match null); // Tag connectionStringParameter.Add(entry); sourceObject.SyncParameters.Add(connectionStringParameter); } } try { syncOptions.WhatIf = setSize; var summary = sourceObject.SyncTo(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: false), destBaseOptions, syncOptions); if (!setSize) { LogTrace("Content Published Succesfully For Site: {0} to {1} ", _localSite.SiteName, _publishSettings.SiteName); Helper.UpdateStatus(_localSite.SiteName, _localSite.ServerName); } else { _control.SetProgressbarMax(this.LocalSite.ServerName + this.LocalSite.SiteName, summary.TotalChanges); } } catch (Exception ex) { string message = string.Format("Error syncing content for site: {0}", _localSite.SiteName); LogTrace(message); LogTrace(ex.ToString()); publishSucceeded = false; } } } catch (Exception ex) { LogTrace("Error starting content publish for site: {0}", _localSite.SiteName); LogTrace(ex.ToString()); publishSucceeded = false; } _control.UpdateStatusLabel(string.Empty); #endregion if (!setSize) { _control.SetContentPublished(this.LocalSite.ServerName + this.LocalSite.SiteName, publishSucceeded); } this.PublishStatus = publishSucceeded; return publishSucceeded; }
public override bool Publish(bool setSize) { var sourceBaseOptions = new DeploymentBaseOptions(); var destBaseOptions = new DeploymentBaseOptions(); if (!setSize) { sourceBaseOptions.Trace += TraceEventHandler; sourceBaseOptions.TraceLevel = TraceLevel.Verbose; destBaseOptions.Trace += TraceEventHandler; destBaseOptions.TraceLevel = TraceLevel.Verbose; } destBaseOptions.ComputerName = _publishSettings.ComputerName; destBaseOptions.UserName = _publishSettings.Username; destBaseOptions.Password = _publishSettings.Password; LogTrace("Publishing as {0}", destBaseOptions.UserName); destBaseOptions.AuthenticationType = "basic"; bool publishSucceeded = true; #region Publish Content try { using (var sourceObject = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: true), sourceBaseOptions)) { var syncOptions = new DeploymentSyncOptions() { DoNotDelete = true, }; if (!setSize) { LogTrace("Started content publish for: {0}", _localSite.SiteName); if (HasDatabase) { var connectionStringParameter = new DeploymentSyncParameter( "ConnectionStringParam", // Name "DBConnectionString Param", // Description _publishSettings.SqlDBConnectionString.ConnectionString, // Default Value to set null); // Tag var entry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.XmlFile, // Kind @"\\web\.config$", // Scope connectionStringXPath, // Match null); // Tag connectionStringParameter.Add(entry); sourceObject.SyncParameters.Add(connectionStringParameter); } } try { syncOptions.WhatIf = setSize; var summary = sourceObject.SyncTo(DeploymentWellKnownProvider.Manifest, GetManifest(isSource: false), destBaseOptions, syncOptions); if (!setSize) { LogTrace("Content Published Succesfully For Site: {0} to {1} ", _localSite.SiteName, _publishSettings.SiteName); Helper.UpdateStatus(_localSite.SiteName, _localSite.ServerName); } else { _control.SetProgressbarMax(this.LocalSite.ServerName + this.LocalSite.SiteName, summary.TotalChanges); } } catch (Exception ex) { string message = string.Format("Error syncing content for site: {0}", _localSite.SiteName); LogTrace(message); LogTrace(ex.ToString()); publishSucceeded = false; } } } catch (Exception ex) { LogTrace("Error starting content publish for site: {0}", _localSite.SiteName); LogTrace(ex.ToString()); publishSucceeded = false; } _control.UpdateStatusLabel(string.Empty); #endregion if (!setSize) { _control.SetContentPublished(this.LocalSite.ServerName + this.LocalSite.SiteName, publishSucceeded); } this.PublishStatus = publishSucceeded; return(publishSucceeded); }
private void Publish(object unusedState) { Operation operation = null; try { lock (_pendingPublishOperations) { operation = _pendingPublishOperations.Dequeue(); } if (operation == null) { PublishHelper.LogVerboseInformation("Publish: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId); return; } // This was not required earlier but now that every site will be synced twice for every incoming publish (Look at the postsync override in publishextender), // there are chances that same operation might get scheduled in concurrent threads which is not a supported web deploy scenario. bool canContinue = true; lock (_operationsInProgress) { if (_operationsInProgress.Contains(operation.SiteName)) { PublishHelper.LogVerboseInformation("Publish: An operation for {0} is already in progress. Thread {1} will mark it as not started to be scheduled later.", operation.SiteName, Thread.CurrentThread.ManagedThreadId); operation.Status = PublishOperationStatus.NotStarted; canContinue = false; } else { _operationsInProgress.Add(operation.SiteName); } } if (!canContinue) { lock (_completedOperations) { _completedOperations.Enqueue(operation); } return; } operation.ThreadID = Thread.CurrentThread.ManagedThreadId; operation.Status = PublishOperationStatus.Error; DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions(); AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName); using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Manifest, PublishHelper.GetPublishManifest(operation.PhysicalPath), srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; string modifiedPhysicalPath = operation.PhysicalPath; string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath); var fileServerIPParameter = new DeploymentSyncParameter( FileServerIPParameterName, FileServerIPParameterDescription, ipDefaultValue, string.Empty); var fileServerIPEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); fileServerIPParameter.Add(fileServerIPEntry); var contentPathParameter = new DeploymentSyncParameter( ContentPathParameterName, ContentPathParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.PhysicalPath.ToString()); var contentParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); contentPathParameter.Add(contentParamEntry); var setAclParameter = new DeploymentSyncParameter( SetAclParameterName, SetAclParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.SetAcl.ToString()); var setAclParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.SetAcl.ToString(), string.Empty, string.Empty); setAclParameter.Add(setAclParamEntry); depObj.SyncParameters.Add(fileServerIPParameter); depObj.SyncParameters.Add(contentPathParameter); depObj.SyncParameters.Add(setAclParameter); destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; destBaseOptions.Trace += new EventHandler <DeploymentTraceEventArgs>(WebDeployPublishTrace); destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose; depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions()); operation.Status = PublishOperationStatus.Completed; AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName); } catch (Exception e) { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); } } } catch (Exception e) { if ((e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) || e is WebHostingObjectNotFoundException) { operation.Status = PublishOperationStatus.SourceOrDestinationInvalid; } AntaresEventProvider.EventWritePublishFailOverServiceFailedToGetSourceSite(operation.SiteName, e.ToString()); } finally { lock (_completedOperations) { PublishHelper.LogVerboseInformation("Publish: Thread {0} qeuing completed operation for site: {1}", operation.ThreadID, operation.SiteName); _completedOperations.Enqueue(operation); } lock (_operationsInProgress) { _operationsInProgress.Remove(operation.SiteName); } _continueEvent.Set(); PublishHelper.LogVerboseInformation("Publish: Thread {0} exiting", Thread.CurrentThread.ManagedThreadId); } }
/// <summary> /// Web Deploy does not parameterize or run any rules (parameterization is one of the rules) when deletion is used. /// So to work around that deletecontent does a simple publish of empty content to the server and gets the IP that is hosting the volume. /// After finding the IP the deletion is called on that content path. This will effectively delete "\\someipaddress\volumename\guidfolder" /// </summary> /// <param name="unusedState">This is not used. This is the signature for the waitcallback expected by threadpool.</param> private void DeleteContent(object unusedState) { Operation operation = null; try { lock (_pendingDeleteOperations) { operation = _pendingDeleteOperations.Dequeue(); } if (operation == null) { PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} did not find any operations to process", Thread.CurrentThread.ManagedThreadId); return; } operation.ThreadID = Thread.CurrentThread.ManagedThreadId; operation.Status = PublishOperationStatus.Error; DeploymentBaseOptions srcBaseOptions = new DeploymentBaseOptions(); AntaresEventProvider.EventWritePublishFailOverServiceProgressInformation(operation.ThreadID, operation.SiteName); string remoteIP = string.Empty; bool errorOcurred = false; using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.ContentPath, Path.GetTempPath(), srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; string modifiedPhysicalPath = operation.PhysicalPath; string ipDefaultValue = GetFileServerIP(ref modifiedPhysicalPath); var queryServerIPParameter = new DeploymentSyncParameter( QueryServerIPParameterName, QueryServerIPParameterDescription, string.Empty, DeploymentWellKnownTag.PhysicalPath.ToString()); var queryServerIPParameterEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); queryServerIPParameter.Add(queryServerIPParameterEntry); var contentPathParameter = new DeploymentSyncParameter( ContentPathParameterName, ContentPathParameterDescription, modifiedPhysicalPath, DeploymentWellKnownTag.PhysicalPath.ToString()); var contentParamEntry = new DeploymentSyncParameterEntry( DeploymentSyncParameterEntryKind.ProviderPath, DeploymentWellKnownProvider.ContentPath.ToString(), string.Empty, string.Empty); contentPathParameter.Add(contentParamEntry); depObj.SyncParameters.Add(contentPathParameter); depObj.SyncParameters.Add(queryServerIPParameter); destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; depObj.SyncTo(destBaseOptions, new DeploymentSyncOptions()); } catch (Exception e) { bool unhandledException = false; // In cases where the site was deleted on the source before it was ever synced to the destination // mark as the destination invalid and set the status so that its never attempted again. if (e is DeploymentDetailedException && ((DeploymentDetailedException)e).ErrorCode == DeploymentErrorCode.ERROR_INVALID_PATH) { string[] messageArray = e.Message.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); if (messageArray.Length > 0) { remoteIP = messageArray[0]; } else { errorOcurred = true; } } else if (e is DeploymentException) { errorOcurred = true; } else { // its not a deployment exception. This is an exception not handled by web deploy such as duplicate key exception. // This needs to be retried. unhandledException = true; errorOcurred = true; } if (errorOcurred) { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); operation.Status = unhandledException ? PublishOperationStatus.Error : PublishOperationStatus.SourceOrDestinationInvalid; } } } if (!errorOcurred) { string[] pathParts = operation.PhysicalPath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries); string remotePath = string.Concat(@"\\", remoteIP, @"\", pathParts[1], @"\", pathParts[2]); using (DeploymentObject depObj = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Auto, string.Empty, srcBaseOptions)) { try { DeploymentBaseOptions destBaseOptions = new DeploymentBaseOptions(); destBaseOptions.ComputerName = operation.PublishUrl; destBaseOptions.UserName = operation.AdminCredential.UserName; destBaseOptions.Password = operation.AdminCredential.Password; destBaseOptions.AuthenticationType = "basic"; destBaseOptions.Trace += new EventHandler <DeploymentTraceEventArgs>(WebDeployPublishTrace); destBaseOptions.TraceLevel = System.Diagnostics.TraceLevel.Verbose; var syncOptions = new DeploymentSyncOptions(); syncOptions.DeleteDestination = true; depObj.SyncTo(DeploymentWellKnownProvider.ContentPath, remotePath, destBaseOptions, syncOptions); operation.Status = PublishOperationStatus.Completed; AntaresEventProvider.EventWritePublishFailOverServicePublishComplete(operation.SiteName); } catch (Exception e) { var ex = e as DeploymentDetailedException; if (ex != null && ex.ErrorCode == DeploymentErrorCode.FileOrFolderNotFound) { operation.Status = PublishOperationStatus.SourceOrDestinationInvalid; } else { AntaresEventProvider.EventWritePublishFailOverServiceFailedToPublishSite(operation.SiteName, e.ToString()); } } } } } finally { lock (_completedOperations) { PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} queuing completed operation for site: {1}", operation.ThreadID, operation.SiteName); _completedOperations.Enqueue(operation); } _continueEvent.Set(); PublishHelper.LogVerboseInformation("DeleteContent: Thread {0} exiting.", Thread.CurrentThread.ManagedThreadId); } }