How to remove previous versions of an offline clickonce application - winforms

We have an net 4.0 winforms application that we publish with clickonce to the client pc's. The installation is about 80 MB. The application is offline available and the update occurs in the startup of the app using
ApplicationDeployment.CurrentDeployment.Update
Each time we do an update of the application everything works fine and each client gets udpated. However the application cache keeps growing in size... We noticed that more then two versions are kept in the LocalAppData folder. The size of the clickonce installation folder is more then 1GB.
ClearOnlineAppCache works only for online applications and we don't find any information to clean the LocalAppData for offline application.
Is there any way to manage previous versions of our application in the LocalAppData folder from our client pc's?
Update:
We removed our custom update code and used the update mechanism of the Clickonce framework. Now old versions are removed properly and only two versions are kept in LocalAppData. I have still no idea why all versions are kept when we update through the custom update code.

I've seen this issue before, but I clarified with the ClickOnce lead at Microsoft before answering.
It keeps two versions of the deployment plus there are extra folders for each assembly. When processing an update, ClickOnce figures out which files have changed by comparing against the assembly it has already cached, and it only downloads the ones that have changed. The deployment folders have hard links to the assemblies in the separate folders. So you might see additional files, but it's not actually the file, it's a link to the files in the assembly-only folders. Explorer will show it as a file, but it's not. So unless you're running out of disk space and are just concerned about the folder size, be aware that the information reported by Windows Explorer may not be accurate.

There is an answer to this problem here
I wrote a function to clean old ClickOnce versions in the client side.
In my machine I've freed 6Gb of space. I don't want to even know the total space used by old versions org wide...

Related

Appengine runs a stale version of the code -- and stack traces don't match source code

I have a python27 appengine application. My application generates a 500 error early in the code initialization, and I can inspect the stack trace in the StackDriver debugger in the GCP console.
I've since patched the code, and I've re-deployed under the same service name and version name (i.e. gcloud app deploy --version=SAME). Unfortunately, the old error still comes up, and line numbers in the stack traces reflect the files in the buggy deployment. If I use the code viewer to debug the error, I am however brought to the updated patched code in the online viewer -- and there is a mismatch. It behave as if the app instance is holding on to a previous snapshot of the code.
I'm fuzzy on the freshness and eventual consistency guarantees of GAE. Do I have to wait to get everything to serve the latest deployed version? Can I force it to use the newer code right away?
Things I've tried:
I initially assumed the problem had to do with versioning, i.e. maybe requests being load-balanced between instances with the same version, but each with slightly different code. I'm a bit fuzzy on the actual rules that govern which GAE instance gets chosen for a new request (esp whether GAE tries to reuse previous instances based on a source IP). I'm also fuzzy on whether or not active instances get destroyed right away when different code is redeployed under the same version name.
To take that possibility out of the equation, I tried pushing to a new version name, and then deleting all previous versions (using gcloud app versions list to get the list). But it doesn't help -- I still get stack traces from the old code, despite the source being up to date in the GCP console debugger. Waiting a couple hours doesn't do anything either.
I've tried two things:
disabling and re-enabling the application in GAE->Settings
I'd also noticed that there were some .pyc files uploaded in the snapshot, so I removed those and re-deployed.
I discovered that (1) is a very effective way to stop all running appengine instances. When you deploy a new version of a project, a traffic split is created (i.e. 0% for the old version and 100% for the new), but in my experience old instances might still be running if they've been used recently (despite them being configured to receive 0% of traffic). Toggling kills them all immediately. I unfortunately found that my stale code was still being used after re-enabling.
(2) did the trick. It wasn't obvious that .pyc were being uploaded. I discovered it by looking at GCP->StackDriver->Debug and I saw .pyc files in the tree snapshot.
I had recently updated my .gitignore to ignore locally installed pip runtime dependencies for the project (output of pip install -t lib requirements.txt). I don't want those in git, but they do need to ship as part of my appengine project. I had removed the #!.gitignore special include line from .gcloudignore. However, I forgot to re-add *.pyc into my .gcloudignore.
Another way to see the complete set of files included in an app deployment is to increase the verbosity to info on the gcloud app deploy command -- you see a giant json manifest with checksums. I don't typically leave that on because it's hard to visually inspect, but I would have spotted the .pyc in there.

Archive artifact in Nexus

Our internal Nexus repository has an artifact that we wish we never published, but unfortunately we did. And various environments installed it.
I'd like to delete it from the repository so that nobody downloads the erroneous release again, but for the people who already downloaded & installed that artifact, it seems a bit deceptive to pretend the release never happened. Is there a way to "archive" or "disable" an artifact so that it still is preserved somewhere for analysis or archeological purposes, but won't be installed by someone pulling artifacts for installation?
There isn't a feature in NXRM for disabling access to individual artifacts. This is a bit hacky but you could achieve it by
Creating a new hosted repository (either raw format or the same
format that you are currently using)
Marking that repository as "offline"
Moving the artifact to the archived repository.
Step 3 is the problematic part: If you are an NXRM PRO user on a recent version there are REST calls you can use for moving components. See here for more details https://help.sonatype.com/repomanager3/staging#Staging-RESTEndpoints
If you are an OSS user you will likely have to republish the same artifact to the archive repository and then delete it from the original repository.
(Note the above assumes you are using NXRM3 - if you are using NXRM2 take a look at https://blog.sonatype.com/2010/04/nexus-tip-moving-artifacts-between-nexus-repositories/)

All files in IsolatedStorageFile store disappear after rebuilding WP8 Silverlight solution

I'm developing a WP8 Silverlight app which uses the IsolatedStorageFile store for app's data. At some point I detected that if I issue the Rebuild Solution command in VS.NET, VS uses full deployment of my project to the emulator or an attached device instead of incremental deployment. The typical Build output in this case looks like this:
2> Connecting to Emulator 8.1 WXGA 4.5 inch...
2> The application is already installed on the device. Checking if an incremental deployment
is possible...
2> Doing full deployment as project was cleaned and rebuilt...
2> Uninstalling the application...
2> Installing the application...
Sure, all app's settings and data stored in IsolatedStorageFile disappear at that.
As a developer, I may need to rebuild my solution from time to time, or unpack it from the archive backup I do. But this means that my end users will lose all their data too when I publish a new version of my app in the Marketplace after rebuilding the project!
My question is how to save all the data on the device after deploying a rebuilt WP8 Silverlight project to it? Is there a file, or a setting in one of the files produced while compilation responsible for that (maybe, a GUID, or time stamp)? Which can be saved and added to the new rebuilt stuff to prevent data loss with the next app deployment?
IsolatedStorage data are deleted whenever the app is uninstalled, which is exactly what VS does when you rebuild the project. This will not be the case when end users will update your app. The app will be updated rather than uninstalled. So that will preserve your data from IsolatedStorage.
An alternative solution to this problem is the IsoStorSpy utility suggested by the user lisp in this thread.
Using this utility, we can store all app files in the corresponding IsolatedStorage data area to the pc HDD, and then easily upload them back after deploying the rebuilt app.

Click once WPF application (available offline) – Mounting previous versions in the “Application Files” folder – Team City

We are currently building a WPF application which is to be deployed via Click Once, the build is currently being handled by a Team City server.
We are noticing that every time someone checks in some code and the CI server builds the deployment package, the “Application Files” directory contains an additional version of the application.
Due to the mounting size of Click Once deployment, this is becoming un-scalable, does anyone have any idea how to limit the number of previous versions that are placed inside the Application Files directory?
The application files directory:
Click Once does not provide any mechanism for handling the published deployments. It would be difficult for Microsoft to do that, because everybody's requirements would be different. I'm sure that's why Team City didn't add that ability either (assuming they didn't, I don't use Team City).

Auto update for WinForms application

When creating an auto updating feature for a .NET WinForms application, how does it update the DLLs and not affect the currently running application?
Since the application is running during the update process, won't there be a lock on the DLLs (because those DLLs will have to be overwritten during the update).
Usually you would download the new files into a separate area. Then shutdown and restart and at startup you look for and use the new files if found. Always keeping a last known working version on the side so that the user can revert to something that definitely works if the download causes problems.
ClickOnce is a good technology from Microsoft that does this for you and you can use it directly from Visual Studio 2008.
You'll have to shutdown your application and restart it, as other people have already commented.
I wrote an open-source code to do just that in a transparent mode - including an external update application to do the actual cold update. See http://www.code972.com/blog/2010/08/nappupdate-application-auto-update-framework-for-dotnet/
The code is at http://github.com/synhershko/NAppUpdate (Licensed under the Apache 2.0 license)
I have a seperate 'launcher' application that checks for updates via a web service. If there are updates, it downloads them and then executes my application, which is in a seperate assembly.
The other alternatives are using things like ClickOnce, or downloading the files to a seperate area and restarting the app, as someone else mentioned.
Be warned about ClickOnce, though - it's not as flexible as it sounds. And if you deploy to a system that requires elevating your program to a higer security level to run, you might run into problems if you don't have a certificate for your app installed. I found it very difficult to get straight answers on the Internet to things like certificate management when it comes to ClickOnce. If you have a complex app, you may want to just roll your own updater, which is what I ended up having to do.
If you publish via ClickOnce, all of that tends to be handled for you. It has it's own pro's and con's but usually easier than trying to code it all yourself.
Both Wikipedia and 15seconds have decent info on using ClickOnce, how it works, etc.
As others have stated, ClickOnce isn't as flexible as rolling your own solution but it is a LOT less complicated. It has a small learning curve at first, but with pretty much everything bundled into Visual Studio and the use of Wizards, it usually doesn't take long to stumble onto a working solution.
As deployments get more complex (i.e. beyond than just having prerequisites or application code that needs updating) and you need to do a lot of post-install or pre-install tasks, there are things like WiX which give you somewhat of a hybrid solution between Windows Installer and ClickOnce, with the cost of flexibility being a much steeper learning curve.
The only reason I try to avoid custom installers is that you end up spending way too much time trying to get it just right to handle a bunch of different "What If" scenarios...
These days Windows can do such updates automatically for you with AppInstaller if your app is packaged in the MSIX package.
It downloads the new version of the app in another folder inside ProgramFiles\WindowsApps, then when a user runs the app via the start menu, the system knows what folder it should use. The previous version gets deleted when not in use.
If you want to know how to package your app this way I collected my findings in this answer.

Resources