Mer*_*ham 10 ide console-application visual-studio visual-studio-debugging
在Visual Studio中运行控制台应用程序时,根据您的设置,它将在程序退出后添加提示:
按任意键继续 ...
我已经找到了如何检测我是否在调试器(使用Debugger.IsAttached)下运行,但它没有帮助.按CTRL-F5以不开始调试设置该标志false,但仍显示提示.
我想检测这个,因为我想显示我自己的消息并等待按键,但不要加倍按键检查.
我不想破坏我的一般Visual Studio设置.如果我可以以可以检查到源代码管理的方式为此项目禁用它,那也可以.
使用什么机制来附加此提示,以及如何检测它?
或者如何为每个项目禁用它,并将此更改检查为源代码管理?
将以下代码添加到控制台应用程序:
public static class Extensions {
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern bool TerminateThread(IntPtr hThread, uint dwExitCode);
public static Process GetParentProcess(this Process x) {
return (
from it in (new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_Process")).Get().Cast<ManagementObject>()
where (uint)it["ProcessId"]==x.Id
select Process.GetProcessById((int)(uint)it["ParentProcessId"])
).First();
}
public static IEnumerable<Process> GetChildProcesses(this Process x) {
return (
from it in (new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_Process")).Get().Cast<ManagementObject>()
where (uint)it["ParentProcessId"]==x.Id
select Process.GetProcessById((int)(uint)it["ProcessId"])
);
}
public static void Abort(this ProcessThread x) {
TerminateThread(OpenThread(1, false, (uint)x.Id), 1);
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样修改你的代码:
class Program {
static void Main(String[] args) {
// ... (your code might goes here)
try {
Process.GetCurrentProcess().GetParentProcess().Threads.Cast<ProcessThread>().Single().Abort();
}
catch(InvalidOperationException) {
}
Console.Write("Press ONLY key to continue . . . ");
Console.ReadKey(true);
}
}
Run Code Online (Sandbox Code Playgroud)
所以,我们所期待的一切都已经完成了.我认为这是一种解决方案.它可以工作Windows XP SP3,我猜它可以用于较新的Windows操作系统.在Visual Studio下,应用程序始终是一个衍生过程.在较旧的Visual C++ 6.0中,它由IDE通过调用生成VCSPAWN.EXE; 在Visual Studio 2010中,应用程序在启动时不使用调试时使用以下命令行运行:
"%comspec%"/ c""您的应用程序文件名"&pause"
因此,无法以完全管理的方式实现目标; 因为它不在应用程序域下.
这里我们使用托管的方式WMI来枚举进程,并封装非托管的WINAPIs以终止ProcessThreads,因为ProcessThread它不应该被正常中止; 它提供了像只读的东西.
如上所述,应用程序是使用特定的命令行生成的; 它会有一个线程创建一个进程签名,所以我们使用该Single()方法来检索该线程并终止它.
当我们在现有命令提示符下启动应用程序时,它与Start Without Debugging相同.而且,当启动调试时,应用程序进程由创建devenv.exe.它有很多线程,我们知道并且不会中止任何线程,只是提示并等待按键.这种情况类似于双击启动应用程序或从上下文菜单启动应用程序.这样,应用程序进程通常由系统shell创建Explorer.exe,它也有很多线程.
实际上,如果我们可以成功中止线程,则意味着我们有权杀死父进程.但是,我们不要需要.我们只需要中止唯一的线程,当系统没有更多线程时,进程会自动终止.通过识别调用进程来杀死父进程%comspec%是另一种做同样事情的方法,但这是一个危险的过程.因为生成应用程序的进程可能具有其他线程,这些线程具有任意数量的线程,所以创建进程匹配%comspec%.你可能会粗心地杀死一个重要的过程工作,或者只是增加检查过程是否可以安全杀死的复杂性.所以我认为单个线程创建一个进程作为我们父进程的签名,可以安全地终止/中止.
WMI是现代的,有些WINAPI可能会在未来被弃用.但这种构成的真正原因在于它的简单性.老Tool Help Library就是这样复杂的像转换的方式ProcessThread来System.Threading.Thread.使用LINQ和扩展方法,我们可以使代码更简单,更具语义.
| 归档时间: |
|
| 查看次数: |
2959 次 |
| 最近记录: |