首页

如果清理代码执行失败了,要怎么办?  

有一位读者 Matt 问了我这样一个问题; 如果我有一些清理资源的代码,例如关闭文件 fclose,或者关闭句柄 CloseHandle,当这些代码执行失败时,应该怎么做最为合适? 很显然,我们可能啥也做不了,请思考:如果清理代码都执行失败了,说明应用程序甚至操作系统已经遇到了严重的问题。 这些清理功能属于”不得因程序无法控制的原因而失败”的类别。 如果一个程序试图调用 f...

一天一个小技巧:善用 WM_NCDESTROY 消息  

某天,一个客户请求我的帮助,他们直接发送了下面的调用堆栈: 有了这个,事儿就好办了。如果你明白窗口销毁的过程,则你应该能明白程序异常的原因。 主要问题在于,树控件(TreeView Control)尝试使用一个已经不再有效的图像列表(Image List),它不再有效的原因可能是它已经被销毁了。 如果我们再次深入研究下这个调用堆栈,则你会发现:树控件自己也正在被销毁。 你可以从名称为 TV_De...

非注意盲视:人们容易看不到眼前显而易见的东西  

某天,我收到这样一条 Bug 报告: “当我进入控制面板中的电源管理,然后点击编辑电源计划,我发现,”关闭显示器”下拉框是灰色的,看起来被禁用了,这是一个 Bug 吗?” 我是这样回复他的: “在关闭显示器的上方,你是否看到有一条醒目的提示信息,上面写到’某些设置由系统管理员进行管理’,然后旁边还有一个链接,写着&...

死锁调试技巧:工作线程和用户界面线程  

有人碰到了一个死锁问题,找到我们想请我们看看,这个是关于应用程序用户界面相关的死锁问题。 我也不清楚他为什么会找上我们,可能是因为我们经常会和窗口管理器打交道吧。 下面,我们来看看死锁的两个线程。 调试死锁的问题在于,你通常不太需要了解具体的技术细节。一旦你踏入大门,诊断在很大程度上是机械化的。(尽管有时很难踏入大门。) 让我们先看看线程 0。 它正在等待一个临界区。该临界区的所有者是线程 1...

低优先级线程可能会使用 100% CPU  

经常会有人问我这样的问题: 我将一个线程设置为低优先级,当我的应用程序运行起来之后,我在任务管理器中看到应用程序占满了接近 100% 的 CPU,这就有点奇怪了,难道低优先级设定没有起作用? 我想指出的是,将一个线程设置为低优先级,并不意味着它不会占用很多 CPU,它实际的含义是:只要系统中还有其他高优先级线程,则它不会得到机会运行。 但是,如果当前系统没有其他高优先线程,而 CPU 又想找点事情...

说说以管理员身份执行的命令行的细节  

日日夜夜搞程序的你,是否注意到这样一个细节? 当我们在资源管理器中的某个文件夹里以管理员身份启动命令行的时候,你会发现:启动的命令行的初始文件夹会被忽略,命令行初始文件夹始终被设置为系统文件夹(system32),这是为什么? 问题答案:为了规避某些类型的攻击(所谓的”当前文件夹攻击”),下面细说。 根据动态链接库的搜索顺序规则,在步骤 5 中,在可执行文件夹和各种系统定义...

Visual Studio 对 C++ 头文件和模块的支持  

在 C++ 编程领域,头文件和模块的管理有时候确实比较令人头疼。但是,有许多工具和功能可以简化此过程,提高效率并减少出错的可能性。下面是我们为 C++ 头文件和模块提供的几种工具的介绍。 构建明细 通过菜单栏 Build > Run Build Insights,可以打开构建明细窗口。 此工具提供对“包含文件”和“包含树”视图的见解,以分析和优化 #include 使用情况。 例如,在 b...

为什么资源管理器里不显示文件夹大小?  

如果你好好看看电脑的资源管理器,你会发现:资源管理器中的文件不会显示其大小,而仅仅显示了文件的大小。 问题来了:为什么不可以在资源管理器中显示文件夹的大小呢?这不是一项很方便的功能吗? 如果你看过我之前的一篇关于计算机网络中不会自动探测所有主机的文章的话,则原因你可能已经猜到了。 这样做会使公司的内部网络崩溃,此话怎讲? 我们假设这样一个场景,在一个公司内部网络中,有一个大型的文件服务器,如果现在...

请勿假设你的用户都有管理员权限  

有些人觉得自己很聪明,他们在程序中做了这样一项”优化”。 在程序的安装阶段,他们不会安装某些程序功能,而是等到用户第一次使用的时候才执行,也即所谓的 “按需加载”。 问题在于,第一次使用的时候,用户可能没有管理员权限,而安装阶段一般都要求管理员权限。 举个例子,有一个流行的多媒体软件,用户在第一次使用的时候,才会安装 CD AutoPlay 处理器,...

传递一个比实际字符串大的缓冲区长度会怎么样?  

如果你在 Win32 的世界摸爬滚打过几年,则你会发现:很多函数如果要传入一个源字符串,则通常会有两个参数,一个是字符串缓冲区指针,另一个是字符串缓冲区长度。 如果传递的缓冲区长度,大于实际的字符串长度,则结果和函数的内部实现相关。 一些函数在给定字符串和长度时,会在长度用尽或者遇到空终止符时停止,以先到者为准。 举个例子,我们看一下 StringCchCopyN 的函数原型: STRSAFEAP...