From e53245981377e9d9023917451d748f639fbd0984 Mon Sep 17 00:00:00 2001 From: fionachang Date: Sat, 25 Jun 2016 14:17:36 +0800 Subject: [PATCH 1/2] Set up project --- WebDeployHelper/WebDeployHelper.sln | 22 ++++ .../WebDeployHelper/ConfigReader.cs | 102 ++++++++++++++++++ .../WebDeployHelper/DeployConfig.cs | 24 +++++ .../WebDeployHelper/DeployUploader.cs | 54 ++++++++++ WebDeployHelper/WebDeployHelper/Program.cs | 66 ++++++++++++ .../Properties/AssemblyInfo.cs | 36 +++++++ .../WebDeployHelper/TextCollection.cs | 26 +++++ WebDeployHelper/WebDeployHelper/Uploader.cs | 87 +++++++++++++++ WebDeployHelper/WebDeployHelper/Util.cs | 64 +++++++++++ .../WebDeployHelper/WebDeployHelper.conf | 12 +++ .../WebDeployHelper/WebDeployHelper.csproj | 101 +++++++++++++++++ WebDeployHelper/WebDeployHelper/app.config | 3 + .../WebDeployHelper/packages.config | 4 + 13 files changed, 601 insertions(+) create mode 100644 WebDeployHelper/WebDeployHelper.sln create mode 100644 WebDeployHelper/WebDeployHelper/ConfigReader.cs create mode 100644 WebDeployHelper/WebDeployHelper/DeployConfig.cs create mode 100644 WebDeployHelper/WebDeployHelper/DeployUploader.cs create mode 100644 WebDeployHelper/WebDeployHelper/Program.cs create mode 100644 WebDeployHelper/WebDeployHelper/Properties/AssemblyInfo.cs create mode 100644 WebDeployHelper/WebDeployHelper/TextCollection.cs create mode 100644 WebDeployHelper/WebDeployHelper/Uploader.cs create mode 100644 WebDeployHelper/WebDeployHelper/Util.cs create mode 100644 WebDeployHelper/WebDeployHelper/WebDeployHelper.conf create mode 100644 WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj create mode 100644 WebDeployHelper/WebDeployHelper/app.config create mode 100644 WebDeployHelper/WebDeployHelper/packages.config diff --git a/WebDeployHelper/WebDeployHelper.sln b/WebDeployHelper/WebDeployHelper.sln new file mode 100644 index 0000000..5446a9c --- /dev/null +++ b/WebDeployHelper/WebDeployHelper.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebDeployHelper", "WebDeployHelper\WebDeployHelper.csproj", "{C43BDD5D-FDC9-45BF-B2C8-233F9E339624}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C43BDD5D-FDC9-45BF-B2C8-233F9E339624}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C43BDD5D-FDC9-45BF-B2C8-233F9E339624}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C43BDD5D-FDC9-45BF-B2C8-233F9E339624}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C43BDD5D-FDC9-45BF-B2C8-233F9E339624}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/WebDeployHelper/WebDeployHelper/ConfigReader.cs b/WebDeployHelper/WebDeployHelper/ConfigReader.cs new file mode 100644 index 0000000..1562bbb --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/ConfigReader.cs @@ -0,0 +1,102 @@ +using System; +using System.IO; + +namespace WebDeployHelper +{ + class ConfigReader + { + #region Read Config + + private readonly string _currentDirectory; + private readonly string _configDirectory; + + private static string _configDirUpload; + private static string _configReleaseType; + private static string _configSftpAddress; + private static string _configSftpUser; + private static string _configDevPath; + private static string _configReleasePath; + + public ConfigReader() + { + _configDirectory = DeployConfig.DirConfig; + } + + public ConfigReader(string configDirectory, string vstoDirectory) + { + _configDirectory = configDirectory; + } + + public ConfigReader ReadConfig() + { + //Sequence matters + InitConfigVariables(); + InitDeployInfo(); + return this; + } + + public override string ToString() + { + return + "ConfigDirUpload: " + _configDirUpload + "\r\n" + + "ConfigReleaseType: " + _configReleaseType + "\r\n" + + "ConfigSftpAddress: " + _configSftpAddress + "\r\n" + + "ConfigSftpUser: " + _configSftpUser + "\r\n" + + "ConfigDevPath: " + _configDevPath + "\r\n" + + "ConfigReleasePath: " + _configReleasePath + "\r\n"; + } + + public DeployConfig ToDeployConfig() + { + var config = new DeployConfig + { + ConfigDirUpload = _configDirUpload, + ConfigReleaseType = _configReleaseType, + ConfigSftpAddress = _configSftpAddress, + ConfigSftpUser = _configSftpUser, + ConfigDevPath = _configDevPath, + ConfigReleasePath = _configReleasePath + }; + return config; + } + + private void InitConfigVariables() + { + string[] configContent = {}; + try + { + configContent = File.ReadAllLines(_configDirectory); + } + catch (Exception e) + { + Util.DisplayWarning(TextCollection.Const.ErrorNoConfig, e); + } + + //index here refers to the line number in DeployHelper.conf + _configDirUpload = configContent[1]; + _configReleaseType = configContent[3]; + _configSftpAddress = configContent[5]; + _configSftpUser = configContent[7]; + _configDevPath = configContent[9]; + _configReleasePath = configContent[11]; + } + + private void InitDeployInfo() + { + PrintInfo("You are going to deploy PowerPointLabs Website\r\n"); + Console.Write("Settings info:\n"); + PrintInfo("Upload Directory: ", _configDirUpload); + PrintInfo("Release Type: ", _configReleaseType); + PrintInfo("Dev Path: ", _configDevPath); + PrintInfo("Release Path: ", _configReleasePath); + } + + private void PrintInfo(string text, string highlightedText = "") + { + Console.Write(text); + Util.ConsoleWriteWithColor(highlightedText, ConsoleColor.Yellow); + Console.WriteLine(""); + } + #endregion + } +} diff --git a/WebDeployHelper/WebDeployHelper/DeployConfig.cs b/WebDeployHelper/WebDeployHelper/DeployConfig.cs new file mode 100644 index 0000000..67cdb0c --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/DeployConfig.cs @@ -0,0 +1,24 @@ +using System; + +namespace WebDeployHelper +{ + class DeployConfig + { + public static readonly string DirConfig = Environment.CurrentDirectory + @"\WebDeployHelper.conf"; + + public string ConfigDirUpload; + public string ConfigReleaseType; + public string ConfigSftpAddress; + public string ConfigSftpUser; + public string ConfigDevPath; + public string ConfigReleasePath; + + public void VerifyConfig() + { + if (ConfigReleaseType != "release" && ConfigReleaseType != "dev") + { + Util.DisplayWarning(TextCollection.Const.ErrorInvalidConfig + " Release type not correct.", new Exception()); + } + } + } +} diff --git a/WebDeployHelper/WebDeployHelper/DeployUploader.cs b/WebDeployHelper/WebDeployHelper/DeployUploader.cs new file mode 100644 index 0000000..aa219fe --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/DeployUploader.cs @@ -0,0 +1,54 @@ +using System; +using WinSCP; + +namespace WebDeployHelper +{ + class DeployUploader + { + #region SFTP upload + + private readonly DeployConfig _config; + + public DeployUploader(DeployConfig config) + { + _config = config; + } + + public void SftpUpload() + { + try + { + using (var session = new Session()) + { + Console.WriteLine("\nConnecting the server..."); + var uploader = new Uploader(); + uploader.SetConfig(_config); + session.Open(uploader.GetSessionOptions()); + if (session.Opened) + { + Util.DisplayDone(TextCollection.Const.DoneSftpConnected); + Console.WriteLine(TextCollection.Const.InfoFileUploading); + + var remotePath = uploader.SetupRemotePath(); + var transferOptions = uploader.SetupTransferOptions(); + + uploader.UploadLocalDirectory(session, remotePath, transferOptions); + + Util.DisplayDone(TextCollection.Const.DoneUploaded); + } + else + { + Util.DisplayWarning(TextCollection.Const.ErrorNetworkFailed, new InvalidOperationException()); + } + } + } + catch (Exception e) + { + Console.WriteLine("Error during SFTP uploading: {0}", e); + Util.DisplayWarning(TextCollection.Const.ErrorNetworkFailed, e); + } + } + + #endregion + } +} diff --git a/WebDeployHelper/WebDeployHelper/Program.cs b/WebDeployHelper/WebDeployHelper/Program.cs new file mode 100644 index 0000000..25b7e51 --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/Program.cs @@ -0,0 +1,66 @@ +using System; +#region WebDeployHelper Description +// +// WebDeployHelper Class +// ------------------ +// Simply double click the .exe file to patch PowerPointLabs Website, +// so that it uploads the files onto the PowerPointLabs server. +// +// HOW TO USE +// +// For the first time use, you need to setup the followings: +// +// 0. Compile WebDeployHelper using Visual Studio. .NET 4.5 is required. The output program is under bin/debug or bin/release folder. +// +// 1. Fill in WebDeployHelper.conf +// - Upload directory is the local directory to upload to the server +// - Release type is dev or release +// - SFTP address is the server to upload to +// - SFTP username is the username used to login the server +// - Dev path is the installation folder path on the server for dev version PowerPointLabs Website +// - Release path is the installation folder path on the server for release version PowerPointLabs Website +// +// 2. Copy WebDeployHelper.exe, WebDeployHelper.conf, WinSCP.exe and WinSCPnet.dll from the output folder to the publish folder +// +// 3. Run WebDeployHelper.exe and follow the instructions. +// +// For the next time +// +// 0. Run WebDeployHelper.exe and follow the instructions. +// +// Have a nice day :) +// +//TODO: add testing +#endregion +namespace WebDeployHelper +{ + class Program + { + public static void Main(string[] args) + { + try + { + # region Init + + var config = new ConfigReader() + .ReadConfig() + .ToDeployConfig(); + config.VerifyConfig(); + + # endregion + + new DeployUploader(config) + .SftpUpload(); + Util.DisplayEndMessage(); + } + catch + { + Util.IgnoreException(); + } + finally + { + Console.ReadKey(); + } + } + } +} diff --git a/WebDeployHelper/WebDeployHelper/Properties/AssemblyInfo.cs b/WebDeployHelper/WebDeployHelper/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ccbebf6 --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("DeployHelper")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("DeployHelper")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("57277935-16d4-471b-9706-49fca9fa69cb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WebDeployHelper/WebDeployHelper/TextCollection.cs b/WebDeployHelper/WebDeployHelper/TextCollection.cs new file mode 100644 index 0000000..5f35287 --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/TextCollection.cs @@ -0,0 +1,26 @@ + +namespace WebDeployHelper +{ + class TextCollection + { + #region Const + + public class Const + { + public const string ErrorNoConfig = "Can't Find Config."; + public const string ErrorInvalidConfig = "Invalid Config."; + public const string ErrorNetworkFailed = "Can't Connect The Server."; + + public const string DoneSftpConnected = "SFTP Connected."; + public const string DoneUploaded = "Uploaded."; + + public const string InfoEnterPassword = "Enter SFTP password: "; + public const string InfoFileUploading = "Uploading files..."; + + public const string VarDev = "dev"; + public const string VarRelease = "release"; + } + + # endregion + } +} diff --git a/WebDeployHelper/WebDeployHelper/Uploader.cs b/WebDeployHelper/WebDeployHelper/Uploader.cs new file mode 100644 index 0000000..d60448e --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/Uploader.cs @@ -0,0 +1,87 @@ +using System; +using WinSCP; + +namespace WebDeployHelper +{ + class Uploader + { + private const bool IsToRemoveAfterUpload = false; + + protected DeployConfig Config; + + public void SetConfig(DeployConfig config) + { + Config = config; + } + + public void UploadLocalDirectory(Session session, string remotePath, TransferOptions transferOptions) + { + // Construct folder with permissions first + try + { + session.SynchronizeDirectories(SynchronizationMode.Remote, Config.ConfigDirUpload, remotePath, IsToRemoveAfterUpload, + options: transferOptions); + } + catch (InvalidOperationException) + { + if (session.Opened) + { + Util.IgnoreException(); + } + else + { + throw; + } + } + + var synchronizeResult = session.SynchronizeDirectories(SynchronizationMode.Remote, Config.ConfigDirUpload, remotePath, + IsToRemoveAfterUpload, options: transferOptions); + synchronizeResult.Check(); + } + + public TransferOptions SetupTransferOptions() + { + var transferOptions = new TransferOptions { TransferMode = TransferMode.Binary }; + var permissions = new FilePermissions { Octal = "644" }; + transferOptions.FilePermissions = permissions; + return transferOptions; + } + + public string SetupRemotePath() + { + var versionToUpload = Config.ConfigReleaseType; + switch (versionToUpload) + { + case TextCollection.Const.VarDev: + return Config.ConfigDevPath; + case TextCollection.Const.VarRelease: + return Config.ConfigReleasePath; + default: + Util.DisplayWarning("Incorrect release type!", new Exception()); + //dummy return, won't reach + return Config.ConfigDevPath; + } + } + + public SessionOptions GetSessionOptions() + { + string password = null; + while (password == null || password.Trim() == "") + { + Console.Write(TextCollection.Const.InfoEnterPassword); + password = Util.ReadPassword(); + } + + var sessionOptions = new SessionOptions + { + Protocol = Protocol.Sftp, + HostName = Config.ConfigSftpAddress, + UserName = Config.ConfigSftpUser, + Password = password, + PortNumber = 22, //TODO: make it configurable + GiveUpSecurityAndAcceptAnySshHostKey = true + }; + return sessionOptions; + } + } +} diff --git a/WebDeployHelper/WebDeployHelper/Util.cs b/WebDeployHelper/WebDeployHelper/Util.cs new file mode 100644 index 0000000..8c07fba --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/Util.cs @@ -0,0 +1,64 @@ +using System; +using System.Text; + +namespace WebDeployHelper +{ + class Util + { + #region Helper functions + + public static void ConsoleWriteWithColor(String content, ConsoleColor color) + { + Console.ForegroundColor = color; + Console.Write(content); + Console.ResetColor(); + } + + public static void IgnoreException() + { + } + + public static void DisplayWarning(string content, Exception e) + { + ConsoleWriteWithColor(content, ConsoleColor.Red); + throw new InvalidOperationException(content, e); + } + + public static void DisplayDone(string content) + { + ConsoleWriteWithColor(content + "\n", ConsoleColor.Green); + } + + public static void DisplayEndMessage() + { + DisplayDone("All Done!"); + Console.WriteLine("Have a nice day :)"); + } + + public static string ReadPassword() + { + StringBuilder password = new StringBuilder(); + ConsoleKeyInfo info = Console.ReadKey(true); + while (info.Key != ConsoleKey.Enter) + { + if (info.Key != ConsoleKey.Backspace) + { + password.Append(info.KeyChar); + } + else if (info.Key == ConsoleKey.Backspace) + { + if (password.Length > 0) + { + password.Length--; + } + } + info = Console.ReadKey(true); + } + // add a new line because user pressed enter at the end of their password + Console.WriteLine(); + return password.ToString(); + } + + #endregion + } +} diff --git a/WebDeployHelper/WebDeployHelper/WebDeployHelper.conf b/WebDeployHelper/WebDeployHelper/WebDeployHelper.conf new file mode 100644 index 0000000..a6a5704 --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/WebDeployHelper.conf @@ -0,0 +1,12 @@ +//upload directory +... +//release type +dev +//SFTP address +... +//SFTP username +... +//Dev path +... +//Release path +... \ No newline at end of file diff --git a/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj b/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj new file mode 100644 index 0000000..9d9d0e6 --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj @@ -0,0 +1,101 @@ + + + + + Debug + AnyCPU + {C43BDD5D-FDC9-45BF-B2C8-233F9E339624} + Exe + Properties + WebDeployHelper + WebDeployHelper + v4.5 + 512 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + False + ..\packages\WinSCP.5.5.3\lib\WinSCPnet.dll + + + + + + + + + + + + + + + + + + + + False + Microsoft .NET Framework 4.5 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + + + + \ No newline at end of file diff --git a/WebDeployHelper/WebDeployHelper/app.config b/WebDeployHelper/WebDeployHelper/app.config new file mode 100644 index 0000000..c5e1dae --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/app.config @@ -0,0 +1,3 @@ + + + diff --git a/WebDeployHelper/WebDeployHelper/packages.config b/WebDeployHelper/WebDeployHelper/packages.config new file mode 100644 index 0000000..a9d1c8a --- /dev/null +++ b/WebDeployHelper/WebDeployHelper/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 6a6a7b900a670fa60ffd00fb63d2d7747655ddb4 Mon Sep 17 00:00:00 2001 From: fionachang Date: Mon, 27 Jun 2016 18:03:46 +0800 Subject: [PATCH 2/2] Explicitly upload files and directory with specified permissions --- .../WebDeployHelper/ConfigReader.cs | 47 ++++--- .../WebDeployHelper/DeployConfig.cs | 10 +- .../WebDeployHelper/DeployUploader.cs | 32 +---- WebDeployHelper/WebDeployHelper/Program.cs | 3 +- .../WebDeployHelper/TextCollection.cs | 27 ++-- WebDeployHelper/WebDeployHelper/Uploader.cs | 119 +++++++++--------- .../WebDeployHelper/WebDeployHelper.csproj | 5 - .../WebDeployHelper/packages.config | 4 - 8 files changed, 109 insertions(+), 138 deletions(-) delete mode 100644 WebDeployHelper/WebDeployHelper/packages.config diff --git a/WebDeployHelper/WebDeployHelper/ConfigReader.cs b/WebDeployHelper/WebDeployHelper/ConfigReader.cs index 1562bbb..e65e5a4 100644 --- a/WebDeployHelper/WebDeployHelper/ConfigReader.cs +++ b/WebDeployHelper/WebDeployHelper/ConfigReader.cs @@ -6,8 +6,7 @@ namespace WebDeployHelper class ConfigReader { #region Read Config - - private readonly string _currentDirectory; + private readonly string _configDirectory; private static string _configDirUpload; @@ -17,6 +16,8 @@ class ConfigReader private static string _configDevPath; private static string _configReleasePath; + private static string _remotePath; + public ConfigReader() { _configDirectory = DeployConfig.DirConfig; @@ -31,21 +32,11 @@ public ConfigReader ReadConfig() { //Sequence matters InitConfigVariables(); + InitRemotePath(); InitDeployInfo(); return this; } - public override string ToString() - { - return - "ConfigDirUpload: " + _configDirUpload + "\r\n" + - "ConfigReleaseType: " + _configReleaseType + "\r\n" + - "ConfigSftpAddress: " + _configSftpAddress + "\r\n" + - "ConfigSftpUser: " + _configSftpUser + "\r\n" + - "ConfigDevPath: " + _configDevPath + "\r\n" + - "ConfigReleasePath: " + _configReleasePath + "\r\n"; - } - public DeployConfig ToDeployConfig() { var config = new DeployConfig @@ -54,8 +45,7 @@ public DeployConfig ToDeployConfig() ConfigReleaseType = _configReleaseType, ConfigSftpAddress = _configSftpAddress, ConfigSftpUser = _configSftpUser, - ConfigDevPath = _configDevPath, - ConfigReleasePath = _configReleasePath + RemotePath = _remotePath }; return config; } @@ -69,7 +59,7 @@ private void InitConfigVariables() } catch (Exception e) { - Util.DisplayWarning(TextCollection.Const.ErrorNoConfig, e); + Util.DisplayWarning(TextCollection.ErrorNoConfig, e); } //index here refers to the line number in DeployHelper.conf @@ -81,14 +71,31 @@ private void InitConfigVariables() _configReleasePath = configContent[11]; } + private void InitRemotePath() + { + switch (_configReleaseType) + { + case TextCollection.VarRelease: + _remotePath = _configReleasePath; + break; + case TextCollection.VarDev: + _remotePath = _configDevPath; + break; + default: + Util.DisplayWarning(TextCollection.ErrorInvalidReleaseType, new Exception()); + break; + } + } + private void InitDeployInfo() { - PrintInfo("You are going to deploy PowerPointLabs Website\r\n"); - Console.Write("Settings info:\n"); + PrintInfo("You are going to deploy PowerPointLabs Website"); + PrintInfo(""); + PrintInfo("Settings info:"); PrintInfo("Upload Directory: ", _configDirUpload); PrintInfo("Release Type: ", _configReleaseType); - PrintInfo("Dev Path: ", _configDevPath); - PrintInfo("Release Path: ", _configReleasePath); + PrintInfo("Remote Path: ", _remotePath); + PrintInfo(""); } private void PrintInfo(string text, string highlightedText = "") diff --git a/WebDeployHelper/WebDeployHelper/DeployConfig.cs b/WebDeployHelper/WebDeployHelper/DeployConfig.cs index 67cdb0c..31a1638 100644 --- a/WebDeployHelper/WebDeployHelper/DeployConfig.cs +++ b/WebDeployHelper/WebDeployHelper/DeployConfig.cs @@ -10,15 +10,7 @@ class DeployConfig public string ConfigReleaseType; public string ConfigSftpAddress; public string ConfigSftpUser; - public string ConfigDevPath; - public string ConfigReleasePath; - public void VerifyConfig() - { - if (ConfigReleaseType != "release" && ConfigReleaseType != "dev") - { - Util.DisplayWarning(TextCollection.Const.ErrorInvalidConfig + " Release type not correct.", new Exception()); - } - } + public string RemotePath; } } diff --git a/WebDeployHelper/WebDeployHelper/DeployUploader.cs b/WebDeployHelper/WebDeployHelper/DeployUploader.cs index aa219fe..e6ee72b 100644 --- a/WebDeployHelper/WebDeployHelper/DeployUploader.cs +++ b/WebDeployHelper/WebDeployHelper/DeployUploader.cs @@ -1,5 +1,4 @@ using System; -using WinSCP; namespace WebDeployHelper { @@ -18,34 +17,15 @@ public void SftpUpload() { try { - using (var session = new Session()) - { - Console.WriteLine("\nConnecting the server..."); - var uploader = new Uploader(); - uploader.SetConfig(_config); - session.Open(uploader.GetSessionOptions()); - if (session.Opened) - { - Util.DisplayDone(TextCollection.Const.DoneSftpConnected); - Console.WriteLine(TextCollection.Const.InfoFileUploading); - - var remotePath = uploader.SetupRemotePath(); - var transferOptions = uploader.SetupTransferOptions(); - - uploader.UploadLocalDirectory(session, remotePath, transferOptions); - - Util.DisplayDone(TextCollection.Const.DoneUploaded); - } - else - { - Util.DisplayWarning(TextCollection.Const.ErrorNetworkFailed, new InvalidOperationException()); - } - } + Console.WriteLine("Connecting the server..."); + var uploader = new Uploader(); + uploader.SetConfig(_config); + uploader.Upload(); } catch (Exception e) { - Console.WriteLine("Error during SFTP uploading: {0}", e); - Util.DisplayWarning(TextCollection.Const.ErrorNetworkFailed, e); + Console.WriteLine("Error during SFTP uploading:"); + Util.DisplayWarning(e.Message, e); } } diff --git a/WebDeployHelper/WebDeployHelper/Program.cs b/WebDeployHelper/WebDeployHelper/Program.cs index 25b7e51..3cb47ce 100644 --- a/WebDeployHelper/WebDeployHelper/Program.cs +++ b/WebDeployHelper/WebDeployHelper/Program.cs @@ -20,7 +20,7 @@ // - Dev path is the installation folder path on the server for dev version PowerPointLabs Website // - Release path is the installation folder path on the server for release version PowerPointLabs Website // -// 2. Copy WebDeployHelper.exe, WebDeployHelper.conf, WinSCP.exe and WinSCPnet.dll from the output folder to the publish folder +// 2. Copy WebDeployHelper.exe, WebDeployHelper.conf, WinSCP.exe and WinSCP.com from the output folder to the publish folder // // 3. Run WebDeployHelper.exe and follow the instructions. // @@ -45,7 +45,6 @@ public static void Main(string[] args) var config = new ConfigReader() .ReadConfig() .ToDeployConfig(); - config.VerifyConfig(); # endregion diff --git a/WebDeployHelper/WebDeployHelper/TextCollection.cs b/WebDeployHelper/WebDeployHelper/TextCollection.cs index 5f35287..3b798c5 100644 --- a/WebDeployHelper/WebDeployHelper/TextCollection.cs +++ b/WebDeployHelper/WebDeployHelper/TextCollection.cs @@ -3,24 +3,19 @@ namespace WebDeployHelper { class TextCollection { - #region Const - - public class Const - { - public const string ErrorNoConfig = "Can't Find Config."; - public const string ErrorInvalidConfig = "Invalid Config."; - public const string ErrorNetworkFailed = "Can't Connect The Server."; - - public const string DoneSftpConnected = "SFTP Connected."; - public const string DoneUploaded = "Uploaded."; + public const string ErrorNoConfig = "Cannot find config file."; + public const string ErrorInvalidReleaseType = "Invalid release type in config file."; + + public const string DoneUploaded = "Uploaded."; - public const string InfoEnterPassword = "Enter SFTP password: "; - public const string InfoFileUploading = "Uploading files..."; + public const string InfoEnterPassword = "Enter SFTP password: "; - public const string VarDev = "dev"; - public const string VarRelease = "release"; - } + public const string VarDev = "dev"; + public const string VarRelease = "release"; - # endregion + public const string FileXmlLogName = "log.xml"; + + public const string PermissionsFile = "644"; + public const string PermissionsDirectory = "755"; } } diff --git a/WebDeployHelper/WebDeployHelper/Uploader.cs b/WebDeployHelper/WebDeployHelper/Uploader.cs index d60448e..1f93d57 100644 --- a/WebDeployHelper/WebDeployHelper/Uploader.cs +++ b/WebDeployHelper/WebDeployHelper/Uploader.cs @@ -1,5 +1,9 @@ using System; -using WinSCP; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Xml; +using System.Xml.XPath; namespace WebDeployHelper { @@ -14,74 +18,77 @@ public void SetConfig(DeployConfig config) Config = config; } - public void UploadLocalDirectory(Session session, string remotePath, TransferOptions transferOptions) + public void Upload() { - // Construct folder with permissions first - try - { - session.SynchronizeDirectories(SynchronizationMode.Remote, Config.ConfigDirUpload, remotePath, IsToRemoveAfterUpload, - options: transferOptions); - } - catch (InvalidOperationException) - { - if (session.Opened) - { - Util.IgnoreException(); - } - else - { - throw; - } - } + var winscp = new Process(); + winscp.StartInfo.FileName = "winscp.com"; + winscp.StartInfo.Arguments = "/xmllog=\"" + TextCollection.FileXmlLogName + "\""; + winscp.StartInfo.UseShellExecute = false; + winscp.StartInfo.CreateNoWindow = true; + winscp.StartInfo.RedirectStandardInput = true; + winscp.Start(); - var synchronizeResult = session.SynchronizeDirectories(SynchronizationMode.Remote, Config.ConfigDirUpload, remotePath, - IsToRemoveAfterUpload, options: transferOptions); - synchronizeResult.Check(); - } + var writer = winscp.StandardInput; - public TransferOptions SetupTransferOptions() - { - var transferOptions = new TransferOptions { TransferMode = TransferMode.Binary }; - var permissions = new FilePermissions { Octal = "644" }; - transferOptions.FilePermissions = permissions; - return transferOptions; - } + WriteUploadCommands(writer); - public string SetupRemotePath() - { - var versionToUpload = Config.ConfigReleaseType; - switch (versionToUpload) - { - case TextCollection.Const.VarDev: - return Config.ConfigDevPath; - case TextCollection.Const.VarRelease: - return Config.ConfigReleasePath; - default: - Util.DisplayWarning("Incorrect release type!", new Exception()); - //dummy return, won't reach - return Config.ConfigDevPath; - } + writer.Close(); + winscp.WaitForExit(); + + CheckForError(); } - - public SessionOptions GetSessionOptions() + + private void WriteUploadCommands(StreamWriter writer) { + writer.WriteLine("open sftp://" + Config.ConfigSftpUser + "@" + Config.ConfigSftpAddress + ":22 -hostkey=\"*\""); + string password = null; while (password == null || password.Trim() == "") { - Console.Write(TextCollection.Const.InfoEnterPassword); + Console.Write(TextCollection.InfoEnterPassword); password = Util.ReadPassword(); } + writer.WriteLine(password); + password = null; + + writer.WriteLine("option confirm off"); + writer.WriteLine("put -permissions=" + TextCollection.PermissionsFile + " -transfer=binary \"" + Config.ConfigDirUpload + + "\" \"" + Config.RemotePath + "\""); + + var directoryInfos = new DirectoryInfo(Config.ConfigDirUpload).EnumerateDirectories("*", SearchOption.AllDirectories); + + foreach (var directoryInfo in directoryInfos) + { + string remoteDirectoryPath = Config.RemotePath + directoryInfo.FullName.Replace(Config.ConfigDirUpload, "").Replace("\\", "/"); + + writer.WriteLine("chmod " + TextCollection.PermissionsDirectory + " \"" + remoteDirectoryPath + "\""); + } + + writer.WriteLine("exit"); + } - var sessionOptions = new SessionOptions + private void CheckForError() + { + var log = new XPathDocument(TextCollection.FileXmlLogName); + var xmlNamespace = new XmlNamespaceManager(new NameTable()); + xmlNamespace.AddNamespace("w", "http://winscp.net/schema/session/1.0"); + var navigator = log.CreateNavigator(); + var iterator = navigator.Select("//w:message", xmlNamespace); + + if (iterator.Count > 0) + { + var errorMessage = new StringBuilder(); + foreach (XPathNavigator message in iterator) + { + errorMessage.AppendLine(message.Value); + } + + throw new Exception(errorMessage.ToString()); + } + else { - Protocol = Protocol.Sftp, - HostName = Config.ConfigSftpAddress, - UserName = Config.ConfigSftpUser, - Password = password, - PortNumber = 22, //TODO: make it configurable - GiveUpSecurityAndAcceptAnySshHostKey = true - }; - return sessionOptions; + Console.WriteLine(TextCollection.DoneUploaded); + } } } } diff --git a/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj b/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj index 9d9d0e6..3b6642a 100644 --- a/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj +++ b/WebDeployHelper/WebDeployHelper/WebDeployHelper.csproj @@ -58,10 +58,6 @@ - - False - ..\packages\WinSCP.5.5.3\lib\WinSCPnet.dll - @@ -75,7 +71,6 @@ - diff --git a/WebDeployHelper/WebDeployHelper/packages.config b/WebDeployHelper/WebDeployHelper/packages.config deleted file mode 100644 index a9d1c8a..0000000 --- a/WebDeployHelper/WebDeployHelper/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file