I currently store a serialized XML file in the application directory that contains all changes specific to the program operation (not typical system or user configuration). Weeks ago, we started running into problems where it would not save correctly (read my previous question about this).
Long story short, we finally discovered that Windows 7 (and sometimes Vista) has an issue with writing into the application directory (specifically anything under Program Files). Now, if this were a normal configuration file I would simply store it under the user's APPDATA folder, but it is not normal. We run this on our own instrumentation, and misconfigurations are 99% of the reason customers have issues running our software. So we need this file to be accessible such that they can easily find it and email it to us. Appdata is hard enough for experienced users to find, much less very non-technological people.
We've also tried running it as Administrator, and making folder permissions wide open (we have control over every computer it runs on; it will never run on some random person's machine). But, these sometimes work, and sometimes do not.
The worst part is that when I write the file back out, it doesn't even throw an error; it simply writes it to some temporary directory that expires at some unknown point in time. Weeks later, our user will have an issue, and the configuration file is all messed up.
So, my question is where should I be storing this file, if not in Program Files? Should I just put it in APPDATA anyway, and make a small utility that emails it to us automatically in case of a problem? Or can I leave it in Program Files, but change some specific permission or registry key to allow it to operate normally?
It depends on whether or not the user needs to edit the file directly. If not, you should put them in %APPDATA%, which you can access via:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
Otherwise, you might put it in My Documents:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
Either way, putting it in Program Files is not a good idea. As you discovered, there are permission issues, even if running as Administrator.
For those users, you could build a button in that would open this directory. You could put it in an inconspicuous place that you could later direct them to.
For users that have an email client on their box, you could have a button that would create a new email with subject and automatically attach the file to the email.
Related
I want to prevent executable being copied to another PC and thus i need to somehow save information inside my EXE file about that it was already used somewhere else on another PC.
Can i embed small piece of information like user's hard drive number into my EXE file so this information would be available when this EXE is copied to another PC?
I thought maybe there is a way to read and write to some resource file embedded in an EXE file but i presume that resource file is read only and if so is there is a place inside EXE file where i could keep information which i need?
You're fighting an uphill battle this way. It's possible to create a home-grown licensing scheme but be prepared to do a lot of work (I did it, so I speak from first-hand experience). Just some problems to solve:
If the hard drive fails and needs to be replaced, your user won't be able to use the program. Every time this happens, you'll get a support call with an angry user.
If the user runs your program inside a virtual machine, the hard drive serial number won't be unique - anyone can clone the virtual machine and now your program can be run on another machine.
Hard drive serial numbers can be changed - they don't come directly from the hardware.
What if the hard drive is a removable drive? Your user can run your program from a removable drive and then keep moving it to different machines.
Even if you get it done, how do you protect the license information from being modified?
If you really want to license your product, look at existing licensing products - they're not cheap but they already did the (considerable amount of) work that's necessary to have any kind of reliability.
Even if you only want to have minimal protection, consider this: you'll have to do a lot of work to get even minimal security of your secret token (whatever that is). If its security is minimal, then what's the point of you even doing all that work? If all you do is force people to put in a meaningless serial number, you'll just annoy your honest customers. If anyone wants to steal something that's not well protected, they will steal it. All a 'simple' protection scheme does is annoys your users and gives you a false sense of protection.
I ended up using Reprise RLM - I'm not associated with this company but I had a good experience with their sales and support people and their product worked well in the testing scenarios.
Ok, I analyzed all the variants that were proposed and decided that in my case it will be better to develop my own copy-protection system, due to the reason that I am an indie developer and not going to work with extra large applications.
Just in case, somebody faces to the same issue - here is the algorithm (well, one of them):
User starts APP1.EXE
APP1.EXE reads itself to some variable and adds HDD serial number to the end of it, e.g. HDD serial number - when you add something to the end it does not break EXE file and you do not have to worry about PE headers
Unfortunately, EXE cannot save itself in runtime so it saves its copy called APP2.EXE with the information about HDD
When APP2.EXE is saved APP1.EXE starts it as a separate process via Process.Start() and terminates itself
Now APP2.EXE is running and has the same content as APP1.EXE + HDD serial number so we simply write all bytes from APP2.EXE back to APP1.EXE, close current process and start APP1.EXE again
From now on APP1.EXE is running and have all needed information about current HDD so each time user starts APP1.EXE it compares HDD number at the end of its content with the actual one on user's PC, if they differ - terminate the process
Delete APP2.EXE so that user would not realize how these files exchange information about his HDD.
Useful info about self-deleting EXE can be found here :
http://www.catch22.net/tuts/self-deleting-executables
http://buffernow.com/selfdelete-executable-in-c/
P. S. I know that it is like a huge hole of security (I will not mention all of them) but implementation of this algorithm took just 20 lines of code in C# and was moved to a separate DLL which I can use everywhere and it works. There is NO any registration in the algorithm above and user can simply take this app and use it and I am sure that ~ 80% of them will not realize how this app is protected from copying.
Link to implementation : https://bitbucket.org/artemiusgreat/examples/src/ef7b60142277?at=master
I would like to create a c# application which will open when i open a folder automatically.
My c# application is intended to be like a password system, so that the contents in the folder can only viewed after logging in to my application. Everything is ready..........
but i am confused how to open my application directly while opening the folder with a c# script?
I have now created a application which will ask the user for name and password while opening the application and now i want to make it open through the folder to be locked , how to do it?
Ok, first of all if you want the folder to be secure you should encrypt it otherwise all the user has to do to gain access is kill the process.
What i would recommend you do instead is create a encrypted file. For example a zip file. Then all you have to do associate the file with the program and to unpack it with the password. Then when the user is done delete it and overwrite the temporary folder. It's really important that you overwrite it otherwise the encryption is useless.
If you want to avoid conflict with other programs that work with zip files you can make your own file type it does not affect the content of the file in any way.
I hope this helps.
To make sure I understand... you want to build an application that will, when someone tries to open it, will only open after they supply a password. Hmmm... okay. A specific folder, or any folder? Local folders or folders on network shares? I initially was thinking a file system watcher approach, but that will only work on change events, like copying, renaming, deleting, etc. So that won't work. The closest would be to check last accessed time, but that is an alert ex post facto, so this must be rejected. I'm not sure how you could do this in C#. What is wrong with the robust security options MS has already established, like global groups. That provides flexible restrictions on access. Especially over large amounts of folders. Are users going to have one password per folder? Too cumbersome. One password per user? Use Windows authentication to lock it down. How is this app storing the passwords?
I recommend trying to leverage existing technology to solve problems before trying to re-invent the wheel. You have omitted the scope of this, and what you have already attempted, so we may not understand completely.
I have a file called middle.config that is deployed in the same directory as an exe, but I need to update values in this file. That means that I have to go to C:\Program Files (x86)\ directory to access the file. Although it is named as a .config file it does not follow the usual schema of a .config file. It looks like this:
<configuationSettings>
<middleSettings
groupName="XYZ"
forkName="SomeDbName"
dbServerName="123.123.123.123"
cnnTimeoutSeconds="30"
cmdDefaultTimeoutSeconds="30"
cmdMediumTimeoutSeconds="60"
cmdLongTimeoutSeconds="480"
/>
<userKeys>
<Assemblies value="C:\assemblies\" />
</userKeys>
<friendlyDbName value="NiceData"/>
</configuationSettings>
I'm able to read and manipulate the content with Xml, but when I try to save the file back, a "No Permissions" error is thrown. I cannot relocate the file. I'm stuck with this legacy schema so I'm not able to treat it like a normal .config file using ConfigurationManager.OpenExeConfiguration. I cannot define sections or groups on this schema (I've not been able to anyway). All my users are Administrators on their local machines.
How do I overwrite or delete and replace this file while it is in a protected directory(my assumption about the permissions error)? Failing that, is there a way to access this schema somehow with ConfigurationManager.OpenExeConfiguration.
{edit starts here}
There are three applications in this scenario, A, B, and mine C. Application A does not know about any other applications. It can connect to many, many databases, and it drops a single file 'middle.config' that contains pointer info to the last database location that was used by the last Application A session. Application B, let's call it an import/export application, only operates on the last Application A database location. Application B reads the 'middle.config' file for database pointer info and then executes console commands against that database. It performs bulk dumps or bulk imports for selected portions of the database.
This was the situation when I come along to build application C that uses the import/export application B to fetch, blocks of data and return them to the database. So, in order for application C to use Application B
against any database, application C must modify the 'middle.config' file so that application B will find the correct database. Application C is new and the other two are legacy. I either find a way to make this work, or I force the user to start Application A and point to the database of interest, then close Application A. This is VERY unhandy.
{edit ends here}
It is not advisable to write data files to the program files directory, as this requires elevated permissions. Giving a program elevated permissions just to update a config file clashes with the Principal of Least Privilege, which states that
a particular abstraction layer of a computing environment, every
module (such as a process, a user or a program depending on the
subject) must be able to access only the information and resources
that are necessary for its legitimate purpose
It's not a "legitimate purpose" to give the process elevated permissions (that can allow it to do many harmful things) just to update a config file. MS recommended practice is to write that type of data elsewhere.
Instead, consider storing the config file in a subfolder of the ApplicationData folder.
Suggested that your app is creating its own location under the AppData location folder for the current user instead of writing to files under location where the the app is installed (especially if under Program Files which is very strict.) Not suggested to force the user to run as Administrator for your application either.
Your assumption about protected directories is correct. Program Files has an Access Control List which prevents modification by processes running as standard users and, on Vista upwards, even by administrator processes which are not running elevated. Accessing the file using the standard configuration classes would not get around this.
If you absolutely can't move the file (Eric J. is right when says that writing to Program Files after installation is a bad idea), then you could embed a manifest in your config file-editing program which will try to force elevation with a UAC prompt at launch. Of course, the best solution would involve a) using standard config schema and b) keeping user data in user-writeable locations, but sometimes that isn't possible for legacy reasons.
I'm not aware of any way to persuade ConfigurationManager to read a non-standard schema, unfortunately.
Move the logic to a separate process and launch it with admin privileges from your current application.
From a different angle, look at this: Writing custom sections into app.config
I found the linked article to be very useful. Not sure it is going to answer all your questions though.
Hi is it possible to prevent my .exe application on being renamed..?
here is the senario(my problem)
After i Run my program, (lets say i run MyApp.exe)
a unfriendly user suddenly for fun, renamed my MyApp.exe to ... lets say Goodtime.exe
after that. he log-off windows(xp) and then when my program is attempting to run on startup
MyApp.exe , i wont because it got renamed
is it possible to prevent this through codes?
thanks to anyone who would help =)
You can't really attempt to stop this. It's the user's computer and if they want to rename files on their computer they can do.
That is not possible.
However there is an alternative to do that.
You can set the user to have limited rights on his user account to the computer. In that case he cannot rename files in such a way he wanted. This is a restriction provided by the operating system in which only the administrators of the computer can set these restrictions to user accounts.
EDIT
What I mean here is if you are the administrator of the computer, as an alternative you can manually limit the privileges of the users who logs-in to the computer. For a better understanding on what I mean, please read the replies on my post. :)
You can place your application somewhere the user is less likely to go and rename it, like in the program files folder. But you can't stop them actually renaming the application.
If the user isn't an administrator on that machine they won't have permissions to rename files in the Program Files directory by default. One would hope that unfriendly users aren't administrators on the target machine (If they are, they can do a lot worse than renaming one application file).
You can check what name the executable has when it's being run.
But you cannot prevent a user from renaming it.
You might consider using clickonce publishing. For the life of me I can never guarantee I can find the ruddy application after installing it with clickonce so that might stop your friendly user messing with the app? ;-)
Here is some info on ClickOnce Publishing.
In essence, write an application, right click the project/solution, choose "Publish", then follow the wizard.
It won't guarantee the user won't be able to rename and mess with the files, but it'll make it harder.
By permissions way as most folks here explained.
Stupid and waste method is to have a daemon (Service) running accessing this file all time since system boot. That way system wont allow this executable to be renamed unless this daemon is stopped.
you can prevent renaming or moving your exe file while it is running.
Open the exe file within your exe file for reading and deny writing.
Keep this file open as long as it runs.
So I have been writing to
Environment.SpecialFolder.ApplicationData
this data file, that upon uninstall needs to be deleted. I am using Innos Setup to build my installer. It works great for me. So my data file hangs out in the above path and I do that cause when I used to try to write it to
Application.ExecutablePath
certain boxes I tested it on would throw a nasty error at me trying to write data there. I do research and somehow its not always writable and its how i came up with the Environment.SpecialFolder.ApplicationData
That is why my data file now resides in the SpecialFolder.ApplicationData. Trouble is if the user uninstalls and reinstalls I need that file gone. It might be a short coming of my knowledge of Innos but I cannot figure out how to know where that file will be to tell innos that.
So then I thought I had a clever solution: Innos can run a file when its done uninstalling, so I had my program create this file "uninstallData.bat" that says:
del "the file in my special folder application data path"
and I wrote it out to drumroll
Application.ExecutablePath
(yes it was a while in development and I had forgot it was't doable.)
So of course I am back to square one, I need to write a file to a path Innos knows about {app} and I need it to be able to delete my data file in the SpecialFolder... i don't care how I do it i just need that file gone.
Are there other Environment. or Application. approches I have missed? Maybe somewhere that is viewable by an uninstaller AND can be written to?
As an aside, I am not sure why my box I develop on can write to the application folder no issue, but it cannot on other boxes... weird.
Any input would be great sorta lost as to how to crack this nut.
The environment location is in the user profile. If there are multiple users on the machine, and they all run the application then a copy of the file will be in each profile.
The path also depends on the OS.
Regardless, the current user's app data location is pointed to by %APPDATA% and %LOCALAPPDATA%. These Windows environment variables should be available within Innos.
Appliccation.ExecutablePath is not writable per standard defintions - the program files folder should never be manipulated by running applications. Ther area number of special folders for that. Nice that you finally found.... what is properly documented by Microsoft for a LONG time now (minimum 10 years).
I suggest you get a proper installer - WIX comes to my mind. Your problem is totally unrelated to C# - it seems to be totally a "crappy installer" issue. Or provide a PROGRAM (not bat file) to run at uninstall. What exatly is your problem there?