How to set permission of spawned application?

A

A Nonymous

I am trying to implement a web updater for my C# application. I am
using a technique I have used for several years in Win32 apps but it
isn't working for the .NET version of my app.

This is my process:
1. My app retrieves a version file form our web server and compares the
version to the version of the current assembly. Works fine.

2. If an update is available, I download the new Setup.exe from the web
server and save it in a folder under My Documents. Works fine.

3. I start the setup and close my app. Works fine.

4. At this point setup should perform the upgrade and then launch the
new version. This is where it fails.

Apparently the Setup.exe does not have permission to copy the new exe
into the \Program files\My App\ folder.

If I launch Setup.exe by double clicking on it, it works fine. As I
mentioned before I have been using this technique with the same
installer for several years with my Win32 applications.

I have included the subroutine that actually spawns setup.exe below.
This is actually the version I originally started with. I have tried
MANY variations and nothing works except launching with a specific user
and password. For testing I hard coded my info, but for a released app
it needs the credentials of the current user not mine and I can't figure
out how to get the current users password...

How can I spawn setup with the same permissions as the current user from
my C# app?

private void miHelpCheckForUpdates_Click(object sender, EventArgs e)
{
frmHelpCheckForUpdates CFU = new frmHelpCheckForUpdates(CFG,
_SerialNumber);
if (CFU.ShowDialog() == DialogResult.OK)
{
if (CFU.UpdatesDownloaded)
{
ProcessStartInfo SI = new ProcessStartInfo();
SI.FileName = CFG.DownloadPath + CFU.NewVersionSetupFile;
SI.WorkingDirectory = CFG.DownloadPath;
SI.UseShellExecute = false;
Process P = Process.Start(SI);
Close();
}
}
}
 
J

Jeroen Mostert

A said:
I am trying to implement a web updater for my C# application. I am
using a technique I have used for several years in Win32 apps but it
isn't working for the .NET version of my app.

This is my process:
1. My app retrieves a version file form our web server and compares the
version to the version of the current assembly. Works fine.

2. If an update is available, I download the new Setup.exe from the web
server and save it in a folder under My Documents. Works fine.

3. I start the setup and close my app. Works fine.
How does setup know your app is finished? It *does* test for that, right?
It'll have a hard time replacing the executable if the process is still
unloading. In general, managed applications don't start and stop quite as
fast as their Win32 counterparts.
4. At this point setup should perform the upgrade and then launch the
new version. This is where it fails.

Apparently the Setup.exe does not have permission to copy the new exe
into the \Program files\My App\ folder.

If I launch Setup.exe by double clicking on it, it works fine. As I
mentioned before I have been using this technique with the same
installer for several years with my Win32 applications.

I have included the subroutine that actually spawns setup.exe below.
This is actually the version I originally started with. I have tried
MANY variations and nothing works except launching with a specific user
and password. For testing I hard coded my info, but for a released app
it needs the credentials of the current user not mine and I can't figure
out how to get the current users password...
There's no way to do that, nor should it make any difference. I'm skeptical
the problem is with user credentials. That said, it could still be a problem
with permissions: if the setup program is managed too, it might apply some
sort of zone check to the downloaded assembly (which by default wouldn't be
trusted). This is pure speculation, though, as I'm hazy on the details of
code permissions on zones and evidence.
How can I spawn setup with the same permissions as the current user from
my C# app?
You're without a doubt already doing that, as this is the default. You can
verify this by looking at the process through Task Manager or Process
Explorer; the account name should match that of the parent process.

If you can't figure it out, try Process Monitor
(http://technet.microsoft.com/sysinternals/bb896645) and have it check for
access denieds. This should shed some light on what part's going wrong and why.
 
A

A Nonymous

How does setup know your app is finished? It *does* test for that,
right? It'll have a hard time replacing the executable if the process
is still unloading. In general, managed applications don't start and
stop quite as fast as their Win32 counterparts.
Setup doesn't know that my app has closed, but since I call Close()
immediately after spawning setup it is closed before they can click Next on
the setup dialog. I make them save/close any open files before I start the
update check, so there are no questions at this point it just closes.

What's really interesting is that at first I thought that the reason for
failure might be that by app hadn't really closed. But task manager shows
that it has close. I don't remember why I tried it, but I had my app
running and I clicked on setup without closing the app. I was surprised
that setup DID install the new app with the old app running. I closed the
app, and opened it again and it was the new version. I thought that
couldn't happen?

The reason I am relatively sure it is a permission problem is that the only
time it has worked is when I spawned setup with my user credentials.

I will take a look at process monitor to see if it can give me more info.
 
J

Jeroen Mostert

A said:
Setup doesn't know that my app has closed, but since I call Close()
immediately after spawning setup it is closed before they can click Next on
the setup dialog. I make them save/close any open files before I start the
update check, so there are no questions at this point it just closes.

What's really interesting is that at first I thought that the reason for
failure might be that by app hadn't really closed. But task manager shows
that it has close. I don't remember why I tried it, but I had my app
running and I clicked on setup without closing the app. I was surprised
that setup DID install the new app with the old app running. I closed the
app, and opened it again and it was the new version. I thought that
couldn't happen?
So did I. You learn something new every day, I guess... I know renaming and
moving an in-use executable is generally possible, but replacing it
shouldn't be. It might be some devilish trickery employed by the CLR for
managed applications, or else the copy uses some sort of shadowing
functionality.
The reason I am relatively sure it is a permission problem is that the only
time it has worked is when I spawned setup with my user credentials.
Specifying explicit credentials makes Process use a different set of calls
to launch the process. I still don't believe the credentials are actually
any different when launching it directly, but I'm just stubborn like that.
I will take a look at process monitor to see if it can give me more info.

That's probably the most expedient way.
 
A

A Nonymous

After going through the 18,772 events generated by Procmon for the
installer I discovered that the problem was caused by my obfuscator.

It always worked from the IDE (un-obfuscated). The hard coding of the user
credentials was a mistake. I was putting the update on the web site and
downloading it to do the update. But since I had my password hard coded I
didn't want to put it up there. So for that test I skipped the download
and just hard coded the return from the download dialog so that it looked
like I had downloaded it when in fact the file was already there. I also
skipped the step where I obfuscated the exe and created the version.xml
file. That worked, but it was because it was not obfuscated.

I don't understand why the obfuscation would have anything to do with a
spawned application, but it does. When setup.exe runs one of the first
calls it makes is to get it own name. When it is started from the
obfuscated version of my app the returned path is to a virtual directory
that doesn't really exist. When setup tries to FileOpen itself to unpack
the new exe, of course, it fails.

And by the way I was able to confirm that a running C# EXE has permissions
of "Read, Write, Delete".

I have reported the problem to the vendor and sent them a sample of my
config file.

Computers are evil and they are plotting against us. ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top