I'm trying to create an updater for my app in VB.NET, No, I do not want to use clickonce, it sucks because I have to deal with managing self signed certs etc.
I know the code to check for new update files:
http://pastebin.com/ZjYBWABu
I also know the code for specifying where those files download to, the issue is I dont want to just download 1 .exe...I want to download all the latest build files which I would have uploaded to my server, which i would have taken from my Bin\release folder of my project.
Then when the updater downloads the files to a directory, it would go to the directory of the application, and somehow overwrite/replace all the files that have changed...maybe by using a hash or something?
I do not know how to proceed with this. What I do know is this.
The updater and the main app would have to be separate so that the updater could do the replacing while the app is closed so it doesn't get file in use errors. After the updater app has finished it would then start up the main app from the new exe.
Would appreciate help here thank you guys.
I am currently working on a project for which I have to implement a similar approach for updates. The project is lengthy, it would take some time to finish. But this is how I have planned to apply the updates:
There will be two main parts of the application Launcher (main application program) and Updater (To download files from server and replace them with the new ones and then launch the new file)
The application will have the option to manually check for update and also to check for update on startup.
If an update is available, it asks the user to apply the update now or later.
If the user selects to apply the update now then Updater application is executed in a separate process and then Launcher application is closed from within the code in Launcher. I have following approaches in my mind to launch another program from within first one and then exit:
Execute the Updater directly from within the Launcher using Process.Start
If that causes problem then as second approach launch command prompt from Process.Start, execute another program (Updater) from command prompt, close the command prompt and then exit the Launcher.
The Updater application then downloads all the relevant files from the server and upon completion old application files are replaced with the new ones.
Update availability information from server will include the new Version_No of application. For the purpose of providing all files for update, I will compress (zip) all of them in a single file named as Application.Version_No (as given by the server).
Upon download completion decompress (unzip) them to a folder named as the same Application.Version_No.
After decompressing all the files in this (Application.Version_No) folder will be copied to the Bin folder of application.
The new application Launcher file is executed in a separate process and Updater application is closed from within the code in Updater.
I have NOT yet tried this scenario as currently my focus is on completing the main application, but surely this must work.
UPDATE:
Another approach to check for updates is to use a bootstrap like application startup. It will be the main entry point of the program. Upon execution it will check for the updates and if there is none the Launcher is executed otherwise it will download the files, replace the old ones and then execute the new / updated Launcher.
For copying / overriding the files
One approach is to include only those files in the compressed (zip) file which are required to be replaced with the old ones and then after the download completes, either directly decompress them to the Bin folder or decompress them to a designated folder and then copy all of them to the Bin folder.
As another approach which seems somewhat lengthy, an additional helper file (XML, text or any other format) could be prepared for the download.
This helper file contains information of updated files like version number of each file, location where these are to be copied etc.
The files may be downloaded to a specific folder named as the new application version.
After downloading all the required files to a specific folder process each file mentioned in the helper file. Compare version of every old file with the new downloaded file. If it is latest then replace it in the folder mentioned in the helper file.
As another step in between all the downloads may be verified prior to copying and replacing.
Built an updater that ships with a daemon. Main project here:
https://github.com/UVLabs/dotNetUpdatify
There should be a way to eliminate the use of the daemon, if i figure it out i will update.
Related
I have a project that need to run in a pen drive, the content is updated daily, and i need a automated way to generate a single file (.exe) to be downloaded by users.
I use this tool https://github.com/mllrsohn/node-webkit-builder, but when build for windows, the build generate multiple files ( dlls, dat ,exe ).
This break my automation because the content need to be downloaded (single file).
Any help?
As far as I know, it can't. You could try making a 7zip SFX archive and running your own program instead of an installer.
This needs to create temporal files when run (which are deleted when the program quits) and I don't think you can remove the initial prompt. If you're okay with that, it might be what you need.
Edit: You can get the necessary SFX modules here.
I'm creating a WIX installer for a C# application.
In the application I use System.Configuration.ConfigurationManager.AppSettings[Setting1] to get settings.
My question is, where must I place the program.exe.config file on the machine in order for it to work?
I can't place it with the program in ProgramFiles directory, since those files are read-only.
I tried:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
config.AppSettings.Settings[Config1].Value = "Value1";
config.Save();
Unfortunately I don't know where it's looking.
Thanks your replies, Trevy
It should be in the same folder of the program.exe. Use wix to copy both program.exe and program.exe.config to the required folder.
If you need to edit the configuration file during the installation you will need to do it using a custom action in wix. Make sure you pass the file path to the custom action and write the code to read the configurations in that file and edit.
The problem isn't that the files there are readonly - the problem is that you are trying to update files in the Program Files folder with your config.Save, and you can't do that if you are a limited user, and you are always limited (even if you are admin) unless you elevate. The short answer is that:
If your app routinely updates files in restricted areas then it probably needs elevation, so give it an elevation manifest.
If however you require you app to be used by limited users and allow them to update that config file then don't install to Program Files. Choose User Appdata folder, for example. Windows is probably using your config file during program startup, so you can't separate it from the exe.
When I was creating an installer for my app, I found I couldn’t save my settings.
The reason is because the Program Files repository, from a practical point of view, is read-only (Applications should never run with elevated permissions). When installing a program, the only time we modify the MyApp.exe.config file is at installation/upgrade/repair time.
The config file has many sections. One of them is userSettings. This is where we store any data we need to modify during the lifetime of the application. When run for the first time, Windows creates a hidden file in the user’s AppData folder. That is why we can save user settings, even though the config file is in the same directory as the MyApp.exe
So the answer is, if we run into permission errors when trying to save our settings it means we are writing our settings to the wrong section of the config file. We need to place it in the userSettings section and nowhere else.
For convenience, Visual Studios has a settings editor (the settings tab of the properties page). It allows you to create strongly typed user and application settings. The generated class lets you save user settings, but not application settings for the above reasons.
So I currently have a script that works just fine with one problem. Whenever I publish it as a ClickOnce application, it has to be installed on the users computer before it can be used, and the the files I have specified to run if the user provides a valid login are showing up in the local APPDATA files.
I feel like there has to be a better way to publish my application. I want the 4 files ( a .swf that will run with flash, a bat file to run those, and a .vbs script that runs the bat file in the background so it doesn't pop up) to be included in the project, but to be written into the resulting binary files, not in their original form so the source is freely available.
Anyone have a suggestion?
I am writing an application in VB.NET. In the app, I have a function which calls a Powershell script and places the resulting information in a text box.
I have two issues:
How to I ensure that when my app is published, the powershell script is included?
How do I reference the script in my code?
Currently, I simply give my function the full path to the script, which is in a folder on my Desktop. Obviously, this will not work once I deploy the app to other computers.
You will need to create a Setup project to get your script in place on your target system.
A first step is to change the Build Action to Content and Copy to Output Directory to Copy always.
Your Setup project can pick up the script from the VB app build result and put it in place when installing your app.
As for your question concerning the user configurable install path: The easiest way to handle this would be to add registry entry containing the selected program file path and have your app read the path from there.
I am writing a program in Objective-C using Xcode. My program creates a file as follows:
[#"" writeToFile:fileName atomically:YES encoding:NSUTF8StringEncoding error:NULL];
I would like the file to be created in the same directory as the executable. When I run the program from Xcode, the file is created in the debug directory as expected.
However, when I run the .app file, the file is created in the root directory. How can I get the program to create a file in the directory where the .app file is located.
Thanks a lot.
EDIT: This is a MacOS application
EDIT2: Well, it seems that I shouldn't be writing to the .app directory. Thanks bbum and Paul R. What is the proper way to do it? To be more concrete, here's what I am doing: each time the user clicks a button in the application, a piece of hardware connected to a serial port will send a bunch data which will be written to a new file. This can happen any number of times while the application is running, so numerous files may be created. I would like them all created in the same folder.
You must never make any assumptions about the initial working directory for your application, as this will depend on what method was used to launch it (e.g. Finder, Terminal (via open), Xcode, gdb, third party utility, etc). You should use an appropriate API to find a suitable directory to store temporary files or user-specific files or whatever it is you need to do. This should never be within the app's bundle and never at a path that is relative to the initial working directory.
You do not want the file to be created inside the .app wrapper. That is never the right answer; your application may easily be installed somewhere where the current user does not have write access to the YourApp.app wrapper.
(For example, my main user account is non-admin and all applications are installed admin-write-only. If an app ever fails to work because it can't write to its app wrapper, the app goes in the trash.)
See this question for an outline of where files should be stored. Depends on the role of the file.