在Delphi的Windows 7登录屏幕 [英] Windows 7 logon screensaver in Delphi
问题描述
我在使用Delphi应用程序与Windows 7的登录屏幕(适用于32位和64位Windows)有问题。甚至空白的应用程序(没有任何额外的code新建项目)抛出一个错误。
I'm having problems while using Delphi application as Windows 7 logon screensaver (for both 32-bit and 64-bit Windows). Even blank application (New Project without any extra code) throws an error.
德尔福7应用程序将引发内存不能为read错误和Delphi 2010应用程序抛出发生在应用程序中的未知软件异常,然后在运行时错误217。任何形式的初始化之前和异常处理程序的任何初始化之前发生此错误。
Delphi 7 application throws "The memory could not be read" error and Delphi 2010 application throws "The exception unknown software exception occurred in the application" and then "Runtime error 217". This error happens before any form initialization and before any initialization of exception handlers.
NOTEPAD.EXE设置为屏保登录工作正常。
Setting notepad.exe as logon screensaver works fine.
任何想法发生的事情吗?
Any ideas what goes on here?
推荐答案
正如我在我的评论说,这不是隐形code,只需code在一些单位的初始化部分是造成问题。我已经设法追查元凶(以及至少其中之一 - 有可能是其他人)。
As I said in my comment, it's not "invisible code", just code in the initialization section of some unit that's causing the problem. I've managed to track down the culprit (well at least one of them - there may be others).
当您使用表格
单元,它对类的依赖
单元。
When you use the Forms
unit, it has a dependency on the Classes
unit.
初始化部分调用 InitThreadSynchronization
,其中除其他事项外调用以下:
The initialization section calls InitThreadSynchronization
, which amongst other things calls the following:
SyncEvent := CreateEvent(nil, True, False, '');
if SyncEvent = 0 then
RaiseLastOSError;
从登录屏幕中调用时,它似乎API调用 CreateEvent
失败。不幸的是我不能确定是否在登录屏幕:(一)禁止 CreateEvent
共(b)项要求 CreateEventEx
代替或( C)将用适当的 lpEventAttributes
参数工作。我已经发布了一个更具体的问题,希望能够找出: CreateEvent从Windows 7登录屏幕
It seems the API call CreateEvent
fails when called from within the login screen. Unfortunately I'm unsure whether the login screen: (a) forbids CreateEvent
altogether (b) requires CreateEventEx
instead or (c) would work with an appropriate lpEventAttributes
argument. I've posted a more specific question to hopefully find out: CreateEvent from Windows-7 Logon Screen
您可以用下面的控制台应用程序验证问题:
You can verify the problem with the following console app:
program TestLoginScreensaver;
{$APPTYPE CONSOLE}
uses
Windows,
SysUtils;
var
SyncEvent: THandle;
begin
try
SyncEvent := CreateEvent(nil, True, False, '');
if SyncEvent = 0 then
RaiseLastOSError;
CloseHandle(SyncEvent); //So handle is closed if it was created (e.g. while logged in)
except
on E:Exception do
Writeln(E.Classname, ': ', E.Message);
end;
Readln;
end.
SyncEvent
的目的是使的TThread
实例同步回主线程。所以,如果你写一个单线程的应用程序,或者使用超过的TThread
其他的东西你的线程,你实际上并不需要/使用 SyncEvent
的。
The purpose of SyncEvent
is to enable TThread
instances to synchronise back to the main thread. So if you write a single threaded app, or create your threads using something other than TThread
, you don't actually need/use SyncEvent
at all.
SIDE-RANT :这是用在初始化部分问题的一个最好的例子。仅仅包括一个单元具有引入不必要的副作用的潜力。他们的晴无害的,但不是在这种情况下。现在你可能会说, Classes.pas
是臃肿的,我不会说。但问题是,如果初始化的类被称为明确从DPR,这个问题本来就容易识别和找到一个解决办法。
SIDE-RANT: This is a prime example of the problem with using the initialization section. Merely including a unit has the potential to introduce unnecessary side-effects. They're Mostly Harmless, but not in this case. Now you may argue that
Classes.pas
is bloated, and I won't argue. But the point is that if Classes initialization were called explicitly from the DPR, this problem would have been easier to identify and find a workaround for.
由于雷米勒博在我张贴的另一个问题指出。结果
该行:
New Solution
As Remy Lebeau noted in the other question I posted.
The line:
SyncEvent := CreateEvent(nil, True, False, '');
必须改成:
SyncEvent := CreateEvent(nil, True, False, nil);
由于该方案涉及重新编译VCL单位,可能要经过几个 previous问题,关于这个问题
以此为唯一的变化(在D2009编译)我能在登录屏幕上显示出成功的一个空白表单。但是,请记住,有些事情你可能通常希望能够做的将是关闭的限制,由于在登录屏幕的安全限制。
With this as the only change (compiled in D2009) I was able to successfully show a blank form at the Logon screen. However, bear in mind that some things you may normally expect to be able to do will be off limits due to the security restrictions at the Logon screen.
这篇关于在Delphi的Windows 7登录屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!