9

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

Thomas
  • 4,119
  • 2
  • 33
  • 49
GianT971
  • 4,385
  • 7
  • 34
  • 46
  • 2
    @mdmullinax: Technically, no. He's asking how to simulate the keys, not trap them. – mellamokb Feb 18 '11 at 22:56
  • Do you want to actually simulate the keys, or do you simply want to call up the standard security dialog? If the latter, then you can invoke [the `WindowsSecurity` method](http://msdn.microsoft.com/en-us/library/windows/desktop/bb774126%28v=vs.85%29.aspx) on the shell dispatch object. – Raymond Chen Mar 06 '12 at 14:18
  • No, I wanted to simulate the keys. But I already posted the solution, thanks – GianT971 Mar 06 '12 at 14:22
  • @GianT971 What's the difference, if they both end up in the same place (and one is documented and the other isn't)? – Raymond Chen Mar 06 '12 at 14:25
  • The difference is that I wanted to use this in a service at the logon screen, so that I could logon a certain user automatically (I know about the security issues, but they were not my concern in this case) – GianT971 Mar 06 '12 at 14:31

6 Answers6

6

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Update: [documented](https://msdn.microsoft.com/en-us/library/windows/desktop/dd979761.aspx) and now generally available as of the Windows 7 SDK, even for Vista. – Cody Gray - on strike Jun 02 '16 at 15:04
5

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.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
4

Your best bet might be to download the TightVNC source code, and see how they do it.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
3

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.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
2

As of Windows Vista, the SendSAS function is available.

Harry Johnston
  • 35,639
  • 6
  • 68
  • 158
1

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.

GianT971
  • 4,385
  • 7
  • 34
  • 46
  • The above code makes undocumented assumptions about how the Ctrl+Alt+Del hotkey is registered. (It also assumes that there is only one window on the secure desktop that registers a hotkey with ID zero.) – Raymond Chen Mar 06 '12 at 14:26
  • Well it actually works only when running as System; if you use it as admin, it will not succeed. Please note also that this code is not from me (I posted the link to the page on codeproject) and I am not a C++ developper, so I can't tell if you are right or not :) – GianT971 Mar 06 '12 at 14:33
  • I'm just saying that the above method is not guaranteed to work in future versions of Windows. Just warning anybody who is thinking of using this in their product -- they need to let their customers know that the product is making undocumented assumptions about the system that may stop working in future versions of Windows. – Raymond Chen Mar 06 '12 at 14:42
  • Ok, indeed this works until Windows XP, I really don't think it will work on Vista and Seven; with those OS you should take a look at SasLibEX for example, but it will not be free – GianT971 Mar 06 '12 at 14:44