且构网

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

.NET模拟按Ctrl + Alt + Del键的SendKeys

更新时间:2023-12-02 23:32:10

我终于找到在$ C $的CProject这个C ++ code ,当为系统用户推出>效果很好。因此,我转换了code为DLL,并从我的code调用的函数。

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 ++ code(可以使用的 ErrorExit例如功能的使用 GetLastError函数从MSDN万一发生问题)

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#code

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

VB.NET code

<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.