File.Move "File in use" exception

rethrow

Member
Joined
Nov 9, 2017
Messages
5
Programming Experience
5-10
Hi,

I recently wrote some software in C# for a friend, he has been testing it until now. It all works fine, for some minor error in my threading of my class. Will look at that later again and solve it. But for now the biggest issue is File.Move throwing a exception when my download class (fork of monotorrent, which I applied several fixed to..) is finished.

Let me explain a little bit more about how my program works(flow chart).

Inno setup installer > Installing in >%ProgramFiles% > After the installation we run the Installed executable.
Main executable in PF > read local SQLite db, sees first run > Ask for download > YES > Start download thread > Download UI will show up and show details > When done > Move downloaded data from ProgramFiles for example "C:\Program Files (x86)\MyProgram\downloadeddata" to "C:\Program Files (x86)\MyProgram" So it moves ALL files and folder to from downloaddata to the root of the installed application in PF.

I0xjDOp.png
https://i.imgur.com/I0xjDOp.png

Here is where it goes wrong.. When I tested the software on my test machines (Win 7 Pro x64 latest and Win 10 pro x64 latest) it works. But apparently my systems have the default user being administrator.

When My friend tested the software on his system and when he runs the installer it starts my application after Inno is finished, downloads the client data but then when it wants to move all downloaded data it runs in a exception "File x in use". When he ran the application(the installer with run application on finish) as Administrator the exception never showed up.

Why is this? Even on my Win 10 pro system (I did a default install, never messed with it) it works here. I mean UAC and account rights are like default..

Here is the code that does the moving copied from my application.

C#:
public static string RootPath = AppDomain.CurrentDomain.BaseDirectory.ToString();


MoveClient(@RootPath + "downloadeddata\\some-data", @RootPath);

        private static void MoveClient(string pobjSource, string pobjTarget)
        {
            try
            {
                if (Directory.Exists(pobjTarget) == false)
                {
                    Directory.CreateDirectory(pobjTarget);
                }


                foreach (string filename in Directory.GetFiles(pobjSource, "*.*"))
                {
                    File.Move(filename, Path.Combine(pobjTarget, Path.GetFileName(filename)));
                }


                foreach (string objSourceSubDir in Directory.GetDirectories(pobjSource))
                {
                    MoveClient(objSourceSubDir, Path.Combine(pobjTarget, Path.GetFileName(objSourceSubDir)));
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message.ToString() + "\r\n" + e.StackTrace + "\r\n" + e.HelpLink + "\r\n" + e.HResult + "\r\n" + e.Source);
            }
        }

What is a solution for this or does the application really need administrator rights for this ?
 
Last edited:
It does seem like an odd exception under the circumstances but I do know that non-admins are not supposed to write to Program Files. I can't tell you much more than that though I'm afraid.
 
but I do know that non-admins are not supposed to write to Program Files. I can't tell you much more than that though I'm afraid.
This is really odd because the Inno Setup has enough rights to write all the files to PF folder. But there was one problem especially on Win 8 and higher.

I had to add "Permissions: users-full" to all my files that Inno installs (for the database file) otherwise after the setup was finished and my program executed it had NO write access/permission to my .db file.
So when it did update and download client info and tried to write it to the db it also got a exception. Since I added those permissions to the installer, it now works flawlessly on Win 8 and higher machines.

It's only this "File is in use" bullsh!T that makes me want to smash my keyboard lol.

https://i.imgur.com/itunc9N.jpg

I can't tell you much more than that though I'm afraid.
Thanks for the reply anyway.
 
The problem was CreateProcess (it runs with not enough rigths) from Inno Setup at finish.
I have removed this and now when the setup is completed and the shortcut is opened by the user the program works the way it should.
 
Last edited:
Quick update. Problem is still present. I have no clue on how to fix this.
Even if the program is installed on another drive in a user created folder. I don't understand why.. It only happens on Windows 10 machines..
 
I've never ran into this issue with .Net, but then again I don't try to copy/move/rename files in restricted folders either.
Typically what should be done is you have the installer handle the windows permissions to install your program in the Program Files (or Program Files (x86) folder then your application simply works with data files in either the current user's profile folders (AppData for your app's config files, main data files, etc; Documents, Music, Videos, etc) of which your program doesn't need any special permissions to access, or if your application needs to use data across multiple Windows users you can use the ProgramData folder (it's a Windows folder in the root of the Windows drive, next to the Program Files folders) which you also don't need to have increased permissions to write to.

So all of that being said, is there a reason you can't have both versions of the UI be installed when Inno runs, then your app simply displays the appropriate one when it runs?
You can have your app download newer versions of itself too, simply download the new installer file to the current user's Downloads folder and have your app run it & close itself when it does so. The new version installer would still install both versions of the UI of course.
 
I've never ran into this issue with .Net, but then again I don't try to copy/move/rename files in restricted folders either.
Typically what should be done is you have the installer handle the windows permissions to install your program in the Program Files (or Program Files (x86) folder then your application simply works with data files in either the current user's profile folders (AppData for your app's config files, main data files, etc; Documents, Music, Videos, etc) of which your program doesn't need any special permissions to access, or if your application needs to use data across multiple Windows users you can use the ProgramData folder (it's a Windows folder in the root of the Windows drive, next to the Program Files folders) which you also don't need to have increased permissions to write to.

So all of that being said, is there a reason you can't have both versions of the UI be installed when Inno runs, then your app simply displays the appropriate one when it runs?
You can have your app download newer versions of itself too, simply download the new installer file to the current user's Downloads folder and have your app run it & close itself when it does so. The new version installer would still install both versions of the UI of course.

Hi,

I have found out what the problem was. It seems on Windows 10 it takes a lot longer to close all files handles after the download is finished (in monotorrent).
So when my finish flag was raised on Win 10 I just start the moving process. My solution is really dirt simple. I made a retry mechanism for moving. It waits 10 seconds if a file is in use and tries again, if a exception is hit again, wait 10 seconds again and retry.

It now works the way it should.

I know this isn't the best way but since the problem is really occurring on only a few machines randomly, this seemed the best way to fix it imo.
 

Latest posts

Back
Top Bottom