views:

29

answers:

2

I'm using Process.Start() to initialize an elevated copy of the currently running application. Unfortunately Process.Start() returns null because it thinks it's using an existing process of my application, and while there is an existing process, it doesn't specify any way of handling this kind of entry point.

Is there any way in .NET (via configuration or otherwise) that I can tell the system not to reuse existing copies of my process? This issue only seems to occur on Windows XP, and not Vista or 7.

A copy of the code is below:

internal static bool EnsureAssociation()
{
    // Check to make sure RoketPack is associated.
    if (!Protocol.IsAssociated())
    {
        ProcessStartInfo info = new ProcessStartInfo();
        info.FileName = UNC.UniversalApplicationPath;
        info.UseShellExecute = true;
        if (!UAC.IsAdmin())
            info.Verb = "runas"; // Provides Run as Administrator
        info.Arguments = "--associate";
        Process proc = null;
        try
        {
            proc = Process.Start(info);
        }
        catch (Win32Exception)
        {
            Errors.Raise(Errors.ErrorType.ERROR_CAN_NOT_ASSOCIATE_PROTOCOL);
            return false;
        }

        if (null != proc)
        {
            // Wait until the association is complete.
            proc.WaitForExit();
            return Protocol.IsAssociated();
        }
        else
        {
            Errors.Raise(Errors.ErrorType.ERROR_CAN_NOT_ASSOCIATE_PROTOCOL);
            return false;
        }
    }
    else
        return true;
}
A: 

I solved this by checking to see if UAC.IsAdmin() is true, and if it is, simply perform the actions that the elevated process would have performed.

This doesn't directly solve the issue of Process.Start() returning null, but I think that the re-use situation is caused because the process that would have been started is identical in every way (where as if the process is started elevated via the 'runas' verb, it's considered different and will not return null).

Hach-Que
A: 

What you want to do is the default behaviour, i.e., any program can run multiple instances. Preventing the application from running more than once would require additional code.

Looking in Reflector at Process.Start()

public static Process Start(ProcessStartInfo startInfo)
{
    Process process = new Process();
    if (startInfo == null)
    {
        throw new ArgumentNullException("startInfo");
    }
    process.StartInfo = startInfo;
    if (process.Start())
    {
        return process;
    }
    return null;
}

You can trace where is returning null. It will return null if the process fails to start inside of process.Start().

public bool Start()
{
    this.Close();
    ProcessStartInfo startInfo = this.StartInfo;
    if (startInfo.FileName.Length == 0)
    {
        throw new InvalidOperationException(SR.GetString("FileNameMissing"));
    }
    if (startInfo.UseShellExecute)
    {
        return this.StartWithShellExecuteEx(startInfo);
    }
    return this.StartWithCreateProcess(startInfo);
}

...

You get the idea. Continue to trace why you are getting a null value. If you haven't got a copy of Reflector, GET IT NOW!

NB: Apologies that this does not give you the exact solution to your problem, however it shows you can go about finding it yourself. :)

HTH,

Dennis Roche