Update app from the application - c#

I am trying to develop a feature in my app, which will enable users to check for the updates and, if new version exists (on the FTP server), it will download all the new files and run the new instance of the application.
I have successfully managed to check for an update (by comparing XML files) and downloading the zip file from the FTP server into a temporary folder. However once I started copying the files into the main folder, application suddenly crashed becuase all the dll's I have tried to copy were already in use.
I came with two approaches that are possible:
1) rename all the files under the main folder to: originalname.dll.bak (append .bak to the end of their name). Then copy original files and restart application. Upon opening new instance (updated exe file), the very first thing we do is that we erase old files ending with .bak. One problem with this approach is, that I can easily rename currently running process to include .bak, yet I am not sure if I can do the same with the dll files (have not implemented this solution yet)
2) Create an external app (e.g. console app), which will be executed from the main application whcih will handle the update process. Upon opening this external updater, my main app will immediately close so that we can assure that copying of the new files will be without a problem.
I have not done any of this before therefore any comments & suggestions will be more than welcome. Also shall shall there be any better way how to handle the update process, I would be more than happy to implement it.

Related

Winforms showing different values from xml

I have a windows service project which contains a Test.xml file. In the properies it is changed to copy always.
I have created a setup for service and after installing the service the Test.xml is present in the C:\program files(86)\service folder.
Now I want to edit the Test.xml file throgh a UI. So i have created a small Winforms project 'EditXml'. The EditXml is accessing the Test.xml like this
document = XDocument.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test.xml"));
I have added the EditXml.exe also to the setup of services. So after installing the service the EditXml.exe is also present in the folder.
But when I edit using EditXml I cant see the changes in test.xml.
Why values are different from Test.xml? Is this a correct approach? Let me know if question is not clear.
I think that you have an issue with inssuficient permissions and windows file virtualization. When your installer creates a file inside Program Files folder, it usually sets permission only for read operations.
When you try to modify the file using an application running at user account that has now write permissions, windows makes an illusion that the file has been successfully written, but puts it in a virtual store - check if such directory/file exists in c:\users\CurrentUserName\Local\VirtualStore\Program Files (x86)\YourFolderName
Only your application can see modified file version, but all other application see original version written by installer.
To be able to modify the file using an application, you need to add write permissions to the file.

Self Deleting Executable (Uninstaller)

I'm trying to make an uninstaller.
I basically need to be able to remove a directory in the program files that contains the uninstaller.
I was thinking to have the uninstaller create a copy of itself to the temp folder,
then have the uninstaller running from the program folder open the uninstaller in temp and close itself where it continues the uninstall.
Problem is, how do I delete the uninstaller in the temp folder...
Check out: https://www.catch22.net/tuts/win32/self-deleting-executables
He has multiple solutions - but mostly aimed at C++ code.
I am currently trying to implement the "DELETE_ON_CLOSE" method in C#.
A comment to all the nay-sayers: MSI does not solve this problem in all cases. In my case, my application needs to install to a network folder, where any network user can run the app. It also needs to support upgrades and uninstalls from any network workstation - not necessarily the same workstation that installed the app. This means I cannot register an Uninstaller into the Add/Remove Programs list on the local machine. I must create an Uninstall.exe that is dropped into the install folder. MSI does not support that, so I have to write my own.
Even though I agree with everyone saying you shouldn't do that, what you can do is:
Have your program create an executable (and config file) in the temporary folder of the OS it's working on.
Have your program start it as an independent process, then exit.
That executable then calls back the actual setup stuff.
Once the setup is done, the temporary executable can delete the setup files.
Since the only trace of your program is now in the temp folder, it will eventually get cleared automatically.

File redirection from Program data to AppData\Local\VirtualStore\ProgramData

I am using C# with .net 3.5
I am saving my program data in a file under: C:\Program Data\MyProgramName\fileName.xml
After installing and running my application one time I uninstalled it (during uninstallation I'm removing all the files from "program data")
and then I reinstall the application, and ran it.
The strange thig is that my application started as if the files in program data existed - means, I had old data in my app even though the data file was deleted.
When running:
File.Exists("C:\Program Data\MyProgramName\fileName.xml")
I got "true" even though I knew for sure that the file does not exist.
The thing became stranger when I ran the application as admin and then the file didn't exist.
After a research, I found out that when running my application with no admin priviliges instead of getting: "C:\Program Data\MyProgramName\fileName.xml" I get "C:\Users\userName\AppData\Local\VirtualStore\ProgramData\MyProgramName\fileName.xml"
and indeed there was a file that existed from the previous installation (that I obviously didn't delete ,because I didn't know it existed).
So apparentlly there is some virtual path to the file under program data.
EDIT :
I found out that after deleting the old file in the virtual store, my application is suddenly able to find the correct file. (I didn't make any changes in the file under Program Data.
My question is:
why is it happen.
How can I prevent it from happening
Thanks in advance
Do you actually have to write to the per-system Program Data folder instead of the per-user Application Data folder(s)?
You might want to take a look at Environment.GetFolderPath and the following Environment.SpecialFolders:
Environment.SpecialFolder.ApplicationData - data folder for application data, synchronized onto domain controller if the user profile is roaming
Environment.SpecialFolder.LocalApplicationData - data folder for application data, local and not synchronized (useful for, for instance, caches)
EDIT:
Tested on Windows 7 x64, non-administrator user.
var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
var myFolder = Path.Combine(appData, "MyApp");
if(!Directory.Exists(myFolder)) Directory.CreateDirectory(myFolder);
File.WriteAllText(Path.Combine(myFolder, "Test.txt"), "Test.");
This does what is expected, ie. writes into C:\ProgramData\MyApp\Test.txt. As far as I can tell (Administrator mode Command Prompt), there's no UAC virtualization going on either.
Double edit:
I guess what's happened is that at some point an Administrator user has written the files into your ProgramData folder, and as such, UAC file system virtualization kicks in and redirects the non-administrator writes into the VirtualStore.
Does your uninstaller run as Administrator? If it does, you might have to check both the VirtualStore path for the user who initiates the uninstall, and the actual file system path for program data to remove. I'm not sure if there's an official way to do this, though...
I found the reason for the bug.
the application is trying to take ownership on the file and then the other file is created.
I removed that line and now everything works just fine.

File.Copy fails when copying a DLL that is not in use

I've built a winforms app (C#) that will take a list of file paths, and copy those files (from a different VS solution) to a new location (In a folder the user specifies) in the same directory structure they currently exist on local file system.
I use the Path class, Directory class etc and everything works wonderfully...except when it reaches a file path that points to a DLL.
The DLLs I am trying to copy are a part of the other solution, and that solution is not currently open.
I have tried restarting computer to make sure visual studio isn't somehow hooking into that DLL even after the solution is closed.
The DLL in question can be copied by regular manual means (i.e. copy and paste shortcut).
So short of creating a batch file in the program, and running xcopy on that DLL path, I don't know of a way to get this to work.
From what I have found from google searches (which isn't much on this particular situation), File.Copy() should work..
Any help would be wonderful, even if it is a link to a duplicate question I may have over looked.
Thanks!
-The error message is: The process cannot access the file [insert file path] because it is being used by another process (The path is definitely correct also)
-Just downloaded and tried to search for the DLL name with Process Explorer.. I also ran a similar exe from command prompt to no avail. It claims nothing is using it. That's why I am utterly baffled by this. Also, I just checked the permissions and everything looks great (i.e. Full Control, owner effective permissions)
-It does not handle open files. It basically build the correct src and dest paths and does a File.Copy() on those. How would I go about handling open files? I'm sure I could figure out if it was open, but what would I do it it were open?
It is not complaining about the file you're trying to copy, it is complaining about the file that you're trying to overwrite with the copy. Lots of candidates for that, virus scanners always get very excited about new DLLs, for example. Or it is loaded into a process, the typical failure mode for trying to implement your own auto-updater.
You can rename the target file to make your copy succeed.
Are you in vista or win7? If so, Check your 'User Account Control Settings'. Sometimes this can interfere with .NET security options and prevent file operations that would otherwise work.
As well as Process Explorer, I would use Process Monitor also from Microsoft so you can see what is happening at the point of failure and allows you to see if anything else is accessing the dll.
Possible culprits are
the program you are running,
your antivirus package
a virus.
If the path it is complaining about is the destination path, then is is possible that the path is too long?
Also, when using Process Explorer, make sure you have enabled the option to show details for all processes and not just your own.
I just ran into this issue as well. I tried copying a .DLL from an FTP server to a local directory (replacing the existing one) and for the life of me I could not get it to work. Keeps giving me an 'Access Denied code: 5' Error.
I then realized that the .DLL on the FTP server was not marked as hidden while the .DLL I was trying to replace was marked as hidden.
Once I changed the local one to also be visible. I had no more issues.
So my solution is:
Make sure both files are visible.
Hope this helps someone

Won't let me delete a folder that I just moved a file out of?

Here's my problem: I just finished up an app which allows you to right-click on a file in Explorer and hit an option to open the app. It then renames and moves that file out of the folder to a specific location, and then deletes the folder (empty or not). This works fine when the files are loaded through the GUI, but the whole point of the explorer context menu is that the GUI never has to load, it's just a one-hit-wonder for single files.
However, when using the context menu, the folder doesn't delete and it throws an exception saying the folder is in use by another process. The file still gets moved and all other files still get deleted. Why is this happening? Is there some way I can explicitly release the handle on the directory in order to make this work?
I'd show you the code but it's extremely basic (ie one line, Directory.Delete). I've also tried using DirectoryInfo.Delete but that didn't help. Like I say, it works fine from within the GUI.
Am I correct in assuming that deleting from the GUI means that the folder is not currently open in explorer whereas when you delete using the context menu the folder is (obviously) open? If so, this blog might have some insight into the problem. Also, here's another SO question which asked how to close an explorer window. Might help.
"Windows NT family of operating systems keeps open a handle to the process's current directory."
I think whats happening is explorer is trying to delete the folder while the file is being copied or moved. What you need to do is create a seperate thread that moves or copies the file (or files) first, then when that thread completes, delete the folder.

Categories

Resources