Process.Start() возвращает null в собственном процессе

Я использую Process.Start() для инициализации копии запущенного в данный момент приложения с повышенными правами. К сожалению, Process.Start() возвращает null, потому что считает, что использует существующий процесс моего приложения, и, хотя процесс существует, он не указывает какой-либо способ обработки точки входа такого типа.

Есть ли способ в .NET (с помощью конфигурации или иным образом), чтобы я мог запретить системе повторно использовать существующие копии моего процесса? Эта проблема возникает только в Windows XP, а не в Vista или 7.

Копия кода ниже:

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;
}

person Hach-Que    schedule 18.10.2010    source источник


Ответы (2)


Я решил эту проблему, проверив, является ли UAC.IsAdmin() истинным, и если это так, просто выполните действия, которые выполнял бы процесс с повышенными правами.

Это не решает напрямую проблему возврата Process.Start() null, но я думаю, что ситуация повторного использования вызвана тем, что процесс, который был бы запущен, идентичен во всех отношениях (где, как если бы процесс был запущен с повышенным уровнем через глагол runas, он считается другим и не возвращает null).

person Hach-Que    schedule 18.10.2010

То, что вы хотите сделать, это поведение по умолчанию, то есть любая программа может запускать несколько экземпляров. Чтобы предотвратить запуск приложения более одного раза, потребуется дополнительный код.

Глядя в Reflector на 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;
}

Вы можете проследить, где возвращается null. Он вернет null, если процесс не запустится внутри 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);
}

...

Вы поняли идею. Продолжайте отслеживать, почему вы получаете значение null. Если у вас нет копии Reflector, ПОЛУЧИТЕ ЕЕ СЕЙЧАС!

NB: приносим свои извинения за то, что это не дает вам точное решение вашей проблемы, однако показывает, что вы можете найти его самостоятельно. :)

ХТХ,

person Dennis    schedule 18.10.2010