繁体   English   中英

检测程序是否由Visual Studio运行,而不是从Windows资源管理器运行

[英]Detecting if a program was run by Visual Studio, as opposed to run from Windows Explorer

有没有办法检测您的程序是否通过Visual Studio加载,而不是它是作为独立的可执行文件启动的?

我们的软件具有错误报告功能,可以处理未处理的异常 - 我们需要能够将调试版本分发给我们的beta测试人员,但是当我们处于开发阶段时,我们不希望错误报告发生,因为如果VS使用完整堆栈跟踪捕获它们,则异常会更有用。

现在,如果Application.ExecutablePath包含bin \\ Debug或bin \\ Release,我将禁用错误报告,但我认为可能有更强大的方法来检测程序是否通过VS加载。

显然,我们可以使用一些预处理器宏来设置不同的构建,但是为了这个问题,假设这不是一种可能性 - 我不介意添加代码,但我试图对其进行最少的修改构建过程,这就是为什么命令行选项也是最后的选择。

如果重要,我正在使用VS2003 / .NET 1.1。

如果你这样做是为了确定它是否在任何调试器中(由@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();
    }
}

你考虑过命令行参数吗? 使用--no-exception-handling标志(或任何合适的声音)从Visual Studio运行程序,如果传入该参数,则不处理异常。当你在其他地方启动程序时,如果没有这个参数,它将会表现正常。

我不做.net开发,但在java中我通过将标志传递给应用程序的启动选项来完成此操作。 因此,您可以从IDE将调试标志传递到应用程序,然后检查,当应用程序作为可执行文件运行时,标志将不存在。 如果.net没有类似的东西,我会感到惊讶。

我知道这已经过时了,但所提供的解决方案并不令人满意。

我改为使用以下类:

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”。

注意:正如Troy Gizzi在评论中提到的,此解决方案仅在从输出目录以外的其他目录运行可执行文件时才有效。 对于我的用例(模拟部署目录结构,项目目录为根目录),这是一个合适的解决方案。 一般情况下,我稍后将我的可执行文件复制到部署目录,并期望与从Visual Studio中运行我的程序一样的行为。 在我的案例中,内容和其他依赖项相对于项目目录而定。

我会添加一个启用报告功能的配置标志,而不是按进程树进行跟踪。 除非您在DEV环境中,否则该标志始终默认为“true”,然后将其设置为“false”。

有时,应用程序在调试器外部启动,调试器稍后会附加。 (双击应用程序分配给的文件...)我使用此代码等待调试器附加。

using System.Diagnostics;

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

if(procName.Length > 0)
  MessageBox.Show("Wait for debugger attach");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM