且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

.NET 模拟 Ctrl+Alt+Del 发送键

更新时间:2023-12-02 23:36:40

我终于找到了此 C++ 代码 在 CodeProject 上,当作为 启动时运行良好系统用户.因此,我将代码转换为 dll,并从我的代码中调用该函数.

I finally found this C++ code on CodeProject, which works well when launched as System user. Therefore, I converted the code into a dll, and called the function from my code.

这是 C++ 代码(您可以使用 ErrorExit 示例函数,该函数使用 MSDN 中的 GetLastError,以防出现问题):

Here is the c++ code (you can use the ErrorExit example function that uses GetLastError from MSDN in case a problem occured):

#include "windows.h"
#include <strsafe.h>

__declspec(dllexport) BOOL SimulateAltControlDel()
{
    HDESK   hdeskCurrent;
    HDESK   hdesk;
    HWINSTA hwinstaCurrent;
    HWINSTA hwinsta;

    // 
    // Save the current Window station
    // 
    hwinstaCurrent = GetProcessWindowStation();
    if (hwinstaCurrent == NULL)
        return FALSE;
    // 
    // Save the current desktop
    // 
    hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
    if (hdeskCurrent == NULL)
        return FALSE;
    // 
    // Obtain a handle to WinSta0 - service must be running
    // in the LocalSystem account
    // 
    hwinsta = OpenWindowStation("winsta0", FALSE,
                              WINSTA_ACCESSCLIPBOARD   |
                              WINSTA_ACCESSGLOBALATOMS |
                              WINSTA_CREATEDESKTOP     |
                              WINSTA_ENUMDESKTOPS      |
                              WINSTA_ENUMERATE         |
                              WINSTA_EXITWINDOWS       |
                              WINSTA_READATTRIBUTES    |
                              WINSTA_READSCREEN        |
                              WINSTA_WRITEATTRIBUTES);
    if (hwinsta == NULL)
        return FALSE;
    // 
    // Set the windowstation to be winsta0
    // 

    if (!SetProcessWindowStation(hwinsta))
     return FALSE;

    // 
    // Get the default desktop on winsta0
    // 
    hdesk = OpenDesktop("Winlogon", 0, FALSE,
                        DESKTOP_CREATEMENU |
              DESKTOP_CREATEWINDOW |
                        DESKTOP_ENUMERATE    |
                        DESKTOP_HOOKCONTROL  |
                        DESKTOP_JOURNALPLAYBACK |
                        DESKTOP_JOURNALRECORD |
                        DESKTOP_READOBJECTS |
                        DESKTOP_SWITCHDESKTOP |
                        DESKTOP_WRITEOBJECTS);
    if (hdesk == NULL)
       return FALSE;

    // 
    // Set the desktop to be "default"
    // 
    if (!SetThreadDesktop(hdesk))
       return FALSE;

    PostMessage(HWND_BROADCAST,WM_HOTKEY,0,MAKELPARAM(MOD_ALT|MOD_CONTROL,VK_DELETE));


    // 
    // Reset the Window station and desktop
    // 
    if (!SetProcessWindowStation(hwinstaCurrent))
       return FALSE;

    if (!SetThreadDesktop(hdeskCurrent))
    return FALSE;

    // 
    // Close the windowstation and desktop handles
    // 
    if (!CloseWindowStation(hwinsta))
        return FALSE;
    if (!CloseDesktop(hdesk))
        return FALSE;
    return TRUE;
}

你还需要在项目中添加一个.def文件才能正确导出函数(项目名为AltCtrlDelCpp)并告诉链接器模块的定义文件就是这个文件

You also need to add a .def file to the project to export the function correctly (the project is named AltCtrlDelCpp) and tell the linker that the definition file of the module is this file

;altctrldel.def
LIBRARY AltCtrlDelCpp

;CODE PRELOAD MOVEABLE DISCARDABLE
;DATA PRELOAD MOVEABLE

EXPORTS
   SimulateAltControlDel

然后,在 .NET 解决方案中,您将 dll 添加到项目中,对其进行配置,使其始终复制到输出目录中,您只需使用 DllImport 导入函数:

Then, in the .NET solution, you add the dll to the project, configures it so that it is always copied in the output directory, and you just use DllImport to import the function:

C# 代码

[DllImport(@"AltCtrlDelCpp.dll")]
static extern bool SimulateAltControlDel();

VB.NET 代码

<DllImport("AltCtrlDelCpp.dll")> _
Private Function SimulateAltControlDel() As Boolean

在VB.NET中,还需要在Sub Main中添加属性:

In VB.NET, you also need to add the attribute to the Sub Main :

<MTAThread()> _
Sub Main()

然后您只需调用 SimulateAltControlDel 函数即可.请注意,我只对 控制台应用程序 进行了这项工作,它在 winform 应用程序中不起作用.

Then you just have to call the SimulateAltControlDel function and there you go. Please note that I had this work only for a Console Apps, it didn't work in winform apps.