Обнаружение, если программа была запущена Visual Studio, в отличие от запуска из Windows Explorer - PullRequest
23 голосов
/ 27 августа 2009

Есть ли способ определить, была ли ваша программа загружена через Visual Studio, и была ли она запущена как отдельный исполняемый файл?

Наше программное обеспечение имеет функцию отчетов об ошибках для обработки необработанных исключений - нам нужно иметь возможность распространять отладочные сборки нашим бета-тестерам, но мы не хотим, чтобы отчет об ошибках сработал, когда мы находимся в середине разработки потому что исключения гораздо полезнее, если VS ловит их с полной трассировкой стека и т. д.

Прямо сейчас я отключаю отчет об ошибке, если Application.ExecutablePath включает bin \ Debug или bin \ Release, но я думаю, что, вероятно, есть более надежный способ определения, была ли программа загружена через VS.

Очевидно, мы могли бы создать другую сборку с некоторыми макросами препроцессора, но ради вопроса предположим, что это не возможно - я не против добавить код, но я пытаюсь сделать Наименьшее количество модификаций в процессе сборки, поэтому параметры командной строки также являются последним средством.

Если это имеет значение, я использую VS2003 / .NET 1.1.

Ответы [ 6 ]

46 голосов
/ 27 августа 2009

Если вы делаете это, чтобы определить, находится ли он в любом отладчике (пояснено @ JaredPar ), вы можете использовать Debugger.IsAttached обработчик исключений.

try
{
    // ...
}
catch(Exception ex)
{
    if (!Debugger.IsAttached)
    {
        ExceptionHandler.Frob(ex);
    }
    else
    {
        throw;
    }
}

В качестве альтернативы:

public static void Frob(Exception ex)
{
    if (Debugger.IsAttached)
    {
        Debugger.Break();
    }
}
3 голосов
/ 27 августа 2009

Рассматривали ли вы аргументы командной строки? Запустите программу из Visual Studio с флагом --no-exception-processing (или любым другим подходящим звуком) и не обрабатывайте исключения, если этот аргумент передается. Когда вы запустите программу в другом месте, без этого аргумента, она будет вести себя нормально.

2 голосов
/ 15 апреля 2018

Я знаю, что это старо, но предоставленные решения не очень удовлетворяют.

Вместо этого я использовал следующий класс:

using System.IO;
using System.Reflection;

public static class Program
{
    public static string ExecutablePath
    {
        get;
        private set;
    }

    static Program()
    {
        var assemblyPath = Assembly.GetEntryAssembly().Location;
        var assemblyDirectory = Path.GetDirectoryName(assemblyPath);

        if (assemblyDirectory.EndsWith(@"\Debug") || assemblyDirectory.EndsWith(@"\Release"))
        {
            string projectFile = Path.GetFileNameWithoutExtension(assemblyPath) + ".csproj";

            var root = new DirectoryInfo(assemblyDirectory);

            while (root.Parent != null)
            {
                if (File.Exists(Path.Combine(root.FullName, projectFile)))
                    break;

                root = root.Parent;

                if (root.Parent == null) // we could not find it (should not happen)
                    ExecutablePath = assemblyDirectory;
            }

            ExecutablePath = root.FullName;
        }
        else
        {
            ExecutablePath = assemblyDirectory;
        }
    }
}

Тогда вы можете просто использовать Program.ExecutablePath. Если у вас уже есть класс с именем Program, вы можете просто расширить его с помощью этих свойств и методов.

При запуске из Visual Studio он даст вам путь к проекту, в котором находится файл csproj. Это путь к исполняемому файлу без содержимого «bin \ * \ Debug» или «bin \ * \ Release».

Если он не запущен из Visual Studio, он укажет путь к исполняемому файлу.

Решение не зависит от настроек отладки, других подключенных отладчиков или конфигураций сборки. Единственное, что важно, чтобы ваши конфигурации назывались «Release» и «Debug».

Примечание: Как упомянул в комментариях Трой Джиззи, это решение работает, только если вы запускаете исполняемый файл из другого каталога, а не из выходного каталога. Для моего варианта использования (смоделируйте структуру каталогов развертывания с корневым каталогом проекта), это подходящее решение. Обычно я копирую свой исполняемый файл позже в каталог развертывания и ожидаю того же поведения, как если бы я запускал свою программу из Visual Studio. В моем случае содержимое и другие зависимости расположены относительно каталога проекта.

2 голосов
/ 27 августа 2009

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

1 голос
/ 27 августа 2009

Вместо отслеживания по дереву процессов я бы добавил флаг конфигурации, который включает функцию отчетов. Флаг всегда может быть установлен по умолчанию на «true», если только вы не находитесь в своей среде DEV, тогда вы устанавливаете его на «false».

0 голосов
/ 27 февраля 2019

Иногда приложение запускается вне отладчика, а отладчик подключается позже. (Дважды щелкните файл, которому назначено приложение ...) Я использую этот код для ожидания присоединения отладчика.

using System.Diagnostics;

Process[] procName = Process.GetProcessesByName("devenv");

if(procName.Length > 0)
  MessageBox.Show("Wait for debugger attach");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...