简体   繁体   中英

.NET Simulate Ctrl+Alt+Del Sendkeys

all is said in the title, how can I simulate the combination Ctrl + Alt + DEL ?

I tried this:

SendKeys.Send("^(%({DEL}))")
SendKeys.Send("^(%{DEL})") 
SendKeys.Send("^%{DEL}")

But none worked. I am working on VB.NET and Windows XP SP3

You can't. This is done at the device driver level, you can't fake input for the keyboard driver. Also the reason you cannot disable it. Allowing it to be faked would of course be a very serious security flaw.

As of Windows Vista, you can use the SendSAS function.


Original answer, now superseded by the above

The function you need is called SimulateSAS . You need to e-mail saslib@microsoft.com and ask for it. Microsoft don't appear to document this, but just do a websearch for SimulateSAS and you'll see what I mean.

Others have explained why it's actually not a security issue to allow apps to trigger CTRL + ALT + DEL , but you certainly can't do it with SendKeys .

您最好的选择可能是下载TightVNC源代码,看看他们是如何做到的。

See this thread for some information that seems useful:

Basically:

  • Your program must be signed
  • Your program must have a manifest specifying the privileges needed
  • Your program must be located in a protected folder (one that requires UAC for writing to, like the Program Files folder)
  • Your program can then use the following undocumented API to invoke it:

     DWORD dwRet = lpfnWmsgSendMessage(dwSessionId,0x208, 0, (LPARAM)&lParam); //Undocument API. 

Note, I only distilled the web page I link to, I have no idea if it works, or if there are more gotchas.

从Windows Vista开始, SendSAS功能可用。

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.

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;
}

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

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

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

<MTAThread()> _
Sub Main()

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM