✅ Need Help Finishing Up Installer C# Avalonia V11.0.2
https://pastebin.com/gNG6t3Fd
This is my current code with all the fluff text to be an example of what I want my installer to do while the loading screen is going, however, I need help with getting the rest of the stuff to happen and making this loading screen become real and put the work in behind it
1. Connecting to the repo
2. Getting the file size of the zip folder
3. Downloading the zip folder into memory
4. Getting the location of the project on the users system without needing user input
5. Extracting the files from the zip folder and over writing the existing files to update the program
6. Correctly and accurately updating the progress bar as each thing happens.
54 Replies
my code is commented and I have each step noted as to what I believe should happen at that current step value. I just don't know how to bring it all together and make it all work like it's supposed to. Thanks in advance
1. Connecting to the repowhat repo? why would your program be connecting to a code repo?
did you look at the link containing my code?
nope
everything is commented within my code that follows the bullet points
yes, you mentioned
mhm
the link containing my code has been throughouly commented. If anyone can help, that would be great, but I'm not going to re-explain what I've already explained throughout my code to follow the bullet points. Thanks again in advance
Are you trying to access the assets part of the api endpoint?
Since there's multiple assets on the repo release. So the json path would be $.assets[0].browser_download_url for the
Todo_Linux_x64.zip
idk if this is best practise but you could download it as a JsonObject, access the ["assets"] and deserialize that as a ReleaseData[] like this
Then you should be left with a bunch of ReleaseData objects, each containing a link to their respective versions; eg.
Additionally, I believe the method Directory.GetCurrentDirectory() uses the working directory instead of the application's location.
You could also check if the application is running when the installer is also running, maybe ask or quit the todo appAre you trying to access the assets part of the api endpoint?correct. I need to have a function that can determine what operating system the user has so that the installer can pull the correct update.
Since there's multiple assets on teh repo release. So the json path would be $.assets[0].browser_download_url for the Todo_Linux_x64.zip
I'm not exactly sure on how to use this since my url is private readonly string _url = "https://api.github.com/repos/mekasu0124/Todo/releases/latest";
idk if this is best practise but you could download it as a JsonObject, access the ["assets"] and deseralize that as a ReleaseData[] like this <code snippet>where you use
<JsonObject>
can I make that a class like I did my ReleaseData? If so, how?
Then you should be left with a bunch of ReleaseData objects, each containing a link to their respective versions; eg. <snippet>This will help a lot with determining the users operating system. How can I go about determining what OS the user has?
Yes, you can use a class instead of
JsonObject
. It's even preferable
Look at how the API response looks, and create a class that describes it
With the properties you want to get
Alternatively, you can use something like quicktype.io to just generate classes from JSON, and either remove what you don't need, or leave it as-isok bet ty
Seems everything's been addressed except the last part.
You can use RuntimeInformation to determine the OS
You could possibly do something like this for the deserialization of what you need:
then compare file names to OSPlatform i guess
Oddly enough, there doesn't seem to be a way to just get the
OSPlatform
I guess for the people implementing their own operating system and feeling left out
and wanting to run C# on it
You can get the OS description string and the platform architecture, so I guess that's something
ok so here's what I have so far
MainWindowViewModel.cs
https://pastebin.com/NjYLDAsQ
And then I have /Models/ReleaseData.cs
it doesn't like this part
You just use it like
ok doing that lead to this
you dont need to deserialize it again, its already deserialized in _client.GetFromJsonAsync for you
oh ok. my fault. thank you
so to iterate over the releases you can now do
or alternatively
is it better to iterate over the releases? or to use an if/else statement and just index the releases by name and pull the correct name of the correct zip folder?
ok so I'm making an adjustment and I want your opinion
You could do
then in the GetDownloadUrl method you can do something like this
Though I am generally against returning nulls and string.empty kinda qualifies as that here
you could try that, just remember to change your ReleaseData class to include the downloadname
and to make the method return a Task<VersionData> record
just uh
string downUrl = data.Assets[release][data.DownloadUrl]; double downSize = data.Assets[release][data.DownloadSize];remember its not a JsonObject, its a C# class now
ok so I took all of that into consideration and made edits to match (because you're smarter than me on this stuff lol) and it's saying
GetDownloadUrl()
all code paths don't return a value?What is returned if there's no exception, and
osReleaseData
is not null
?osReleaseData.DownloadUrl
and if I changed
async Task<string> GetDownloadUrl()
to async Task<VersionData> GetDownloadUrl()
would I go do
I would suppose nothing is being returned if all conditions are true. I noticed that, and that's why I asked is that where I would have the else statement return the new VersionData and change the decorator from Task<string> to Task<VersionData>?If that's what you want to return, then sure
I feel like I have that wrong
should it be
?
well I'm returning it as a record so that in the function that actually handles the zip folder can work with the data more easily. Once I've gotten getting the correct download url based off the user's os working correctly, I'll be starting the function that will handle downloading the zip folder to the current working directory, extracting the zip folder and over writing the existing files, then deleting the zip folder from the current working directory, and then showing the button and message telling the user that the update has finished and click ok to relaunch the todo app
ok bet. Thank you for that ❤️ I was a little bit off 😛 are there any examples I can view for the remaining things that need to be done?
1. Download, Extract, Over write the existing files in the current working directory (update the application)
2. Have the application remove any files that aren't needed to run the application (Ex: delete the zip folder, )
3. Have the progress bar correctly and accurately update as this entire process goes along
- have progress bar incrementation start off by obtaining the amount of time it will take to download the zip folder, working through the process of updating the application, and removing the no longer needed files
1. How do I download the zip folder to the current working directory so that it stays contained within the projects folder?
2. How do I get the
GetDownloadUrl()
function to call the DownloadAndExtract()
function once the information has been obtained since it returns things?
would it be like that?
The BeginUpdate
function is like the brain since it's was is triggered by the button click1. Not with
WebClient
that's for sure. HttpClient
has a way to get the byte array or a stream of the file, and then you can save it wherever.
2. Not quite. GetDowloadUrl()
needs to be awaited, after all
It'd be more like
tyvm
so how would I do it with HttpClient?
because the function DownloadAndExtract() needs to download the zip folder to the current working directory, extract the contents of that folder, and over write the existing files (or delete and replace) so that the todo application can actually update
url
being the, well, URL
path
beinf where you want to save itok so with those two lines, it's now downloaded the zip folder. What's the documentation on extracting the contents?
https://stackoverflow.com/questions/836736/unzip-files-programmatically-in-net#:~:text=134-,For%20.Net%204.5%2B,-It%20is%20not
I found this, but I'm not entirely sure on how to use it
Stack Overflow
Unzip files programmatically in .net
I am trying to programatically unzip a zipped file.
I have tried using the System.IO.Compression.GZipStream class in .NET, but when my app runs (actually a unit test) I get this exception:
Sys...
Here's the full documentation: https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-compress-and-extract-files
ZipFile.ExtractToDirectory(zipPath, extractPath);
is all you need, it seemswhat do you think?
At a glance, LGTM
Does it work?
I don't know. I'm still lacking the progress bar usage throughout my process. This is my full code for the process https://pastebin.com/mP5zfHFq I have no idea where or how to update the progress bar whatsoever
Pastebin
#region importsusing Installer.Models;using ReactiveUI;using System...
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
looking at this, you might want to include a few try catch finallys
just incase you get some Unauthorized exceptions being thrown, then you wouldn't be able to delete the temp path contents
are you talking about in this function?
Yes, anything that touches a file can fail
Reading, Writing and Deleteing
oh ok. This is my first time dealing with files in C#
apologies on not being sure of what to do
There's multiple things that can fail here, but what you most notably would want is after
string tempPath
wrap it in a try finally until the end of the foreach loop then include the Directory.Delete logic within the finally blockhow's this?
Should work from the looks of things, im not on pc rn
Basically if something errors in that method, files may be left behind that are meant to be temporary. To prevent that we use a finally block as cleanup
oh ok. That makes sense
thank you 🙂
now the only thing I think I have left to do is figure out where to use my
IncrementProgress
function so that my progress bar runs parallel with the work the program is doing from start to finish
https://pastebin.com/40uKfhQM this is the updated code for anyone who might be able to help with that. I also have to figure out how to launch the files that correspond to linux and mac operating systems as well since they don't use the .exe
fileSince essentially everything you're using is a stream (from thr get request, to the file saving etc) which means you should be able to implement a progress bar as the file downloads + as you extract it + as you move the contents etc
Try searching for something like httpclient progress bar or async stream progress bar
https://stackoverflow.com/questions/20661652/progress-bar-with-httpclient
https://stackoverflow.com/questions/67368542/reading-large-txt-file-async-and-reporting-progress-in-progressbar-wpf-c-sharp
I looked at both of these, and I'm still lost. I do apologize
don't worry about it. I'll figure it out on my own somehow