using InfosysPublisher.Classes; using Newtonsoft.Json; using Renci.SshNet; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.InteropServices.ComTypes; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Xml; using Microsoft.Data.SqlClient; using Path = System.IO.Path; namespace InfosysPublisher { /// /// Interaction logic for MainWindow.xaml /// public partial class WinMain : Window { #region Classes public class Project { public string Name { get; set; } public string Path { get; set; } } #endregion private string _projectPath; private List _projects; private Project? _selectedProject = null; private string _selectedProjectSubPath = ""; private string _selectedProjectPublishLocation = ""; private string _selectedProjectVersion = ""; private string _selectedProjectGuid = ""; private const string SftpArchivePath = "Archive"; public WinMain() { InitializeComponent(); var version = typeof(App).Assembly.GetName().Version; this.Title += " " + version; App._application = WinSettings.GetSettings(); TbProjectsPath.LostFocus += TbProjectsPath_LostFocus; CbProjects.SelectionChanged += CbProjects_SelectionChanged; BtnPublish.Click += BtnPublish_Click; BtnSettings.Click += BtnSettings_Click; Closing += MainWindow_Closing; TbProjectsPath.Text = App._application.LastFolder; LoadProjects(); } private void BtnSettings_Click(object sender, RoutedEventArgs e) { App.OpenSettings(); } private void MainWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e) { var settings = WinSettings.GetSettings(); if (settings == null) return; settings.LastFolder = TbProjectsPath.Text; WinSettings.SaveSettings(settings); } private void CbProjects_SelectionChanged(object sender, SelectionChangedEventArgs e) { _selectedProject = (Project)CbProjects.SelectedItem; LoadProject(); } private void TbProjectsPath_LostFocus(object sender, RoutedEventArgs e) { LoadProjects(); } private void LoadProjects() { _projectPath = TbProjectsPath.Text; if (!Directory.Exists(_projectPath)) { MessageBox.Show($"Pot {_projectPath} ne obstaja!"); return; } _projects = new List(); var dirInfo = new DirectoryInfo(_projectPath); dirInfo.GetDirectories() .ToList() .ForEach(directoryInfo => directoryInfo.GetFiles("*.sln") .ToList() .ForEach(x => _projects.Add(new Project { Name = $"{directoryInfo.Name}/{x.Name}", Path = x.FullName }))); CbProjects.ItemsSource = _projects; } private void LoadProject() { TbOutput.Text = ""; LblProjectInfo.Content = ""; BtnPublish.IsEnabled = false; if (_selectedProject == null) return; _selectedProjectVersion = ""; _selectedProjectSubPath = ""; _selectedProjectPublishLocation = ""; var lines = File.ReadLines(_selectedProject.Path); lines.Where(line => line.StartsWith("Project")) .ToList() .ForEach(line => { var projectTitle = line.Split(",")[1].Replace(" ", "").Replace("\"", "").Split(@"\")[0]; var projectSubPath = Path.Combine(new FileInfo(_selectedProject.Path)?.DirectoryName ?? "", projectTitle); var projectFileInfos = new DirectoryInfo(projectSubPath) .GetFiles("*.cs") .Where(x => x.Name is "App.xaml.cs" or "Program.cs") .ToList(); if (projectFileInfos.Count <= 0) { projectFileInfos = new DirectoryInfo(projectSubPath) .GetDirectories("Properties") .SelectMany(x => x.GetFiles("AssemblyInfo.cs")) .ToList(); }; if (projectFileInfos.Count <= 0) return; var csLines = File.ReadLines(projectFileInfos[0].FullName).ToList(); var tmpSelectedProjectVersion = ""; var tmpSelectedProjectSubPath = ""; var tmpSelectedProjectPublishLocation = ""; var tmpSelectedProjectGuid = ""; csLines.Where(csLine => csLine.StartsWith("[assembly: AssemblyVersion(")) .ToList() .ForEach(csLine => { tmpSelectedProjectVersion = csLine.Replace("[assembly: AssemblyVersion(\"", "").Replace("\")]", ""); tmpSelectedProjectSubPath = projectSubPath; System.Diagnostics.Debug.WriteLine(tmpSelectedProjectVersion); }); if (tmpSelectedProjectSubPath != "") { csLines.Where(csLine => csLine.StartsWith("//Publish location:")) .ToList() .ForEach(csLine => { tmpSelectedProjectPublishLocation = csLine.Replace("//Publish location:", ""); System.Diagnostics.Debug.WriteLine(tmpSelectedProjectPublishLocation); }); //Guid za paket vnos dela, tiste ko ga imajo v program cd csLines.Where(csLine => csLine.Contains("public static string GuidAplikacije")) .ToList() .ForEach(csLine => { tmpSelectedProjectGuid = csLine.Split('"')[1]; System.Diagnostics.Debug.WriteLine(tmpSelectedProjectGuid); }); } if (tmpSelectedProjectVersion == "" || tmpSelectedProjectSubPath == "" || tmpSelectedProjectPublishLocation == "") return; //ce se ni guidja pogledam v nlog if (tmpSelectedProjectGuid == "") { var projectNlogConfig= new DirectoryInfo(projectSubPath) .GetFiles("NLog.config") .ToList(); if (projectFileInfos.Count <= 0) return; try { var xmlDocument = new XmlDocument(); xmlDocument.Load(projectNlogConfig[0].FullName); var node = xmlDocument .GetElementsByTagName("variable") .Cast() .FirstOrDefault(x => x.Attributes != null && x.Attributes.Cast().Any(y => y.Name == "name" && y.Value == "AplikacijaGuid")); if (node != null) tmpSelectedProjectGuid = node.Attributes["value"].Value; } catch (Exception exception) { MessageBox.Show(exception.ToString()); } } if (tmpSelectedProjectGuid == "") return; _selectedProjectVersion = tmpSelectedProjectVersion; _selectedProjectSubPath = tmpSelectedProjectSubPath; _selectedProjectPublishLocation = tmpSelectedProjectPublishLocation; _selectedProjectGuid = tmpSelectedProjectGuid; }); if (_selectedProjectVersion == "" || _selectedProjectSubPath == "" || _selectedProjectPublishLocation == "" || _selectedProjectGuid == "") return; LblProjectInfo.Content = $"Verzija: {_selectedProjectVersion} Pot: {_selectedProjectPublishLocation} Guid: {_selectedProjectGuid}"; BtnPublish.IsEnabled = true; } private async void BtnPublish_Click(object sender, RoutedEventArgs e) { if (_selectedProject == null || App._application == null) return; var releaseFolder = Path.Combine(_selectedProjectSubPath, @"bin\Release"); if (!Directory.Exists(releaseFolder)) { MessageBox.Show($"Mapa {releaseFolder} ne obstaja!"); return; } TbOutput.Text = $"Publish start {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; TbOutput.Text += $"\nClean {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; GridProgress.Visibility = Visibility.Visible; LblLoading.Content = $"Čiščenje mape {releaseFolder}"; await Task.Run(() => { var diReleaseFolder = new DirectoryInfo(releaseFolder); foreach (var file in diReleaseFolder.GetFiles()) { file.Delete(); } foreach (var dir in diReleaseFolder.GetDirectories()) { dir.Delete(true); } }); LblLoading.Content = $"Rebuild {_selectedProject.Path}"; TbOutput.Text += $"\nRebuild {_selectedProject.Path} {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; var output = ""; await Task.Run(() => { var command = $"devenv {_selectedProject.Path} /Rebuild \"Release\""; var cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.CreateNoWindow = true; cmd.StartInfo.UseShellExecute = false; cmd.Start(); cmd.StandardInput.WriteLine(command); //cmd.StandardInput.WriteLine("echo Oscar"); cmd.StandardInput.Flush(); cmd.StandardInput.Close(); cmd.WaitForExit(App._application.BuildSeconds * 1000); output = cmd.StandardOutput.ReadToEnd(); Debug.WriteLine("\n\n\n\n"); Debug.WriteLine(output); //System.Diagnostics.Process.Start("CMD.exe", ""); }); TbOutput.Text += "\n" + output; var zipDirectory = new DirectoryInfo(releaseFolder).Parent?.FullName ?? ""; var zipPath = Path.Combine(zipDirectory, "Package.zip"); LblLoading.Content = $"Zip {zipPath}"; TbOutput.Text += $"\nZip {zipPath} {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; if (File.Exists(zipPath)) File.Delete(zipPath); await Task.Run(() => { ZipFile.CreateFromDirectory(releaseFolder, zipPath, CompressionLevel.Optimal, false); }); UploadSftp(zipDirectory, zipPath); TbOutput.Text += $"\nVersion {_selectedProjectVersion} {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; WriteVersion(); GridProgress.Visibility = Visibility.Hidden; LblLoading.Content = ""; TbOutput.Text += $"\nEnd {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; } private async void UploadSftp(string zipDirectory, string zipPath) { if (ChbCreateOnlyZip.IsChecked != null && (bool)ChbCreateOnlyZip.IsChecked) { Process.Start("explorer.exe", zipDirectory); return; } //InfosysUpdate //v&H6c$wTbTkgSgdWvL*8k$st3#z5X LblLoading.Content = $"Upload to SFTP"; TbOutput.Text += $"\nUpload to SFTP {DateTime.Now:dd.MM.yyyy HH:mm:ss}"; var error = ""; await Task.Run(() => { try { using var sftpClient = new SftpClient(App._application.SftpServerAddress, App._application.SftpPort, App._application.SftpUsername, App._application.SftpPassword); sftpClient.Connect(); if (!sftpClient.Exists(_selectedProjectPublishLocation)) sftpClient.CreateDirectory(_selectedProjectPublishLocation); if (!sftpClient.Exists(SftpArchivePath)) sftpClient.CreateDirectory(SftpArchivePath); var files = sftpClient.ListDirectory(_selectedProjectPublishLocation).ToList(); var xmlVersion = ""; //arhiv foreach (var file in files) { if (!file.Name.ToLower().EndsWith(".xml")) continue; var tmpXmlFile = Path.GetTempFileName(); using (var tmpFile = File.OpenWrite(tmpXmlFile)) { sftpClient.DownloadFile(file.FullName, tmpFile); } try { var xmlContent = File.ReadAllText(tmpXmlFile); if (!string.IsNullOrEmpty(xmlContent)) { //Oddaljena verzije var xmlDocument = new XmlDocument(); xmlDocument.LoadXml(xmlContent); var xmlNode = xmlDocument.SelectSingleNode("/Update"); xmlVersion = xmlNode["Version"].InnerText; } } catch (Exception exception) { error += "\n\n"; error += exception.ToString(); } File.Delete(tmpXmlFile); } if (xmlVersion != "") { var projectArchive = SftpArchivePath + "/" + _selectedProjectPublishLocation; if (!sftpClient.Exists(projectArchive)) sftpClient.CreateDirectory(projectArchive); var archiveFolderWithoutIndex = projectArchive + "/" + xmlVersion.Replace(".", "_"); var archiveFolder = archiveFolderWithoutIndex; var index = 1; while (sftpClient.Exists(archiveFolder)) { archiveFolder = archiveFolderWithoutIndex + "_" + index; index++; } sftpClient.CreateDirectory(archiveFolder); foreach (var file in files) { if (!file.IsRegularFile) continue; sftpClient.Get(file.FullName).MoveTo(archiveFolder + "/" + file.Name); } } //Upload var tmpXmlFileUpload = Path.GetTempFileName(); string xml = $@" {_selectedProjectVersion} "; File.WriteAllText(tmpXmlFileUpload, xml); using (var fileStream = new FileStream(tmpXmlFileUpload, FileMode.Open)) { sftpClient.UploadFile(fileStream, _selectedProjectPublishLocation + "/" + "Update.xml", true); } using (var fileStream = new FileStream(zipPath, FileMode.Open)) { sftpClient.UploadFile(fileStream, _selectedProjectPublishLocation + "/" + "Package.zip", true); } var sftpDirVersion = _selectedProjectPublishLocation + "/" + _selectedProjectVersion; if (!sftpClient.Exists(sftpDirVersion)) sftpClient.CreateDirectory(sftpDirVersion); using (var fileStream = new FileStream(zipPath, FileMode.Open)) { sftpClient.UploadFile(fileStream, sftpDirVersion + "/" + "Package.zip", true); } File.Delete(tmpXmlFileUpload); sftpClient.Disconnect(); } catch (Exception ex) { error += "\n\n"; error += ex.ToString(); } }); if (error != "") { MessageBox.Show(error); return; } } private void WriteVersion() { using var sqlConnection = new SqlConnection(App.SqlConnectionString); sqlConnection.Open(); var sqlCommandString = @" DECLARE @idVerzija INT = NULL SELECT TOP 1 @idVerzija = ID_Verzija FROM AplikacijaVerzija WHERE GUID_Aplikacija_FK = @guid AND Verzija = @verzija IF @idVerzija IS NULL BEGIN CREATE TABLE #tmpId( ID INT ); INSERT INTO AplikacijaVerzija (GUID_Aplikacija_FK, Verzija) OUTPUT inserted.ID_Verzija INTO #tmpId VALUES (@guid, @verzija) SELECT TOP 1 @idVerzija = Id FROM #tmpId END INSERT INTO AplikacijaVerzijaRevizija (ID_AplikacijaVerzija_FK, ID_Uporabnik_FK) VALUES (@idVerzija, @idUporabnik);"; using var sqlCommand = new SqlCommand(sqlCommandString, sqlConnection); sqlCommand.Parameters.AddWithValue("guid", _selectedProjectGuid); sqlCommand.Parameters.AddWithValue("verzija", _selectedProjectVersion); sqlCommand.Parameters.AddWithValue("idUporabnik", App.User.Id); sqlCommand.ExecuteNonQuery(); } } }