Downloading and extracting a .7z file from within a WinUI application
I'm currently developing an application installer using WinUI3, and I'm stuck at the part where the installer actually downloads the .7z file for the application and extracts it. This is the first time I've dealt with something like this.
Further context:
I'm trying to download the 7z file to a path determined by an input on the page previous, and I have passed through the variable on my Frame.Navigate() so I can access it.
124 Replies
Give some more info? I can't see the code that's actually doing the unpacking, and the image is not informative
Yeah hold on, you'll have to forgive my nightmare mess of code to try and do this
This is what it tries to do in the background, but nothing ever downloads / happens
ummm, post the code (use a pastebin)? Please don't use screenshots, they make it much harder to help you
oh my bad
Pastebin
DownloadingPage.xaml.cs - Pastebin.com
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.
Ok, so i would consider this a strange approach.
A: You will need to install a copy of 7zip with your program, might not be the best option for the user, especially if they already have 7zip installed.
B: Why use processes and raw binaries in the first place? There are nuget libraries that provide much better level of responsiveness than
Process
, so you can actually see what and where went wrong.
Also shouldn't it be
When passing arguments?Is there any other method of extratcting a 7z without having to include a copy? I can change to a normal .zip file instead if that means it doesn't need any extras to be downloaded.
Also, is the code for actually downloading correct? I don't see anything being downloaded
7zr.exe syntax is just the letter e without any hyphens
Well, that's very important, i assumed you've checked for the existence of the file...
The file downloads when I pass a pre-written directory, but not any of my variable ones
I don't think that's the issue, but use async/await with http
not:
HttpResponseMessage response = client.GetAsync(fileUrl).Result;
better:
HttpResponseMessage response = await client.GetAsync(fileUrl);
Also, i would recommend using RestSharp, for the sake of convenienceI'll take a look at RestSharp, but the await thing won't work since it's not in an async method
Make it async method? I'm pretty sure there is an async override option
This might go down as one of the most obvious things I've ever missed in my life lmao
So, did you find an async method? Did it fix the problem?
It didn't fix the file not appearing, but it did fix another issue I was having where the app would lock up while executing the code in that method
But I'm changing to RestSharp to see if it works
For some reason, VS tells me that GET does not exist in Method
But that is the right syntax according to the documentation
Here, made RestSharp code working for you (using insomnia):
Documentation is a bit outdated...
thank you so much! I must have been reading some out of date documentation because it all looks different
That explains it then, slightly thought I was going crazy :)
It's pretty easy to figure out on your own, using just intellisense, but here are the up-to-date docs: https://restsharp.dev/v107/
RestSharp Next (v107+) | RestSharp
Simple .NET client for HTTP REST APIs
Intellisense is handy I have to say. Another thng though, this doesn't seem to be downloading anything either, is there a way for me to see the progress of the download?
Put a breakpoint after you await the request, inspect the values
this won't show you the progress in real time, but will alert you when the file is downloaded
So I should add "Debugger.Break();" below that line, and set my debugger onto the Breakpoint screen? This is the first time I've had to use one
I ran the code and now it's highlighted yellow
What ide are you using?
Visual Studio
Breakpoints look like this:
red dot - the line the execution will stop at
You can inspect the values of variables in the "locals" tab
Could this maybe have something to do with it?
Yep, that's an exception
I don't know how the direcotry isn't found
Can you show me the code once again (i think it has changed significantly since the last time) and the values of any variables you're supplying?
hold on it's doing something
I had to do File.Create before writing to the file
another obvious thing
that I ovelrooked
however it's still 0b
No? It depends, but the method
File.WriteAllBytes
creates the file automaticallyPastebin
Download.xaml.cs - Pastebin.com
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.
That's weird then
The directory on File.WriteAllBytes is real
and it's the only other time a directory is mentioned in the file
and I have manually set it to my downloads folder
lol what
As far as i remember file paths use
/
not \
Oh? All my other paths have used \ but those were in XAML actually
Still getting an IO exception
Can you send the stack trace?
My call stack is empty
Well, that's strange
am I looking in the wrong place
probably am
debug tab:
This is how it looks for me (very old project)
Maybe my debugger settings aren’t right
I got something! But I have no clue what has opened this file
Honestly it might be the File.Create()
Well, just delete the file (manually) for now
I suspect it's Process.Start you're doing to unzip it
Are you sure your logic waits for the file to get downloaded before processing it?
I removed that part of the code until I could get the downloaading functional
File.Create removed fixed it
my own fix is what broke it in the end lol
ok, great
do I need to close the connection or anything afterwards?
a few exceptions are thrown after it's idle for a few minuites
client.Dispose() fixed it 🎉
now I've seen online that something called 7zSharp exists so it might be handy to use
so hopefully I can take it from here 🤞
Returning to the path not found issue, this works for me:
File.WriteAllBytes(Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads/", "test.7z")), Encoding.UTF8.GetBytes(response.Content));
In general you would want to use Path
class for safe path handling
Good luck to you, hope you can get it working!Thanks! :)
Oops back again, if I want the installer to be able to write to program files, I need to run it as adminstrator, but this then breaks the FolderPicker on the previous page meaning it can't install anywhere
@Stefanidze I don't like pinging because people have lives outside of helping people on Discord, but you've been so helpful and clearly know what you're talking about so hopefully this is a quick fix
Hi, i'm ok with pinging
I will need to see the code, i'm not familiar with any universal "Folder Picker" pattern
The FolderPicker is a part of WinUI
Well, nothing i can do
GitHub
Trying to use a FileOpenPicker while running the app as Administrat...
Describe the bug I am trying to open a File Picker but it works only if I am not using the app in elevation mode. I'm getting the following error: System.Runtime.InteropServices.COMException: &...
this is a winui bug, try finding solution in the issue?
common microsoft L
yep
Also, if you want to dig into this, try creating an issue for FolderPicker on winui github, i don't think it exists
none of the fixes even work wtf is this
I've got 2 options then:
- Don't allow install to program files
- Only install to program files
Well, how about writing two apps, one the installer, and other one is the picker, and pass the location via command line arguments?
I'm trying to think of a lossless workaround...
so am I
it would be nice to just launch the file picker as unelevated while the rest of the program is
I dont use WinUI so I promise nothing, what is the issue with picking a file?
The FilePicker/FolderPicker function doesn’t work when the app is opened as admin
and neither do any of the alternatives for some reason
why do u need admin?
To write to program files
why do u need to write to a folder that is not normally written to?
For an installer
I might be missing some more context here
because a installer will normally go to a temp folder
and install to a location, sure it could be program files
It needs to copy the files to the users selected folder, which could end up being a protected folder such as program files
unless I use an elevated command line etc to move the files AFTER extraction to the temp folder
ok but why can't you have your users pick a non protected folder to install so they dont need to rely on protected locations
because some people like using program files, i don’t want to just make some folders off limits
because of an arbitrary limitation that microsoft can’t be bothered fixing
AFAIK filepicker have something to get permissions to write to other folder then the regular ones have u tried that?
FilePicker doesn’t have that because filepicker can pick the protected folders, the problem comes in the next step when the application tries to write to it and can’t as it doesn’t have privileges
Well, using some workaround maintained by someone other than microsoft may be an option...
https://learn.microsoft.com/en-us/windows/uwp/files/file-access-permissions#example
its the same as uwp
as far as I remember
so let me try to understand u have a winui3 app on programs file already and u want to have it move files to its install dir?
or u are writing an installer and want it to install things to a folder of the user choice
This is not the problem, the problem is that built-in FolderPicker class doesn't work (in an unspecified way) when application has elevated permissions
that's great, I already understood that and I want to see if the uwp solution would work for it, thus im trying to understand what he is doing
Writing an installer (will be built unpacked obviously) and I want it to do this
k, I will give it a go here and see if it works.
thats only if its packaged
I see, so unlike uwp it have a unpackaged version?
@Noah this solution works https://github.com/PavlikBender/Pickers unhappily beyond selecting the folder u will have other issues moving the files(so my suggestion is, try to create the folder first if it fails just tell the user to choose a different folder)
its the simplest to implement since all u need is to reference the project or library if u build it
yeah
you can use the uwp file pickers but you dont need to request any permissions if its unpackaged
you dont need a lib
yeah very interesting I just made a simple app to try it out a bit confusing the templates naming but found the unpackaged one
yeah last i checked they still didnt have an unpackaged template
you just need to change the csproj yourself
the thing is, it doesn't open the folderpicker with winui3 default api, so the library is the workaround
wdym?
what are u referring to here
to use the pickers from Windows.Storage.Pickers
then yes, u do need that library
why?
the reason is because for whatever finik reason winui3 under admin right does not open the folder picker
i didnt use any lib when i used them
it works perfectly fine without admin rights
huh
which is the issue the OP is having
i thought they fixed that a while ago
what version of winui are they using?
apparently not, I tried it myself, and under the thread about that issue that was one of the solutions
you initialized it with the main window handle?
this is what the template gave me as default net7.0-windows10.0.19041.0
var handle = WindowNative.GetWindowHandle(App.MainWindow);
does op use packaged or unpackaged?
I believe unpackaged as he said above in some messages
did they send the csproj?
wait is there a github issue?
no, but I tried it myself just now
yes there is
ah can you link it?
thanks
as you can see still open, so this https://github.com/PavlikBender/Pickers library was the simplest way to go around the issue
but its not the only issue the OP will have since he also wants to move files into a protected folder
its 2 years old oof
welcome to WinUi3 😛
glad im a wpf fanboy
MAUI is also full of holes u have to patch things
yeah im not interested in touching maui
wish I had that privilege.
anyway to not burry the thread
leowest
<@295671854104969216> this solution works https://github.com/PavlikBender/Pickers unhappily beyond selecting the folder u will have other issues moving the files(so my suggestion is, try to create the folder first if it fails just tell the user to choose a different folder)
Quoted by
<@1102729783969861782> from #Downloading and extracting a .7z file from within a WinUI application (click here)
React with ❌ to remove this embed.
because u can test for the authorization failure.