GDI +窗口防止关机

时间:2014-05-13 17:51:36

标签: c# gdi+ windows-server-2003

我正在为使用C#和.NET Framework 2.0的Server 2003进行开发

只要程序运行,我就无法关闭我的机器。没有任何事情发生,但当alt + tabbing我可以看到一个名为“GDI + Window”的窗口。一旦我关闭程序,我就可以正常关闭计算机。

但是,在我的其他计算机(Windows XP专业版,Windows 8,Windows 8.1)上,它不会发生。

程序从数据库中提取数据并将它们发送到互联网,因此我在后台运行了一个Thread。这可能是个问题吗?

主类中的代码如下:

public partial class Form1 : Form
{
    bool run = true;
    //AutoStart autoS = new AutoStart();
    int interval;
    //LogFileBuilder lfboom = new LogFileBuilder(true);*/

    public Form1()
    {
        InitializeComponent();
        /*OpenOnce();
        //autoS.EintragHinzufügen();
        WriteMe();
        LogFileBuilder lfb = new LogFileBuilder();
        lfb.writeLine("Programm gestartet");
        new Thread(Durchführung).Start();*/
    }
}

当然,表单中还有其他方法和事件处理程序,但它们不相关,因为在重现此问题时不会调用它们。正如您所看到的,除了InitializeComponents()之外,我已经注释掉了我的整个代码,但问题仍然存在。

复制步骤:
1.打开程序
2.关闭服务器
3.没有任何反应,除了alt +标签列表中的新“GDI + Window”,它不可打开

1 个答案:

答案 0 :(得分:1)

Cody Gray所示,当GDI +子系统初始化然后保持前景窗口时,存在已知条件。 KB article 943453中提供的解决方案是在主窗体加载后显式设置前景窗口,如下所示:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    //using System.Runtime.InteropServices;
    // tell the runtime to use the user32.dll for implementation of the next method
    [DllImport("user32.dll")]
    // what is returned by this method
    [return: MarshalAs(UnmanagedType.Bool)]
    // the methed to call in User32
    // upper/lower case is important
    static extern bool SetForegroundWindow(IntPtr hWnd);

    private void Form1_Load(object sender, EventArgs e)
    {
        SetForegroundWindow(this.Handle);
    }
} 

在您声称尝试过的评论中,但遇到了类型加载异常:

  

System.TypeLoadException未处理   消息:mscorlib.dll中发生了未处理的“System.TypeLoadException”类型异常   附加信息:无法从程序集'App,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'加载类型'App.Form1',因为方法'SetForegroundWindow'没有实现(没有RVA)。

这是因为SetForegroundwindow没有应用[Dllimport]属性。我可以通过使用[Dllimport]注释该行来重现该异常。没有它你的代码将编译,但因为方法SetForegroundWindow将没有任何实现,运行时拒绝加载您的类型,因此异常。

在技术意义上,RVA代表相对虚拟地址,是模块基址的偏移量。查找项目RVA并将其添加到baseaddress将返回项目(方法,数据等)启动指针。如果没有要查找的内容,因为无法执行任何操作,则无法安全地执行该模块。有关更多背景信息,请参阅https://msdn.microsoft.com/en-us/library/ms809762.aspx

总而言之,下面的代码叫做

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

将执行this unmanaged method in the WinAPI