C # Use the Service Startup form (add the form to the service) to implement user interaction for Windows Services [forwarding]

Source: Internet
Author: User

For personal needs, I want to find a keyboard record program. I have downloaded a lot from the Internet and most of them need to be registered. In addition, I am also killed by the software. So I decided to write one by myself. If I was a Windows application, I could capture the keyboard records. One of the methods to implement startup with the system is to serve as a Windows service. Writing code directly to the service does not capture keyboard records, you can read the information and view the msdn Information on the Internet:

Windows service applications run in a window area different from the login user's interaction area. The window area is a security object that contains the clipboard, a group of global atoms, and a group of desktop objects. Because the Windows Service region is not an Interactive region, the dialog box raised in the Windows service application is invisible and may cause the program to stop responding. Similarly, the error information should be recorded in the Windows event log, rather than in the user interface.

Generally, a service program uses a LocalSystem account with its own window station and default desktop. This window station cannot interact with users. That is to say, you cannot display a window on it, it does not accept users' mouse or keyboard input.

After logging on with a user account, the desktop we see is the default (desktop) under winsta0 (window station ).
Winsta0 has three desktops:
Winlogon: in the form of a logondialog box. When a user crashes, winlogon.exe switches to the default desktop.
Default: This is where the window of assumer.exe and all user programs appears, that is, what we usually see in Windows. The application runs on this desktop.
Screen Saver: runs the screen saver desktop when the system is idle.

Select a service in "Computer Management", modify attributes, and select "allow service to interact with the desktop" on the "Log on" tab ", this Service uses the default (desktop) in winsta0 (window station ). then you can interact with your service. In this case, you can obtain the default desktop bitmap, because the thread desktop is the default under winsta0. To obtain the Winlogon desktop bitmap at the same time, set the thread desktop to Winlogon.

This part of the code is published as follows:

// Service1.designer. CS File

Using system. Threading;

Namespace keyboard
{
Partial class service1
{
/// <Summary>
/// Required designer variables.
/// </Summary>
Private system. componentmodel. icontainer components = NULL;
Thread threadform = NULL;

/// <Summary>
/// Clear all resources in use.
/// </Summary>
/// <Param name = "disposing"> If the managed resource should be released, the value is true; otherwise, the value is false. </Param>
Protected override void dispose (bool disposing)
{
If (disposing & (components! = NULL ))
{
Components. Dispose ();
}
Base. Dispose (disposing );
}

# Code generated by the region component designer

/// <Summary>
/// The designer supports the required methods-do not
/// Use the code editor to modify the content of this method.
/// </Summary>
Private void initializecomponent ()
{
//
// Service1
//
This. servicename = "service1 ";

}

# Endregion

}
}

// Service1.cs File

Using system;
Using system. Collections. Generic;
Using system. componentmodel;
Using system. Data;
Using system. diagnostics;
Using system. serviceprocess;
Using system. text;
Using system. Threading;
Using system. runtime. interopservices;

Namespace keyboard
{
Public partial class service1: servicebase
{
Public service1 ()
{
Initializecomponent ();
}

Protected override void onstart (string [] ARGs)
{
Threadform = new thread (New threadstart (formshow ));
Threadform. Start ();
}

Protected override void onstop ()
{
If (threadform! = NULL)
{
If (threadform. isalive)
{
Threadform. Abort ();
Threadform = NULL;
}
}

}

Void formshow ()
{

Getasktopwindow ();
Intptr hwinstasave = getprocesswindowstation ();
Intptr dwthreadid = getcurrentthreadid ();
Intptr hsf-save = getthreaddesktop (dwthreadid );
Intptr hwinstauser = openwindowstation ("winsta0", false, 33554432 );
If (hwinstauser = intptr. Zero)
{
Rpcreverttoself ();
Return;
}
Setprocesswindowstation (hwinstauser );
Intptr hsf-user = opendesktop ("default", 0, false, 33554432 );
Rpcreverttoself ();
If (hsf-user = intptr. Zero)
{
Setprocesswindowstation (hwinstasave );
Closewindowstation (hwinstauser );
Return;
}
Setthreaddesktop (hsf-user );

Intptr dwguithreadid = dwthreadid;

Mousekeyboard F = new mousekeyboard (); // This form1 can contain policyicon, which can be displayed in the tray. You can click the tray icon to set it.
System. Windows. Forms. application. Run (f );

Dwguithreadid = intptr. zero;
Setthreaddesktop (hsf-save );
Setprocesswindowstation (hwinstasave );
Closedesktop (hsf-user );
Closewindowstation (hwinstauser );
}

[Dllimport ("user32.dll")]
Static extern int getasktopwindow ();

[Dllimport ("user32.dll")]
Static extern intptr getprocesswindowstation ();

[Dllimport ("kernel32.dll")]
Static extern intptr getcurrentthreadid ();

[Dllimport ("user32.dll")]
Static extern intptr getthreaddesktop (intptr dwthread );

[Dllimport ("user32.dll")]
Static extern intptr openwindowstation (string a, bool B, int C );

[Dllimport ("user32.dll")]
Static extern intptr opendesktop (string lpszdesktop, uint dwflags,
Bool finherit, uint dwdesiredaccess );

[Dllimport ("user32.dll")]
Static extern intptr closedesktop (intptr P );

[Dllimport ("rpcrt4.dll", setlasterror = true)]
Static extern intptr rpcimpersonateclient (int I );

[Dllimport ("rpcrt4.dll", setlasterror = true)]
Static extern intptr rpcreverttoself ();

[Dllimport ("user32.dll")]
Static extern intptr setthreaddesktop (intptr );

[Dllimport ("user32.dll")]
Static extern intptr setprocesswindowstation (intptr );
[Dllimport ("user32.dll")]
Static extern intptr closewindowstation (intptr );

}

}

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.