Reputation: 159
First off hi all, and thanks for the many times searching here has helped me out or taught me something.
I've made a custom HUD for a game I play, and am working on an installer in C#, inspired by another HUD for the same game. It downloads and overwrites all the script files to the existing directory:
C:\Program Files (x86)\Steam\steamapps\me\team fortress 2\tf
[I don't have any control over which folder to use unfortunately, since I'm modifying files which Valve installed]
In order to delete folders, add folders, or copy files, I've had to use an app manifest to increase the user permissions every time the exe is launched:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Somehow, the installer I've been inspired by is installing to the same folder that I am, without forcing a UAC prompt.
His app only shows a security warning, but if I uncheck the "always check" checkbox, I can run it over and over again without having to verify any special permissions:
http://www.trishtech.com/img_art_a/win7_publisher_not_verified_0.jpg>">
Any suggestions on how I can make my app more seamless like his? I've contacted the author of the other app, and he says he is also using C#, but doesn't know of anything special he's doing to make this work.
EDIT: A few things I know we're doing differently, just in case they make a difference somehow:
Upvotes: 5
Views: 265
Reputation: 159
I'm marking sgmoore's answer as the right one, although my own case seemed to be something a bit stranger and I want to document that too.
I've stripped down my program to the basics and done a lot of experimenting. I figured out that for some reason, he and I actually can copy files and create folders into that directory. Maybe it's something special about the steamapps folder, or maybe it's just a bug that's making it actually work in this limited case, when it shouldn't normally for "real" programs.
What was actually requires the UAC prompt, strangely, was running the exe from the \Bin\Debug\ folder where my project was initially generating it. If I move my exe somewhere else and then run it, it works fine. If I run his exe from my \Bin\Debug\ folder, his doesn't work either. I haven't been able to figure out why that is.
Something else I noticed is that when my app is going to succeed without an exception, it doesn't prompt with the security warning when I launch it. It just silently opens and then works. Any time it does display the security warning, it fails.
I guess the protocol would be to turn those two issues into new questions, but it seems at this point it's probably well into edgecase/hack territory since all of you agree that this shouldn't even be working at all.
I'm going to build my program back out and see if I can still get it to work with full functionality under these weird circumstances, or whether I'll have to reenable the UAC elevation.
Upvotes: 0
Reputation: 3443
He's just outputting them to the same directory as the exe, requiring the exe to be put in the destination folder.
I don't think that will be it. The same exe directory should be no different, you either have permissions or you don't.
The "normal" response would be, write to a directory you have permission to. But this is not always possible.
If you ran your application as a service it would popup just the once I think under Windows, but this does not seem right for your use case.
I don't think there will be any proper way to suppress such a message, its like a catch 22 situation. To do something you cannot do, you need to get permission (so elevate user -> UAC popup).
Upvotes: 2
Reputation: 16077
If you are trying to write to "C:\Program Files (x86)" then you need admin rights. It follows that the other app must not be creating files there, but to a directory that is not protected by UAC.
If your files are per user, then you can create a subfolder in the appdata folder and save the files there.
Convention is to create a folder to indentity the company and another to identity the product,
eg
var dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
+ "\\MyCompanyName\\MyApplicationName";
Upvotes: 3