在Delphi的Windows 7登录屏幕 [英] Windows 7 logon screensaver in Delphi

查看:239
本文介绍了在Delphi的Windows 7登录屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆