Auto updater added

This commit is contained in:
goomatt33 2023-11-20 16:20:20 -05:00
parent 87a73ff24b
commit 8cff012772
23 changed files with 776 additions and 33 deletions

View File

@ -1,11 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.33529.622
# Visual Studio Version 17
VisualStudioVersion = 17.7.34009.444
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PWAPPv2", "PWAPPv2\PWAPPv2.csproj", "{45E26AF8-41D7-4308-A2C8-D55A0350DB47}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "UnitTests\UnitTests.csproj", "{164B9220-F337-4E88-B619-0C52C502B9C4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PWAppUpdater", "PWAppUpdater\PWAppUpdater.csproj", "{B84B314C-C17A-42A3-BCAE-038F48343F5A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PWAppUpdaterForm", "PWAppUpdater2\PWAppUpdaterForm.csproj", "{093798DD-2EDD-4519-AAC6-9DFF0DE3C15A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -17,10 +19,14 @@ Global
{45E26AF8-41D7-4308-A2C8-D55A0350DB47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{45E26AF8-41D7-4308-A2C8-D55A0350DB47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{45E26AF8-41D7-4308-A2C8-D55A0350DB47}.Release|Any CPU.Build.0 = Release|Any CPU
{164B9220-F337-4E88-B619-0C52C502B9C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{164B9220-F337-4E88-B619-0C52C502B9C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{164B9220-F337-4E88-B619-0C52C502B9C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{164B9220-F337-4E88-B619-0C52C502B9C4}.Release|Any CPU.Build.0 = Release|Any CPU
{B84B314C-C17A-42A3-BCAE-038F48343F5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B84B314C-C17A-42A3-BCAE-038F48343F5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B84B314C-C17A-42A3-BCAE-038F48343F5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B84B314C-C17A-42A3-BCAE-038F48343F5A}.Release|Any CPU.Build.0 = Release|Any CPU
{093798DD-2EDD-4519-AAC6-9DFF0DE3C15A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{093798DD-2EDD-4519-AAC6-9DFF0DE3C15A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{093798DD-2EDD-4519-AAC6-9DFF0DE3C15A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{093798DD-2EDD-4519-AAC6-9DFF0DE3C15A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,10 +1,10 @@
using Microsoft.Win32;
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Windows.Media;
/**
* TODO:
@ -40,7 +40,10 @@ namespace PWAPPv2
List<Source.DataObjects.PWImage> images;
string ConfigPath = "C:\\PWAPP\\Config\\Config.xml";
//string ConfigPath = "C:\\PWAPP\\Config\\Config.xml";
string ConfigPath;
public MainWindow()
{
@ -53,7 +56,10 @@ namespace PWAPPv2
try
{
practiceConfig = new Source.Config.Configuration(".\\Config\\PracticeConfig.xml");
ConfigPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
ConfigPath = Path.Combine(ConfigPath, "PWAPP\\Config\\");
practiceConfig = new Source.Config.Configuration(ConfigPath + "PracticeConfig.xml");
universalConfig = new Source.Config.Configuration(".\\Config\\UniversalConfig.xml");
}
catch
@ -66,15 +72,28 @@ namespace PWAPPv2
try
{
if(pwapiConnection.CheckForUpdate() == true)
if (pwapiConnection.CheckForUpdate() == true)
{
string message = "An update is available! Would you like to install it?";
string title = "Update available!";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result = System.Windows.Forms.MessageBox.Show(message, title, buttons);
if(result == System.Windows.Forms.DialogResult.Yes)
if (result == System.Windows.Forms.DialogResult.Yes)
{
System.Windows.MessageBox.Show("HAHA NO UPDATE FOR YOU!");
//System.Windows.MessageBox.Show("HAHA NO UPDATE FOR YOU!");
Process p = new Process();
p.StartInfo.FileName = "E:\\PatientWebAPI\\PWAPPv2\\PWAPPv2\\PWAppUpdater2\\bin\\Release\\net6.0-windows\\PWAppUpdaterForm.exe";
p.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.Arguments = args[0];
if(System.Environment.OSVersion.Version.Major >= 6)
{
p.StartInfo.Verb = "runas";
}
p.Start();
Environment.Exit(0);
}
}
}
@ -104,11 +123,11 @@ namespace PWAPPv2
this.DataContext = new Source.PatientGUIAdapter(patient);
}
catch(NullReferenceException)
catch (NullReferenceException)
{
}
catch(Exception e)
catch (Exception e)
{
System.Windows.MessageBox.Show(e.Message);
}
@ -123,20 +142,21 @@ namespace PWAPPv2
private void PopulateReferTypesBox()
{
string ReferTypeString = apiConnection.SendPostRequestAsync("api/PWReferralTypes");
//string ReferTypeString = apiConnection.SendPostRequestAsync("api/PWReferralTypes");
string ReferTypeString = pwapiConnection.GetReferalTypes();
TypeBox = new Source.DataObjects.ReferralTypeBox(boxReferType, ReferTypeString);
}
private void PopulateReferToBox()
{
string ReferToString = apiConnection.SendPostRequestAsync("api/PWReferTo");
string ReferToString = pwapiConnection.GetReferTo(); //apiConnection.SendPostRequestAsync("api/PWReferTo");
ToBox = new Source.DataObjects.ReferToBox(boxReferTo, ReferToString);
}
private void PopulateReferFromBox()
{
string ReferFromString = apiConnection.SendPostRequestAsync("api/PWReferFrom");
string ReferFromString = pwapiConnection.GetReferFrom(); //apiConnection.SendPostRequestAsync("api/PWReferFrom");
FromBox = new Source.DataObjects.ReferFromBox(boxReferFrom, ReferFromString);
}
@ -205,7 +225,7 @@ namespace PWAPPv2
try
{
string referralString = referral.ToJsonString();
string result = apiConnection.SendPostRequestAsync("api/PWMakeReferral", referralString);
string result = pwapiConnection.SendReferral(referralString); //apiConnection.SendPostRequestAsync("api/PWMakeReferral", referralString);
if (images.Count > 0)
{
foreach (Source.DataObjects.PWImage im in images)
@ -214,12 +234,10 @@ namespace PWAPPv2
string json = att.ToJsonString();
apiConnection.SendPostRequestAsync("api/PWAttachment", json);
}
System.Windows.MessageBox.Show("Referral added successfully!");
}
else
{
System.Windows.MessageBox.Show(result);
}
System.Windows.MessageBox.Show("Referral added successfully!");
this.Close();
}
catch (Source.DataObjects.Referral.InvalidReferalDataException)
@ -236,7 +254,7 @@ namespace PWAPPv2
openFileDialog.Filter = "Image files (*.jpg,*.jpeg)|*.jpg;*.jpeg";
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
foreach (string filename in openFileDialog.FileNames)
{

View File

@ -100,6 +100,7 @@ namespace PWAPPv2.Source.API
Client.DefaultRequestHeaders.Add("ApiID", Credentials.APIid);
StringContent content = new StringContent(PostData, Encoding.UTF8, "application/json");
string conts = content.ToString();
var response = Client.PostAsync(apiUri, content).Result;

View File

@ -12,6 +12,12 @@ namespace PWAPPv2.Source.API
private APIConnection BaseConnection;
private APIConnection UpdateConnection;
private APIConnection AttachementConnection;
private APIConnection ReferralConnection;
private APIConnection ReferToConnection;
private APIConnection ReferFromConnection;
private APIConnection ReferTypesConnection;
private APICredentials Credentials;
private string AppVersion;
@ -20,6 +26,11 @@ namespace PWAPPv2.Source.API
Credentials = new APICredentials(practiceConfig);
BaseConnection = new APIConnection(universalConfig.Get("PWBaseURI"), Credentials);
UpdateConnection = new APIConnection(universalConfig.Get("PWUpdateURI"), Credentials);
AttachementConnection = new APIConnection(universalConfig.Get("PWAttachmentURI"), Credentials);
ReferralConnection = new APIConnection(universalConfig.Get("PWReferralURI"), Credentials);
ReferToConnection = new APIConnection(universalConfig.Get("PWReferToURI"), Credentials);
ReferFromConnection = new APIConnection(universalConfig.Get("PWReferFromURI"), Credentials);
ReferTypesConnection = new APIConnection(universalConfig.Get("PWReferTypesURI"), Credentials);
AppVersion = universalConfig.Get("PWAppVersion");
@ -46,5 +57,25 @@ namespace PWAPPv2.Source.API
return false;
}
public string GetReferalTypes()
{
return ReferTypesConnection.SendPostWithCredsInHeader("", "");
}
public string GetReferTo()
{
return ReferToConnection.SendPostWithCredsInHeader("", "");
}
public string GetReferFrom()
{
return ReferFromConnection.SendPostWithCredsInHeader("", "");
}
public string SendReferral(string JsonData)
{
return ReferralConnection.SendPostWithCredsInHeader("", JsonData);
}
}
}

9
PWAppUpdater/App.xaml Normal file
View File

@ -0,0 +1,9 @@
<Application x:Class="PWAppUpdater.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PWAppUpdater"
StartupUri="MainWindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>

17
PWAppUpdater/App.xaml.cs Normal file
View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace PWAppUpdater
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

View File

@ -0,0 +1,45 @@
using System;
using System.IO;
using System.Net;
namespace PWAppUpdater.FTP
{
class FTPManager
{
private string BaseUri;
private NetworkCredential credential;
public FTPManager(string baseUri, string username, string password)
{
BaseUri = baseUri;
credential = new NetworkCredential(username, password);
}
public void DownloadFile(string FTPPath, string localPath)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(BaseUri + FTPPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = credential;
request.KeepAlive = false;
request.UseBinary = true;
request.UsePassive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
using (Stream s = File.Create(localPath))
{
responseStream.CopyTo(s);
}
response.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
}
}

View File

@ -0,0 +1,16 @@
<Window x:Class="PWAppUpdater.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PWAppUpdater"
mc:Ignorable="d"
Title="PWUpdater" Height="137" Width="266">
<Grid Margin="0,0,0,-4">
<ProgressBar x:Name="barProgressBar" Minimum="0" Maximum="100" HorizontalAlignment="Center" Height="10" VerticalAlignment="Top" Width="246" Margin="0,46,0,0"/>
<Label x:Name="statusText" Content="Please wait while the application is updating." HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label x:Name="txtUpdateStep" Content="{Binding Path=txtUpdateStep}" HorizontalAlignment="Left" Margin="10,31,0,0" VerticalAlignment="Top"/>
<Button x:Name="OKButton" Content="OK" HorizontalAlignment="Center" Margin="0,70,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</Grid>
</Window>

View File

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading;
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;
namespace PWAppUpdater
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
statusText.Content = "The program will now be updated.\nPlease click \"OK\" to continue.";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
OKButton.IsEnabled = false;
for(int i = 0; i < 100; i++)
{
barProgressBar.Value = i;
barProgressBar.UpdateLayout();
Thread.Sleep(100);
}
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
</PropertyGroup>
<ItemGroup>
<Folder Include="Config\" />
</ItemGroup>
</Project>

52
PWAppUpdater/Updater.cs Normal file
View File

@ -0,0 +1,52 @@
using PWAppUpdater.FTP;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace PWAppUpdater
{
class Updater
{
public static void Update(string installPath, string practiceConfigLocation = "", string tempPath = "")
{
try
{
if (tempPath == "")
{
tempPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
tempPath = Path.Combine(tempPath, "PWAPP\\Temp");
}
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
FTP.FTPManager ftpManager = new FTPManager("ftp://waws-prod-blu-109.ftp.azurewebsites.windows.net/", "patientweb\\$patientweb", "vHBnkgxPDS4Q410eehaFlXb8DH67QW50m9Rsxf1omXyYWRDgYioWJL63Tagp");
ftpManager.DownloadFile("pwapp/current/Release.zip", tempPath);
if (Directory.Exists(installPath))
{
Directory.Delete(installPath, true);
}
Directory.CreateDirectory(installPath);
Zip.ZipManager.UnZip(tempPath, installPath, true);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Updater does not have sufficent permissions to perform update. Please run with administrator privilages to continue.");
}
}
}
class CouldNotFindInstallPathException : Exception
{
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PWAppUpdater.Zip
{
class ZipManager
{
public static void UnZip(string source, string destination, bool Override)
{
if (Override)
{
if (Directory.Exists(destination))
{
Directory.Delete(destination, true);
}
}
ZipFile.ExtractToDirectory(source, destination);
}
}
}

View File

@ -0,0 +1,9 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="highestAvailable" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@ -0,0 +1,45 @@
using System;
using System.IO;
using System.Net;
namespace PWAppUpdater.FTP
{
class FTPManager
{
private string BaseUri;
private NetworkCredential credential;
public FTPManager(string baseUri, string username, string password)
{
BaseUri = baseUri;
credential = new NetworkCredential(username, password);
}
public void DownloadFile(string FTPPath, string localPath)
{
try
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(BaseUri + FTPPath);
request.Method = WebRequestMethods.Ftp.DownloadFile;
request.Credentials = credential;
request.KeepAlive = false;
request.UseBinary = true;
request.UsePassive = true;
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Stream responseStream = response.GetResponseStream();
using (Stream s = File.Create(localPath))
{
responseStream.CopyTo(s);
}
response.Close();
}
catch (Exception e)
{
Console.WriteLine(e.Message.ToString());
}
}
}
}

98
PWAppUpdater2/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,98 @@
namespace PWAppUpdater2
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
progressBar1 = new ProgressBar();
button1 = new Button();
label1 = new Label();
StepInfo = new Label();
SuspendLayout();
//
// progressBar1
//
progressBar1.Location = new Point(30, 60);
progressBar1.Name = "progressBar1";
progressBar1.Size = new Size(200, 10);
progressBar1.TabIndex = 0;
progressBar1.Click += progressBar1_Click;
//
// button1
//
button1.Location = new Point(105, 80);
button1.Name = "button1";
button1.Size = new Size(50, 23);
button1.TabIndex = 1;
button1.Text = "OK";
button1.UseVisualStyleBackColor = true;
button1.Click += button1_Click;
//
// label1
//
label1.AutoSize = true;
label1.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
label1.Location = new Point(12, 9);
label1.Name = "label1";
label1.Size = new Size(168, 30);
label1.TabIndex = 2;
label1.Text = "The program will now update. \r\nPlease click \"OK\" to continue.";
label1.Click += label1_Click;
//
// StepInfo
//
StepInfo.AutoSize = true;
StepInfo.Location = new Point(30, 42);
StepInfo.Name = "StepInfo";
StepInfo.Size = new Size(0, 15);
StepInfo.TabIndex = 3;
StepInfo.Click += label2_Click;
//
// Form1
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(264, 111);
Controls.Add(StepInfo);
Controls.Add(label1);
Controls.Add(button1);
Controls.Add(progressBar1);
Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point);
Name = "Form1";
Text = "Form1";
ResumeLayout(false);
PerformLayout();
}
#endregion
private ProgressBar progressBar1;
private Button button1;
private Label label1;
private Label StepInfo;
}
}

51
PWAppUpdater2/Form1.cs Normal file
View File

@ -0,0 +1,51 @@
using PWAppUpdater;
namespace PWAppUpdater2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void progressBar1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "Updating.... Please wait.";
label1.Update();
progressBar1.Maximum = 8;
progressBar1.Step = 1;
button1.Enabled = false;
try
{
PWAppUpdater.Updater.Update("C:\\PWAPP\\App\\", progressBar1, StepInfo, "C:\\PWAPP\\Temp\\");
}
catch (NoAuthException)
{
MessageBox.Show("Please run the updater with administrator privilages or from the PWApp Application.");
Application.Exit();
}
MessageBox.Show("Done!");
Application.Exit();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void label2_Click(object sender, EventArgs e)
{
}
}
}

120
PWAppUpdater2/Form1.resx Normal file
View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

17
PWAppUpdater2/Program.cs Normal file
View File

@ -0,0 +1,17 @@
namespace PWAppUpdater2
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new Form1());
}
}
}

77
PWAppUpdater2/Updater.cs Normal file
View File

@ -0,0 +1,77 @@
using PWAppUpdater.FTP;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace PWAppUpdater
{
class Updater
{
public static void Update(string installPath, ProgressBar progress, Label stepInfo, string tempPath = "")
{
try
{
progress.PerformStep();
stepInfo.Text = "Creating temp directories...";
stepInfo.Update();
if (tempPath == "")
{
tempPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
tempPath = Path.Combine(tempPath, "PWAPP\\Temp");
}
progress.PerformStep();
if (!Directory.Exists(tempPath))
{
Directory.CreateDirectory(tempPath);
}
progress.PerformStep();
stepInfo.Text = "Downloading update...";
stepInfo.Update();
FTP.FTPManager ftpManager = new FTPManager("ftp://waws-prod-blu-109.ftp.azurewebsites.windows.net/", "patientweb\\$patientweb", "vHBnkgxPDS4Q410eehaFlXb8DH67QW50m9Rsxf1omXyYWRDgYioWJL63Tagp");
ftpManager.DownloadFile("pwapp/current/Release.zip", tempPath + "\\Release.zip");
progress.PerformStep();
stepInfo.Text = "Removing old installation...";
stepInfo.Update();
if (Directory.Exists(installPath))
{
Directory.Delete(installPath, true);
}
progress.PerformStep();
stepInfo.Text = "Creating new install directory...";
stepInfo.Update();
Directory.CreateDirectory(installPath);
progress.PerformStep();
stepInfo.Text = "Unpacking update...";
stepInfo.Update();
Zip.ZipManager.UnZip(tempPath + "\\Release.zip", installPath, true);
progress.PerformStep();
stepInfo.Text = "Cleaning up installation...";
stepInfo.Update();
Directory.Delete(tempPath, true);
progress.PerformStep();
stepInfo.Text = "Complete!";
stepInfo.Update();
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Updater does not have sufficent permissions to perform update. Please run with administrator privilages to continue.");
throw new NoAuthException();
}
}
}
class NoAuthException : Exception { }
class CouldNotFindInstallPathException : Exception
{
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PWAppUpdater.Zip
{
class ZipManager
{
public static void UnZip(string source, string destination, bool Override)
{
if (Override)
{
if (Directory.Exists(destination))
{
Directory.Delete(destination, true);
}
}
ZipFile.ExtractToDirectory(source, destination);
}
}
}

View File

@ -57,12 +57,6 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PWAPPv2\PWAPPv2.csproj">
<Project>{45e26af8-41d7-4308-a2c8-d55a0350db47}</Project>
<Name>PWAPPv2</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">