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)


arrow_upward
0
arrow_downward

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

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

person Hach-Que    schedule 18.10.2010

arrow_upward
0
arrow_downward

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

Глядя в 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