简体   繁体   English

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

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

Is there a way to detect if your program was loaded through Visual Studio vs. whether it was started as a standalone executable? 有没有办法检测您的程序是否通过Visual Studio加载,而不是它是作为独立的可执行文件启动的?

Our software has a bug reporting feature to handle unhandled exceptions -- we need to be able to distribute debug builds to our beta testers, but we don't want the bug report to go off when we are in the middle of development, because the Exceptions are a lot more useful if VS catches them with a full stack trace, etc. 我们的软件具有错误报告功能,可以处理未处理的异常 - 我们需要能够将调试版本分发给我们的beta测试人员,但是当我们处于开发阶段时,我们不希望错误报告发生,因为如果VS使用完整堆栈跟踪捕获它们,则异常会更有用。

Right now, I'm disabling the bug report if Application.ExecutablePath includes bin\\Debug or bin\\Release, but I figure there is probably a more robust way of detecting whether the program was loaded through VS. 现在,如果Application.ExecutablePath包含bin \\ Debug或bin \\ Release,我将禁用错误报告,但我认为可能有更强大的方法来检测程序是否通过VS加载。

Obviously, we could set up a different build with some preprocessor macros, but for the sake of the question, assume that isn't a possibility -- I don't mind adding code, but I'm trying to make the fewest modifications to the build process, which is why command-line options are kind of a last resort as well. 显然,我们可以使用一些预处理器宏来设置不同的构建,但是为了这个问题,假设这不是一种可能性 - 我不介意添加代码,但我试图对其进行最少的修改构建过程,这就是为什么命令行选项也是最后的选择。

If it matters, I'm using VS2003/.NET 1.1. 如果重要,我正在使用VS2003 / .NET 1.1。

If you're doing this to determine if it is in any debugger (clarified by @JaredPar ), you can use Debugger.IsAttached in the exception handler. 如果你这样做是为了确定它是否在任何调试器中(由@JaredPar澄清),你可以在异常处理程序中使用Debugger.IsAttached

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

Alternatively: 或者:

public static void Frob(Exception ex)
{
    if (Debugger.IsAttached)
    {
        Debugger.Break();
    }
}

Have you considered command line arguments? 你考虑过命令行参数吗? Run the program from Visual Studio with a --no-exception-handling flag (or whatever sounds appropriate), and don't handle exceptions if that argument is passed in. When you start the program elsewhere, without this argument, it'll behave normally. 使用--no-exception-handling标志(或任何合适的声音)从Visual Studio运行程序,如果传入该参数,则不处理异常。当你在其他地方启动程序时,如果没有这个参数,它将会表现正常。

I don't do .net development, but in java I have done this by passing a flag into the startup options of the application. 我不做.net开发,但在java中我通过将标志传递给应用程序的启动选项来完成此操作。 So you could pass a debug flag into the app from the IDE, and then check for that, when the app is run as an executable the flag would not be present. 因此,您可以从IDE将调试标志传递到应用程序,然后检查,当应用程序作为可执行文件运行时,标志将不存在。 I would be surprised if .net didn't have something similar. 如果.net没有类似的东西,我会感到惊讶。

I know this is old but the provided solutions are not very satisfying. 我知道这已经过时了,但所提供的解决方案并不令人满意。

I used the following class instead: 我改为使用以下类:

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

Then you can just use Program.ExecutablePath . 然后你可以使用Program.ExecutablePath If you already have a class named Program you can just extend it by those properties and methods. 如果您已经有一个名为Program的类,您可以通过这些属性和方法扩展它。

If running from Visual Studio it will give you the project path where the csproj-file resides. 如果从Visual Studio运行,它将为您提供csproj文件所在的项目路径。 This is the executable path without the "bin\\*\\Debug" or "bin\\*\\Release" stuff. 这是没有“bin \\ * \\ Debug”或“bin \\ * \\ Release”内容的可执行路径。

If not running from Visual Studio it will give you the path where the executable resides. 如果没有从Visual Studio运行,它将为您提供可执行文件所在的路径。

The solution is independent of debug settings, other attached debuggers or build configurations. 该解决方案独立于调试设置,其他附加调试器或构建配置。 The only important thing is, that your configurations are named "Release" and "Debug". 唯一重要的是,您的配置名为“Release”和“Debug”。

Note: As Troy Gizzi mentioned in the comments, this solution only works if you run the executable from another directory than the output directory. 注意:正如Troy Gizzi在评论中提到的,此解决方案仅在从输出目录以外的其他目录运行可执行文件时才有效。 For my use case (simulate the deployment directory structure with the project directory as the root directory), this is a suitable solution. 对于我的用例(模拟部署目录结构,项目目录为根目录),这是一个合适的解决方案。 In general I copy my executable later to the deployment directory and expect the same behavior as if I run my program from within Visual Studio. 一般情况下,我稍后将我的可执行文件复制到部署目录,并期望与从Visual Studio中运行我的程序一样的行为。 Content and other dependencies are located relative to the project directory in my case. 在我的案例中,内容和其他依赖项相对于项目目录而定。

Instead of tracking by process tree, I would add a configuration flag that enables the reporting feature. 我会添加一个启用报告功能的配置标志,而不是按进程树进行跟踪。 The flag can always default to "true" unless you are in your DEV environment then you set it to "false". 除非您在DEV环境中,否则该标志始终默认为“true”,然后将其设置为“false”。

Sometimes the application is started outside the debugger and the debugger gets attached later. 有时,应用程序在调试器外部启动,调试器稍后会附加。 (Doubleclick on a file where the application is assigned to ...) I use this code to wait for the debugger attach. (双击应用程序分配给的文件...)我使用此代码等待调试器附加。

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.

相关问题 如何从Windows C#(Visual Studio)运行cygwin编译的程序? - How do you run a cygwin-compiled program from windows c# (visual studio)? 我可以在没有提升权限的情况下从visual studio运行程序吗? - Can I run a program from visual studio without elevated permissions? 可以使用 Mono 运行程序,但不能使用 Visual Studio Mac - Can run program with Mono but not with Visual Studio Mac 从Windows服务运行程序 - Run program from windows service 是否可以在 Windows 上运行 Visual Studio for Mac 项目? - Is it possible to run a Visual Studio for Mac project on Windows? 测试资源管理器发现失败,除非在Visual Studio 2017中以管理员身份运行 - Test Explorer Discovery Fails Unless Run As Administrator in Visual Studio 2017 Visual Studio 测试资源管理器无法在已编译的测试项目中运行测试 - Visual Studio Test Explorer cannot run tests in compiled test project 如何在命令行中运行通常在Visual Studio测试资源管理器中运行的.cs测试? - How do I run .cs tests that I normally run in the Visual Studio Test Explorer, in the command line? 使用visual studio中的参数运行批处理 - run a batch with parameters from visual studio 如何从Visual Studio运行Grunt命令? - How to run Grunt command from Visual Studio?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM