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 static readonly string SftpServerAddress = "192.168.111.75";
private static readonly int SftpPort = 300;
private static readonly string SftpUsername = "InfosysUpdate";
private static readonly string SftpPassword = "v&H6c$wTbTkgSgdWvL*8k$st3#z5X";
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(SftpServerAddress, SftpPort, SftpUsername, 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();
}
}
}