If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

deployment catch 22

I have dialog app that requires two external *.exe s to function properly. The most important of these is Init.exe which copies a couple of needed files from the main app root (installation) directory to a User directory on the main app's first run. The main app recognizes a 'first time' run on a given machine and, in response, runs Init.exe from the root directory which in turn creates and copies two other files, a *.dll and another *.exe to the User directory.

If all this seems unecessarily complicated, it has been forced upon me because of the enhanced security of Windows 7. The latter OS will not allow the running of Init.exe to copy files out of Programs Files (x86) without administrative privileges. In fact, any Win 7 program installed in Program Files (x86) is prevented from copying or moving files out of the root directory without administrative privileges. Not only does this create runtime problems for such programs run by non-administrators, but for my program, it simply will not run unless the necessary files are in the User directory.

Now it is easy enough to initialize the user directory manually, or even on first run of the main program, provided administrative privileges are held, but woe to the non-administrator who tries to install and run the program. I appreciate the fact that this added security is a safeguard to prevent any user from installing malicious or damaging software, but it also creates a host of other problems as noted here.

Has anyone devised a workaround to deal with this problem? How do you manage your apps in this regard? Manual setup of the User directory and files is a big thing to ask of the average user. Installation outside of Program Files (x86) is an unappealing option - mainly because Windows Installer does not provide a user-friendly option and the non-administrator installer user would have to know where to install the app - a big order for most users. Reconfiguring the security on a machine is only an option if the machine is not on a network requiring local machine security where administrative privileges are granted to only a select few.

Re: deployment catch 22

Not only does this create runtime problems for such programs run by non-administrators,

That's the whole idea!!! To improve security of the system and to attempt to prevent malicious programs doing malicious things.

but for my program, it simply will not run unless the necessary files are in the User directory.

As S_M_A has said, this is not the correct approach. No exe/dll should ever be placed in the User directory. These all belong in Program Files. If your program has been so badly designed to need these in the User directory then you should re-design your program so that it doesn't. Any program on my system that started to create exe and dll files outside of the stated Program Files folder would find itself terminated and purged with extreme predudice quicker than you could say bad idea.

All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

Re: deployment catch 22

Mike, ask yourself "is there an existing piece of software that does what I want to do?". If the answer is "no", then there is a reason for that, given the vast amount of Windows software that has to go through an "official" installation process.

Re: deployment catch 22

I misspoke about the dll. No dll is placed in the User directory. Sorry. But the *.exe is a simple Win32 CheckForUpdates.exe that the Main App runs via a ShellExecute to do what it's name implies. It uses the URLDownloadToFile method to download a file from a website that can be compared with the current version. The reason that CheckForUpdates.exe is copied from the Main App root to the User is because Windows 7 won't allow it to use http connection necessary from the Program Files (x86) directory. The other file that is copied to User is a short (256 bit) binary file that serves as a required key for the main app and can be changed by the user when desired.

While I certainly appreciate your comments, nowhere in them do I find a suggestion as to how to overcome the limitations imposed by Win7+ security for non-administrators. All that I gather is that we must now give up applications designed to interact with other executables that copy files to User directories or that attempt to download files from a website. If that is the case, I will need to revise my thinking on application design. Dissappointing. I thought I had solved the problem.

Re: deployment catch 22

Originally Posted by Mike Pliam

While I certainly appreciate your comments, nowhere in them do I find a suggestion as to how to overcome the limitations imposed by Win7+ security for non-administrators. All that I gather is that we must now give up applications designed to interact with other executables that copy files to User directories or that attempt to download files from a website. If that is the case, I will need to revise my thinking on application design. Dissappointing. I thought I had solved the problem.

Frankly, I do not understand the whole drama. There's gonna be no suggestion ever "how to overcome the limitations imposed by Win7+ security for non-administrators" as the thing if existed would look absurd from security standpoint. And yes, you must change the design due to imposed limitations, or change the requirements. Period. You either keep complaining (I believe I already heard about the download thing a couple of months ago) or do your job (as it was exactly recommended last time, no change, sorry), it's absolutely up to you.

And what's wrong with copying your exe to user profile as long as the one is intended for comparison only? Or it's not?

BTW, first thing, if your app is properly versioned, there's no need to download anything to see if update required. You just request the latest available version info and compare it with the currently installed version. Second thing, if your program was installed with elevated privileges, it's absolutely normal thing to require the same for running updates. There's no any ground to be disappointed, you just do the things right way.

Re: deployment catch 22

just request the latest available version info

In order to compare the user's version with the latest and greatest version, the user would have to use his browser to go to the website to check a recent posting, a cumbersome task, or obtain 'the latest available version info' programatically and compare it with that user's version. I'm not a web expert, but I have done some fair amount of web programming (see http://www.pliatech.com and http://www.sfhi.com) using asp.net and c#. Outside of downloading a file containing update info, I'm uncertain as to how the user's app would obtain update info. Please tell me how you would do that. Most of the sophistocated programs that I've come across use a Check For Updates menu item that requires an internet connection to work (and can be rigged to autoupdate if so desired). Of course, your point and the others is well-taken, if one is not a member of the administrator group, they shouldn't be allowed to check for updates much less install them.

Re: deployment catch 22

Originally Posted by Mike Pliam

Outside of downloading a file containing update info, I'm uncertain as to how the user's app would obtain update info. Please tell me how you would do that.

This is just about making a single GET to the web page that replies with version info JSON/XML/plain text/whatever, no matter which way this info is built, static or extracted on the fly. You read that in memory with InternetReadFile (see sample), there's no need to write to file.

Re: deployment catch 22

Originally Posted by Mike Pliam

if one is not a member of the administrator group, they shouldn't be allowed to check for updates much less install them.

Checking for need in updates is not something unsecure. The same to downloading bits. But running the downloaded file must be done with caution. The downloaded file must embed manifest where running with admin level is required.

Re: deployment catch 22

you shouldn't download a whole exe simply to compare if your current exe is the right one. you should look into a proper versioning system and just check if you have the right version and download the exe only when necessary.

Things exist for a reason, and what you suggest wouldn't even work properly if the user ran in a low-rights environment. The admin may have set up the system so exe's don't even run other than from known locations.

The reason that CheckForUpdates.exe is copied from the Main App root to the User is because Windows 7 won't allow it to use http connection necessary from the Program Files (x86) directory.

wait. wot ? i've never heard of any such sillyness. There is no relation between program files and ability to do downloads. If there is, it's set as such by the system admin/user explicitely in their firewall/proxy and then it has a reason to be that way. If it works by copying exe's elsewhere, that's more a sign of said user failing to properly plug his own security holes than an actual inherent feature of Windows.

If your exe has a need for automatic upgrades without administrator actions, then there are solutions for that, but somewhere somehow, an admin will have to allow such automatic unattended upgrades being allowed in the first place. It'll typically involve (among others) you having to digitally sign your exe's to make sure the upgrades are indeed valid upgrades from you and not from some malware trying to abuse your autoupdate system to do it's evil deeds.

The thing to keep in mind here...
If you try to bend windows into doing things countrary to it's design or it's security goals. Expect your software to break down horribly every time a new version of windows (or even just service packs) come out and get installed.

Re: deployment catch 22

In fact, there are reliable programs that place dlls, exe's and whathaveyou in the User directory, e.g., Juniper Networks/Setup Client. But that is not the issue here. I agree that it would be much simpler for a non-administrator user to simply be able to read the contents of a remote server text file to determine if there is a more recent update, then let the network administrator do the rest. The problem is how to read that remote server file. Igor has suggested a way using InternetReadFile or the MFC version, but I cannot get either to work for me. Note that the Url and file exist and have been enabled for anonymous read. The non-MFC version fails to make a connection. A dump of the MFC verson buffer yields:

Re: deployment catch 22

The first version fails at the InternetOpenUrl call. Read the docs for InternetOpenUrl, specifically the 'Return value' section which explains what the function returns & what to do when it returns NULL as it is in your case. Once you do that you will have more information about why the function failed & should be able to fix that problem. Once you fix that, you have the same problem as in your 2nd version. Manually confirm that your url works by testing it ("http://www.pliatech.com/UeberKrypt") with a browser.

Re: deployment catch 22

Re-read the docs for InternetOpenUrl. Specifically what it says about the 1st parameter. In general though, when you're having problems with some API, the best thing is to read/re-read the docs for it, in its entirety. The 'Parameters' section, 'Return value' section, 'Remarks', etc...everything. After that if you still have problems also try googling '<api> example c++'.

Testing the target url file with a browser, it readily downloads the file, but that is not what I want to do, only to read it.

One phrase I think applies very well to programming is 'the devil is in the details'. Did you copy & paste the *exact* url I specified in my previous post? I included it there for a reason. That's the one in your InternetOpenUrl call. Entering that in the browser gives the same 'This Virtual Directory does not allow...' error that you are getting in your program.