public void PublishFiles(IPublishProject project, Uri destination) { ImpersonationHelper helper = null; NetworkCredential creds = null; bool impersonated = false; // Use ECWGC here so that a filter cannot run while we're impersonated (and so we always un-impersonate) System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup( (_) => { var files = project.Files; for (int i = 0; i < files.Count; i++) { var item = files[i]; try { // try copying without impersonating first... CopyOneFile(destination, item, ref helper, creds); } catch (UnauthorizedAccessException) { if (impersonated) { // user entered incorrect credentials throw; } // prompt for new credentials and switch to them if available. var res = VsCredentials.PromptForCredentials(PythonToolsPackage.Instance, destination, new[] { "NTLM" }, "", out creds); if (res == System.Windows.Forms.DialogResult.OK) { impersonated = true; helper = new ImpersonationHelper(creds); } else { throw; } // re-try the file copy w/ the new credentials. CopyOneFile(destination, item, ref helper, creds); } project.Progress = (int)(((double)i / (double)files.Count) * 100); } }, (data, exception) => { if (helper != null) { helper.Dispose(); } }, null ); }
public void PublishFiles(IPublishProject project, Uri destination) { var files = project.Files; for (int i = 0; i < files.Count; i++) { var item = files[i]; try { // try copying without impersonating first... CopyOneFile(destination, item); } catch (UnauthorizedAccessException) { var resource = new NativeMethods._NETRESOURCE(); resource.dwType = NativeMethods.RESOURCETYPE_DISK; resource.lpRemoteName = Path.GetPathRoot(destination.LocalPath); NetworkCredential creds = null; var res = VsCredentials.PromptForCredentials( _serviceProvider, destination, new[] { "NTLM" }, "", out creds); if (res != DialogResult.OK) { throw; } var netAddRes = NativeMethods.WNetAddConnection3( Process.GetCurrentProcess().MainWindowHandle, ref resource, creds.Password, creds.Domain + "\\" + creds.UserName, 0 ); if (netAddRes != 0) { string msg = Marshal.GetExceptionForHR((int)(((uint)0x80070000) | netAddRes)).Message; throw new Exception("Incorrect user name or password: " + msg); } // re-try the file copy now that we're authenticated CopyOneFile(destination, item); } project.Progress = (int)(((double)i / (double)files.Count) * 100); } }