├── Images
├── Browser.png
├── OpenScreenApp.png
└── OpenScreenIcon.ico
├── OpenScreen
├── favicon.ico
├── Resources
│ └── favicon.ico
├── App.xaml
├── App.xaml.cs
├── Properties
│ ├── Settings.settings
│ ├── Settings.Designer.cs
│ ├── AssemblyInfo.cs
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── App.config
├── UiConstants.cs
├── OpenScreen.xaml
├── OpenScreen.csproj
└── OpenScreen.xaml.cs
├── OpenScreen.Core
├── Screenshot
│ ├── Fps.cs
│ ├── Resolution.cs
│ ├── WinFeatures
│ │ ├── ApplicationWindow.cs
│ │ ├── MouseCursor.cs
│ │ └── RunningApplications.cs
│ └── Screenshot.cs
├── Server
│ ├── ServerConfig.cs
│ ├── ServerSocketExtension.cs
│ └── StreamingServer.cs
├── Mjpeg
│ ├── MjpegConstants.cs
│ ├── MjpegStream.cs
│ └── MjpegWriter.cs
├── Properties
│ └── AssemblyInfo.cs
└── OpenScreen.Core.csproj
├── LICENSE
├── OpenScreen.sln
├── README.md
├── .gitignore
└── OpenScreen.Installer
└── OpenScreen.Installer.vdproj
/Images/Browser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrKonstantinSh/OpenScreen/HEAD/Images/Browser.png
--------------------------------------------------------------------------------
/OpenScreen/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrKonstantinSh/OpenScreen/HEAD/OpenScreen/favicon.ico
--------------------------------------------------------------------------------
/Images/OpenScreenApp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrKonstantinSh/OpenScreen/HEAD/Images/OpenScreenApp.png
--------------------------------------------------------------------------------
/Images/OpenScreenIcon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrKonstantinSh/OpenScreen/HEAD/Images/OpenScreenIcon.ico
--------------------------------------------------------------------------------
/OpenScreen/Resources/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MrKonstantinSh/OpenScreen/HEAD/OpenScreen/Resources/favicon.ico
--------------------------------------------------------------------------------
/OpenScreen/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/Fps.cs:
--------------------------------------------------------------------------------
1 | namespace OpenScreen.Core.Screenshot
2 | {
3 | ///
4 | /// Provides an enumeration of the possible number of frames per second.
5 | ///
6 | public enum Fps
7 | {
8 | OneHundredAndTwenty = 8,
9 | Sixty = 16,
10 | Thirty = 33,
11 | Fifteen = 66
12 | }
13 | }
--------------------------------------------------------------------------------
/OpenScreen/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace OpenScreen
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Server/ServerConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 |
3 | namespace OpenScreen.Core.Server
4 | {
5 | internal class ServerConfig
6 | {
7 | public IPAddress IpAddress { get; }
8 |
9 | public int Port { get; }
10 |
11 | public ServerConfig(IPAddress ipAddress, int port)
12 | {
13 | IpAddress = ipAddress;
14 | Port = port;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/OpenScreen/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 3030
10 |
11 |
12 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Server/ServerSocketExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Net.Sockets;
3 |
4 | namespace OpenScreen.Core.Server
5 | {
6 | ///
7 | /// Provides an enumerated connection in an enumerated form.
8 | ///
9 | internal static class ServerSocketExtension
10 | {
11 | ///
12 | /// Provides an enumerated connection in an enumerated form.
13 | ///
14 | /// Server socket.
15 | /// An enumerated connection in an enumerated form.
16 | public static IEnumerable GetIncomingConnections(this Socket server)
17 | {
18 | while (true)
19 | {
20 | yield return server.Accept();
21 | }
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/OpenScreen.Core/Mjpeg/MjpegConstants.cs:
--------------------------------------------------------------------------------
1 | namespace OpenScreen.Core.Mjpeg
2 | {
3 | ///
4 | /// Provides request and response headers.
5 | ///
6 | internal static class MjpegConstants
7 | {
8 | public const string ResponseHeaders =
9 | "HTTP/1.1 200 OK\nContent-Type: multipart/x-mixed-replace; boundary=--boundary\n";
10 | public const string NewLine = "\n";
11 |
12 | ///
13 | /// Provides headers with information about the transmitted images.
14 | ///
15 | /// The length of the transmitted content.
16 | /// A string of headers.
17 | public static string GetImageInfoHeaders(long contentLength)
18 | {
19 | return $"\n--boundary\nContent-Type: image/jpeg\nContent-Length: {contentLength}\n\n";
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/OpenScreen/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 3030
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Mjpeg/MjpegStream.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Drawing;
3 | using System.IO;
4 |
5 | namespace OpenScreen.Core.Mjpeg
6 | {
7 | ///
8 | /// Allows to work with the streams of images presented in MJPEG format.
9 | ///
10 | internal static class MjpegStream
11 | {
12 | ///
13 | /// Provides an enumerated streams of images represented in MJPEG format.
14 | ///
15 | /// Images to save to the streams.
16 | /// An enumerated streams of images represented in MJPEG format.
17 | internal static IEnumerable GetMjpegStream(this IEnumerable images)
18 | {
19 | using var memoryStream = new MemoryStream();
20 |
21 | foreach (var image in images)
22 | {
23 | memoryStream.SetLength(0);
24 | image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
25 |
26 | yield return memoryStream;
27 | }
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Konstantin Shulga
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle("OpenScreen.Core")]
8 | [assembly: AssemblyDescription("")]
9 | [assembly: AssemblyConfiguration("")]
10 | [assembly: AssemblyCompany("")]
11 | [assembly: AssemblyProduct("OpenScreen.Core")]
12 | [assembly: AssemblyCopyright("Copyright © 2020")]
13 | [assembly: AssemblyTrademark("")]
14 | [assembly: AssemblyCulture("")]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible(false)]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid("666657b0-cde6-4274-bd25-3e72a1fb87fb")]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | // You can specify all the values or you can default the Build and Revision Numbers
32 | // by using the '*' as shown below:
33 | // [assembly: AssemblyVersion("1.0.*")]
34 | [assembly: AssemblyVersion("1.0.0.0")]
35 | [assembly: AssemblyFileVersion("1.0.0.0")]
36 |
--------------------------------------------------------------------------------
/OpenScreen.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.30011.22
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenScreen.Core", "OpenScreen.Core\OpenScreen.Core.csproj", "{666657B0-CDE6-4274-BD25-3E72A1FB87FB}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenScreen", "OpenScreen\OpenScreen.csproj", "{B088B160-DBC1-484C-BEF7-62BF5F15BC98}"
9 | EndProject
10 | Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "OpenScreen.Installer", "OpenScreen.Installer\OpenScreen.Installer.vdproj", "{FB3B3370-2C47-424F-9001-2642A031B475}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {666657B0-CDE6-4274-BD25-3E72A1FB87FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {666657B0-CDE6-4274-BD25-3E72A1FB87FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {666657B0-CDE6-4274-BD25-3E72A1FB87FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {666657B0-CDE6-4274-BD25-3E72A1FB87FB}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {B088B160-DBC1-484C-BEF7-62BF5F15BC98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {B088B160-DBC1-484C-BEF7-62BF5F15BC98}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {B088B160-DBC1-484C-BEF7-62BF5F15BC98}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {B088B160-DBC1-484C-BEF7-62BF5F15BC98}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {FB3B3370-2C47-424F-9001-2642A031B475}.Debug|Any CPU.ActiveCfg = Debug
27 | {FB3B3370-2C47-424F-9001-2642A031B475}.Release|Any CPU.ActiveCfg = Release
28 | EndGlobalSection
29 | GlobalSection(SolutionProperties) = preSolution
30 | HideSolutionNode = FALSE
31 | EndGlobalSection
32 | GlobalSection(ExtensibilityGlobals) = postSolution
33 | SolutionGuid = {BAA0F3D7-7F65-4C59-B549-88765170BA85}
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/OpenScreen/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenScreen.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("")]
29 | public string IpAddress {
30 | get {
31 | return ((string)(this["IpAddress"]));
32 | }
33 | set {
34 | this["IpAddress"] = value;
35 | }
36 | }
37 |
38 | [global::System.Configuration.UserScopedSettingAttribute()]
39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
40 | [global::System.Configuration.DefaultSettingValueAttribute("3030")]
41 | public string Port {
42 | get {
43 | return ((string)(this["Port"]));
44 | }
45 | set {
46 | this["Port"] = value;
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Mjpeg/MjpegWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 |
5 | namespace OpenScreen.Core.Mjpeg
6 | {
7 | ///
8 | /// Provides a stream writer that can be used to write images as MJPEG
9 | /// to any stream.
10 | ///
11 | internal class MjpegWriter : IDisposable
12 | {
13 | private Stream _stream;
14 |
15 | ///
16 | /// The constructor of the class that initializes the fields of the class.
17 | ///
18 | public MjpegWriter(Stream stream)
19 | {
20 | _stream = stream;
21 | }
22 |
23 | ///
24 | /// Writes response headers to a stream.
25 | ///
26 | public void WriteHeaders()
27 | {
28 | var headers = Encoding.ASCII.GetBytes(MjpegConstants.ResponseHeaders);
29 |
30 | const int offset = 0;
31 | _stream.Write(headers, offset, headers.Length);
32 |
33 | _stream.Flush();
34 | }
35 |
36 | ///
37 | /// Writes an image to a stream.
38 | ///
39 | /// Stream of images.
40 | public void WriteImage(MemoryStream imageStream)
41 | {
42 | var headers = Encoding.ASCII.GetBytes(
43 | MjpegConstants.GetImageInfoHeaders(imageStream.Length));
44 |
45 | const int offset = 0;
46 | _stream.Write(headers, offset, headers.Length);
47 |
48 | imageStream.WriteTo(_stream);
49 |
50 | var endOfResponse = Encoding.ASCII.GetBytes(MjpegConstants.NewLine);
51 |
52 | _stream.Write(endOfResponse, offset, endOfResponse.Length);
53 |
54 | _stream.Flush();
55 | }
56 |
57 | ///
58 | /// The implementation of the IDisposable interface.
59 | ///
60 | public void Dispose()
61 | {
62 | try
63 | {
64 | _stream?.Dispose();
65 | }
66 | finally
67 | {
68 | _stream = null;
69 | }
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/OpenScreen/UiConstants.cs:
--------------------------------------------------------------------------------
1 | namespace OpenScreen
2 | {
3 | internal static class UiConstants
4 | {
5 | #region Connected users info
6 |
7 | public const string ConnectedUsersZero = "Connected users: 0";
8 | public const string ConnectedUsers = "Connected users: ";
9 |
10 | #endregion
11 |
12 | #region Start / stop button
13 |
14 | public const string StartStream = "Start stream";
15 | public const string StopStream = "Stop stream";
16 |
17 | #endregion
18 |
19 | #region Ignored apps
20 |
21 | public const string MicrosoftTextInputApp = "Microsoft Text Input Application";
22 |
23 | #endregion
24 |
25 | #region Errors
26 |
27 | public const string ErrorTitle = "Error";
28 | public const string PortOrIpErrorMessage = "Enter the correct port and IP address.";
29 | public const string IpAddressErrorMessage = "Enter the correct IP address.";
30 |
31 | #endregion
32 |
33 | #region Fps
34 |
35 | public const string OneHundredAndTwentyFps = "120 FPS";
36 | public const string SixtyFps = "60 FPS";
37 | public const string ThirtyFps = "30 FPS";
38 | public const string FifteenFps = "15 FPS";
39 |
40 | #endregion
41 |
42 | #region Resolutions
43 |
44 | public const string OneThousandAndEightyP = "1920x1080 (1080p)";
45 | public const string SevenHundredAndTwentyP = "1280x720 (720p)";
46 | public const string FourHundredAndEightyP = "854x480 (480p)";
47 | public const string ThreeHundredAndSixtyP = "480x360 (360p)";
48 | public const string TwoHundredAndFortyP = "352x240 (240p)";
49 |
50 | #endregion
51 |
52 | #region Server information
53 |
54 | public const string NewLine = "\n";
55 | public const string ServerConfiguration = "Server Configuration...\n";
56 | public const string StartingServer = "Starting the server...\n";
57 | public const string ServerIsStarted = "The server is started at the following address: ";
58 | public const string ServerStop = "Server Stop...\n";
59 | public const string ServerIsStopped = "The server is stopped.\n";
60 |
61 | #endregion
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/OpenScreen/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("OpenScreen")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("OpenScreen")]
15 | [assembly: AssemblyCopyright("Copyright © 2020")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/Resolution.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 |
4 | namespace OpenScreen.Core.Screenshot
5 | {
6 | ///
7 | /// Provides methods for working with image resolutions.
8 | ///
9 | public static class Resolution
10 | {
11 | #region Screen resolutions
12 |
13 | private const int OneThousandAndEightyPWidth = 1920;
14 | private const int OneThousandAndEightyPHeight = 1080;
15 |
16 | private const int SevenHundredAndTwentyPWidth = 1080;
17 | private const int SevenHundredAndTwentyPHeight = 720;
18 |
19 | private const int FourHundredAndEightyPWidth = 854;
20 | private const int FourHundredAndEightyPHeight = 480;
21 |
22 | private const int ThreeHundredAndSixtyPWidth = 480;
23 | private const int ThreeHundredAndSixtyPHeight = 360;
24 |
25 | private const int TwoHundredAndFortyPWidth = 352;
26 | private const int TwoHundredAndFortyPHeight = 240;
27 |
28 | #endregion
29 |
30 | ///
31 | /// Possible screen resolutions.
32 | ///
33 | public enum Resolutions
34 | {
35 | OneThousandAndEightyP,
36 | SevenHundredAndTwentyP,
37 | FourHundredAndEightyP,
38 | ThreeHundredAndSixtyP,
39 | TwoHundredAndFortyP
40 | }
41 |
42 | ///
43 | /// Provides width and height for the required screen resolution.
44 | ///
45 | /// The resolution of the screen whose size you need to know.
46 | /// Width and height of resolution.
47 | public static Size GetResolutionSize(Resolutions resolution)
48 | {
49 | return resolution switch
50 | {
51 | Resolutions.OneThousandAndEightyP => new Size(OneThousandAndEightyPWidth, OneThousandAndEightyPHeight),
52 | Resolutions.SevenHundredAndTwentyP => new Size(SevenHundredAndTwentyPWidth,
53 | SevenHundredAndTwentyPHeight),
54 | Resolutions.FourHundredAndEightyP => new Size(FourHundredAndEightyPWidth, FourHundredAndEightyPHeight),
55 | Resolutions.ThreeHundredAndSixtyP => new Size(ThreeHundredAndSixtyPWidth, ThreeHundredAndSixtyPHeight),
56 | Resolutions.TwoHundredAndFortyP => new Size(TwoHundredAndFortyPWidth, TwoHundredAndFortyPHeight),
57 | _ => throw new ArgumentOutOfRangeException(nameof(resolution), resolution, null)
58 | };
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/OpenScreen/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace OpenScreen.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OpenScreen.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/OpenScreen.Core/OpenScreen.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {666657B0-CDE6-4274-BD25-3E72A1FB87FB}
8 | Library
9 | Properties
10 | OpenScreen.Core
11 | OpenScreen.Core
12 | v4.7.2
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 | latest
25 |
26 |
27 | pdbonly
28 | true
29 | bin\Release\
30 | TRACE
31 | prompt
32 | 4
33 | latest
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/WinFeatures/ApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace OpenScreen.Core.Screenshot.WinFeatures
6 | {
7 | ///
8 | /// Provides methods for obtaining information about the application window.
9 | ///
10 | /// Details of the PrintWindow method:
11 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-printwindow
12 | ///
13 | /// Details of the GetWindowRect method:
14 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getwindowrect
15 | ///
16 | /// Details of the FindWindow method:
17 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-findwindowa
18 | ///
19 | internal static class ApplicationWindow
20 | {
21 | internal const uint DrawAllWindow = 0x0;
22 | internal const uint DrawClientOnly = 0x1;
23 |
24 | ///
25 | /// Copies a visual window into the specified device context (DC), typically a printer DC.
26 | ///
27 | /// A handle to the window that will be copied.
28 | /// A handle to the device context.
29 | /// The drawing options. It can be one of the following values.
30 | /// If the function succeeds, it returns a nonzero value.
31 | [DllImport("User32.dll", SetLastError = true)]
32 | [return: MarshalAs(UnmanagedType.Bool)]
33 | internal static extern bool PrintWindow(IntPtr handle, IntPtr deviceContextHandle, uint drawOption);
34 |
35 | ///
36 | /// Retrieves the dimensions of the bounding rectangle of the specified window.
37 | /// The dimensions are given in screen coordinates
38 | /// that are relative to the upper-left corner of the screen.
39 | ///
40 | /// A handle to the window.
41 | /// A pointer to a RECT structure that receives
42 | /// the screen coordinates of the upper-left and
43 | /// lower-right corners of the window.
44 | /// If the function succeeds, the return value is nonzero.
45 | [DllImport("user32.dll")]
46 | internal static extern bool GetWindowRect(IntPtr handle, ref Rectangle screenRectangle);
47 |
48 | ///
49 | /// Retrieves a handle to the top-level window whose class name and
50 | /// window name match the specified strings. This function does not search
51 | /// child windows. This function does not perform a case-sensitive search.
52 | ///
53 | /// The class name or a class atom c
54 | /// created by a previous call to the RegisterClass or RegisterClassEx function.
55 | /// The atom must be in the low-order word of lpClassName;
56 | /// the high-order word must be zero.
57 | /// The window name (the window's title).
58 | /// If this parameter is NULL, all window names match.
59 | /// If the function succeeds, the return value is a handle
60 | /// to the window that has the specified class name and window name.
61 | [DllImport("user32.dll", SetLastError = true)]
62 | internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
63 | }
64 | }
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/WinFeatures/MouseCursor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace OpenScreen.Core.Screenshot.WinFeatures
5 | {
6 | ///
7 | /// Class for working with the mouse cursor.
8 | ///
9 | /// Details of the CursorInfo structure:
10 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-cursorinfo
11 | ///
12 | /// Details of the GetCursorInfo method:
13 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getcursorinfo
14 | ///
15 | /// Details of the DrawIconEx method:
16 | /// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-drawiconex
17 | ///
18 | internal static class MouseCursor
19 | {
20 | public const int CursorShowing = 0x00000001;
21 | public const int DiNormal = 0x0003;
22 |
23 | ///
24 | /// Contains global cursor information.
25 | ///
26 | [StructLayout(LayoutKind.Sequential)]
27 | public struct CursorInfo
28 | {
29 | public int cbSize; // The size of the structure, in bytes.
30 | public int flags; // The cursor state.
31 | public IntPtr hCursor; // A handle to the cursor.
32 | public PointApi ptScreenPos; // Screen coordinates of the cursor.
33 | }
34 |
35 | ///
36 | /// Defines the x- and y- coordinates of a point.
37 | ///
38 | [StructLayout(LayoutKind.Sequential)]
39 | public struct PointApi
40 | {
41 | public int x;
42 | public int y;
43 | }
44 |
45 | ///
46 | /// Retrieves information about the global cursor.
47 | ///
48 | /// A pointer to a CURSORINFO structure that receives the information.
49 | /// If the function succeeds, the return value is nonzero.
50 | [DllImport("user32.dll")]
51 | public static extern bool GetCursorInfo(out CursorInfo pci);
52 |
53 | ///
54 | /// Draws an icon or cursor into the specified device context,
55 | /// performing the specified raster operations,
56 | /// and stretching or compressing the icon or cursor as specified.
57 | ///
58 | /// A handle to the device context into which the icon or cursor will be drawn.
59 | /// The logical x-coordinate of the upper-left corner of the icon or cursor.
60 | /// The logical y-coordinate of the upper-left corner of the icon or cursor.
61 | /// A handle to the icon or cursor to be drawn.
62 | /// The logical width of the icon or cursor.
63 | /// The logical height of the icon or cursor.
64 | /// The index of the frame to draw, if hIcon identifies an animated cursor.
65 | /// A handle to a brush that the system uses for flicker-free drawing.
66 | /// The drawing flags.
67 | /// If the function succeeds, the return value is nonzero.
68 | [DllImport("user32.dll")]
69 | public static extern bool DrawIconEx(IntPtr hdc, int xLeft, int yTop,
70 | IntPtr hIcon, int cxWidth, int cyHeight, int istepIfAniCur,
71 | IntPtr hbrFlickerFreeDraw, int diFlags);
72 | }
73 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [![Contributors][contributors-shield]][contributors-url]
2 | [![Forks][forks-shield]][forks-url]
3 | [![Stargazers][stars-shield]][stars-url]
4 | [![Issues][issues-shield]][issues-url]
5 | [![MIT License][license-shield]][license-url]
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
OpenScreen
16 |
17 |
18 | Desktop application for screen sharing over the network!
19 |
20 |
21 | Releases
22 | ·
23 | Report Bug
24 | ·
25 | Request Feature
26 |
27 |
28 |
29 |
30 |
31 | ## Table of Contents
32 |
33 | * [About the Project](#about-the-project)
34 | * [Built With](#built-with)
35 | * [Getting Started](#getting-started)
36 | * [Installation](#installation)
37 | * [Roadmap](#roadmap)
38 | * [Contributing](#contributing)
39 | * [License](#license)
40 | * [Contact](#contact)
41 |
42 |
43 |
44 | ## About The Project
45 | Screenshots of a running application:
46 |
47 |
48 |
49 |
50 |
51 |
52 | **OpenScreen** is a desktop application that allows you to show your screen to friends and colleagues.
53 |
54 | **Features:**
55 | * You can show the whole screen
56 | * You can show the window of a specific application
57 | * You are viewing a demo in a browser -> you can do it from a computer, tablet or phone
58 | * You can enable/disable the display of the cursor when demonstrating the screen/application window
59 | * You can choose the quality of the screen demonstration
60 | * You can change the FPS
61 |
62 | ### Built With
63 | * [Visual Studio 2019](https://visualstudio.microsoft.com/vs/)
64 | * [.NET Framework 4.7.2](https://dotnet.microsoft.com/download/dotnet-framework/net472)
65 | * [C# 7.3](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-3)
66 |
67 |
68 |
69 | ## Getting Started
70 |
71 | ### Installation
72 |
73 | 1. Clone the repo
74 | ```sh
75 | > git clone https://github.com/MrKonstantinSh/OpenScreen.git
76 | ```
77 | 2. Go to the project folder
78 | ```sh
79 | > cd ./ProjectFolder
80 | ```
81 |
82 | **OR**
83 |
84 | DOWNLOAD [OpenScreen-Installer.msi](https://github.com/MrKonstantinSh/OpenScreen/releases/download/v1.2/OpenScreen-Installer.msi)
85 |
86 |
87 | ## Roadmap
88 |
89 | See the [open issues](https://github.com/MrKonstantinSh/OpenScreen/issues) for a list of proposed features (and known issues).
90 |
91 |
92 |
93 | ## Contributing
94 |
95 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.
96 |
97 | 1. Fork the Project
98 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)
99 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)
100 | 4. Push to the Branch (`git push origin feature/AmazingFeature`)
101 | 5. Open a Pull Request
102 |
103 |
104 |
105 | ## License
106 |
107 | Distributed under the MIT License. See [LICENSE](https://github.com/MrKonstantinSh/OpenScreen/blob/master/LICENSE) for more information.
108 |
109 |
110 |
111 | ## Contact
112 |
113 | Shulga Konstantin - mrkonstantinsh@gmail.com
114 |
115 | Project Link: [https://github.com/MrKonstantinSh/OpenScreen](https://github.com/MrKonstantinSh/OpenScreen)
116 |
117 |
118 | [contributors-shield]: https://img.shields.io/github/contributors/MrKonstantinSh/OpenScreen.svg?style=flat-square
119 | [contributors-url]: https://github.com/MrKonstantinSh/OpenScreen/graphs/contributors
120 | [forks-shield]: https://img.shields.io/github/forks/MrKonstantinSh/OpenScreen.svg?style=flat-square
121 | [forks-url]: https://github.com/MrKonstantinSh/OpenScreen/network/members
122 | [stars-shield]: https://img.shields.io/github/stars/MrKonstantinSh/OpenScreen.svg?style=flat-square
123 | [stars-url]: https://github.com/MrKonstantinSh/OpenScreen/stargazers
124 | [issues-shield]: https://img.shields.io/github/issues/MrKonstantinSh/OpenScreen.svg?style=flat-square
125 | [issues-url]: https://github.com/MrKonstantinSh/OpenScreen/issues
126 | [license-shield]: https://img.shields.io/github/license/MrKonstantinSh/OpenScreen.svg?style=flat-square
127 | [license-url]: https://github.com/MrKonstantinSh/OpenScreen/blob/master/LICENSE
128 |
129 |
--------------------------------------------------------------------------------
/OpenScreen/OpenScreen.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/Screenshot.cs:
--------------------------------------------------------------------------------
1 | using OpenScreen.Core.Screenshot.WinFeatures;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Drawing;
5 | using System.Runtime.InteropServices;
6 | using System.Windows.Forms;
7 |
8 | namespace OpenScreen.Core.Screenshot
9 | {
10 | ///
11 | /// Provides methods for creating screenshots.
12 | ///
13 | public static class Screenshot
14 | {
15 | ///
16 | /// Provides enumeration of screenshots.
17 | ///
18 | /// Required screenshot resolution.
19 | /// Whether to display the cursor in screenshots.
20 | /// Enumeration of screenshots.
21 | public static IEnumerable TakeSeriesOfScreenshots(Resolution.Resolutions requiredResolution,
22 | bool isDisplayCursor)
23 | {
24 | var screenSize = new Size(Screen.PrimaryScreen.Bounds.Width,
25 | Screen.PrimaryScreen.Bounds.Height);
26 | var requiredSize = Resolution.GetResolutionSize(requiredResolution);
27 |
28 | var rawImage = new Bitmap(screenSize.Width, screenSize.Height);
29 | var rawGraphics = Graphics.FromImage(rawImage);
30 |
31 | bool isNeedToScale = screenSize != requiredSize;
32 |
33 | var image = rawImage;
34 | var graphics = rawGraphics;
35 |
36 | if (isNeedToScale)
37 | {
38 | image = new Bitmap(requiredSize.Width, requiredSize.Height);
39 | graphics = Graphics.FromImage(image);
40 | }
41 |
42 | var source = new Rectangle(0, 0, screenSize.Width, screenSize.Height);
43 | var destination = new Rectangle(0, 0, requiredSize.Width, requiredSize.Height);
44 |
45 | while (true)
46 | {
47 | rawGraphics.CopyFromScreen(0, 0, 0, 0, screenSize);
48 |
49 | if (isDisplayCursor)
50 | {
51 | AddCursorToScreenshot(rawGraphics, source);
52 | }
53 |
54 | if (isNeedToScale)
55 | {
56 | graphics.DrawImage(rawImage, destination, source, GraphicsUnit.Pixel);
57 | }
58 |
59 | yield return image;
60 | }
61 | }
62 |
63 | ///
64 | /// Provides enumeration of screenshots of a specific application window.
65 | ///
66 | /// The title of the main application window.
67 | /// Whether to display the cursor in screenshots.
68 | /// Enumeration of screenshots of a specific application window.
69 | public static IEnumerable TakeSeriesOfScreenshotsAppWindow(string applicationName,
70 | bool isDisplayCursor)
71 | {
72 | var windowHandle = ApplicationWindow.FindWindow(null, applicationName);
73 |
74 | var screeRectangle = new Rectangle();
75 |
76 | while (true)
77 | {
78 | ApplicationWindow.GetWindowRect(windowHandle, ref screeRectangle);
79 |
80 | screeRectangle.Width -= screeRectangle.X;
81 | screeRectangle.Height -= screeRectangle.Y;
82 |
83 | var image = new Bitmap(screeRectangle.Width, screeRectangle.Height);
84 |
85 | var graphics = Graphics.FromImage(image);
86 |
87 | var hdc = graphics.GetHdc();
88 |
89 | if (!ApplicationWindow.PrintWindow(windowHandle, hdc,
90 | ApplicationWindow.DrawAllWindow))
91 | {
92 | int error = Marshal.GetLastWin32Error();
93 | throw new System.ComponentModel.Win32Exception($"An error occurred while creating a screenshot"
94 | + $" of the application window. Error Number: {error}.");
95 | }
96 |
97 | graphics.ReleaseHdc(hdc);
98 |
99 | if (isDisplayCursor)
100 | {
101 | AddCursorToScreenshot(graphics, screeRectangle);
102 | }
103 |
104 | yield return image;
105 |
106 | image.Dispose();
107 | graphics.Dispose();
108 | }
109 | }
110 |
111 | ///
112 | /// Adds a cursor to a screenshot.
113 | ///
114 | /// Drawing surface.
115 | /// Screen bounds.
116 | private static void AddCursorToScreenshot(Graphics graphics, Rectangle bounds)
117 | {
118 | if (graphics == null)
119 | {
120 | throw new ArgumentNullException(nameof(graphics));
121 | }
122 |
123 | MouseCursor.CursorInfo pci;
124 | pci.cbSize = Marshal.SizeOf(typeof(MouseCursor.CursorInfo));
125 |
126 | if (!MouseCursor.GetCursorInfo(out pci))
127 | {
128 | return;
129 | }
130 |
131 | if (pci.flags != MouseCursor.CursorShowing)
132 | {
133 | return;
134 | }
135 |
136 | const int logicalWidth = 0;
137 | const int logicalHeight = 0;
138 | const int indexOfFrame = 0;
139 |
140 | MouseCursor.DrawIconEx(graphics.GetHdc(), pci.ptScreenPos.x - bounds.X,
141 | pci.ptScreenPos.y - bounds.Y, pci.hCursor, logicalWidth,
142 | logicalHeight, indexOfFrame, IntPtr.Zero, MouseCursor.DiNormal);
143 |
144 | graphics.ReleaseHdc();
145 | }
146 | }
147 | }
--------------------------------------------------------------------------------
/OpenScreen/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/OpenScreen/OpenScreen.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {B088B160-DBC1-484C-BEF7-62BF5F15BC98}
8 | WinExe
9 | OpenScreen
10 | OpenScreen
11 | v4.7.2
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 | true
17 |
18 | publish\
19 | true
20 | Disk
21 | false
22 | Foreground
23 | 7
24 | Days
25 | false
26 | false
27 | true
28 | 0
29 | 1.0.0.%2a
30 | false
31 | false
32 | true
33 |
34 |
35 | AnyCPU
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | AnyCPU
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 |
53 |
54 | favicon.ico
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 4.0
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | MSBuild:Compile
75 | Designer
76 |
77 |
78 | MSBuild:Compile
79 | Designer
80 |
81 |
82 | App.xaml
83 | Code
84 |
85 |
86 |
87 | OpenScreen.xaml
88 | Code
89 |
90 |
91 |
92 |
93 | Code
94 |
95 |
96 | True
97 | True
98 | Resources.resx
99 |
100 |
101 | True
102 | Settings.settings
103 | True
104 |
105 |
106 | ResXFileCodeGenerator
107 | Resources.Designer.cs
108 |
109 |
110 | SettingsSingleFileGenerator
111 | Settings.Designer.cs
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | {666657b0-cde6-4274-bd25-3e72a1fb87fb}
120 | OpenScreen.Core
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | False
132 | Microsoft .NET Framework 4.7.2 %28x86 and x64%29
133 | true
134 |
135 |
136 | False
137 | .NET Framework 3.5 SP1
138 | false
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /ConsoleTest
2 |
3 | ## Ignore Visual Studio temporary files, build results, and
4 | ## files generated by popular Visual Studio add-ons.
5 | ##
6 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
7 |
8 | # User-specific files
9 | *.rsuser
10 | *.suo
11 | *.user
12 | *.userosscache
13 | *.sln.docstates
14 |
15 | # User-specific files (MonoDevelop/Xamarin Studio)
16 | *.userprefs
17 |
18 | # Mono auto generated files
19 | mono_crash.*
20 |
21 | # Build results
22 | [Dd]ebug/
23 | [Dd]ebugPublic/
24 | [Rr]elease/
25 | [Rr]eleases/
26 | x64/
27 | x86/
28 | [Aa][Rr][Mm]/
29 | [Aa][Rr][Mm]64/
30 | bld/
31 | [Bb]in/
32 | [Oo]bj/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # StyleCop
67 | StyleCopReport.xml
68 |
69 | # Files built by Visual Studio
70 | *_i.c
71 | *_p.c
72 | *_h.h
73 | *.ilk
74 | *.meta
75 | *.obj
76 | *.iobj
77 | *.pch
78 | *.pdb
79 | *.ipdb
80 | *.pgc
81 | *.pgd
82 | *.rsp
83 | *.sbr
84 | *.tlb
85 | *.tli
86 | *.tlh
87 | *.tmp
88 | *.tmp_proj
89 | *_wpftmp.csproj
90 | *.log
91 | *.vspscc
92 | *.vssscc
93 | .builds
94 | *.pidb
95 | *.svclog
96 | *.scc
97 |
98 | # Chutzpah Test files
99 | _Chutzpah*
100 |
101 | # Visual C++ cache files
102 | ipch/
103 | *.aps
104 | *.ncb
105 | *.opendb
106 | *.opensdf
107 | *.sdf
108 | *.cachefile
109 | *.VC.db
110 | *.VC.VC.opendb
111 |
112 | # Visual Studio profiler
113 | *.psess
114 | *.vsp
115 | *.vspx
116 | *.sap
117 |
118 | # Visual Studio Trace Files
119 | *.e2e
120 |
121 | # TFS 2012 Local Workspace
122 | $tf/
123 |
124 | # Guidance Automation Toolkit
125 | *.gpState
126 |
127 | # ReSharper is a .NET coding add-in
128 | _ReSharper*/
129 | *.[Rr]e[Ss]harper
130 | *.DotSettings.user
131 |
132 | # TeamCity is a build add-in
133 | _TeamCity*
134 |
135 | # DotCover is a Code Coverage Tool
136 | *.dotCover
137 |
138 | # AxoCover is a Code Coverage Tool
139 | .axoCover/*
140 | !.axoCover/settings.json
141 |
142 | # Visual Studio code coverage results
143 | *.coverage
144 | *.coveragexml
145 |
146 | # NCrunch
147 | _NCrunch_*
148 | .*crunch*.local.xml
149 | nCrunchTemp_*
150 |
151 | # MightyMoose
152 | *.mm.*
153 | AutoTest.Net/
154 |
155 | # Web workbench (sass)
156 | .sass-cache/
157 |
158 | # Installshield output folder
159 | [Ee]xpress/
160 |
161 | # DocProject is a documentation generator add-in
162 | DocProject/buildhelp/
163 | DocProject/Help/*.HxT
164 | DocProject/Help/*.HxC
165 | DocProject/Help/*.hhc
166 | DocProject/Help/*.hhk
167 | DocProject/Help/*.hhp
168 | DocProject/Help/Html2
169 | DocProject/Help/html
170 |
171 | # Click-Once directory
172 | publish/
173 |
174 | # Publish Web Output
175 | *.[Pp]ublish.xml
176 | *.azurePubxml
177 | # Note: Comment the next line if you want to checkin your web deploy settings,
178 | # but database connection strings (with potential passwords) will be unencrypted
179 | *.pubxml
180 | *.publishproj
181 |
182 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
183 | # checkin your Azure Web App publish settings, but sensitive information contained
184 | # in these scripts will be unencrypted
185 | PublishScripts/
186 |
187 | # NuGet Packages
188 | *.nupkg
189 | # NuGet Symbol Packages
190 | *.snupkg
191 | # The packages folder can be ignored because of Package Restore
192 | **/[Pp]ackages/*
193 | # except build/, which is used as an MSBuild target.
194 | !**/[Pp]ackages/build/
195 | # Uncomment if necessary however generally it will be regenerated when needed
196 | #!**/[Pp]ackages/repositories.config
197 | # NuGet v3's project.json files produces more ignorable files
198 | *.nuget.props
199 | *.nuget.targets
200 |
201 | # Microsoft Azure Build Output
202 | csx/
203 | *.build.csdef
204 |
205 | # Microsoft Azure Emulator
206 | ecf/
207 | rcf/
208 |
209 | # Windows Store app package directories and files
210 | AppPackages/
211 | BundleArtifacts/
212 | Package.StoreAssociation.xml
213 | _pkginfo.txt
214 | *.appx
215 | *.appxbundle
216 | *.appxupload
217 |
218 | # Visual Studio cache files
219 | # files ending in .cache can be ignored
220 | *.[Cc]ache
221 | # but keep track of directories ending in .cache
222 | !?*.[Cc]ache/
223 |
224 | # Others
225 | ClientBin/
226 | ~$*
227 | *~
228 | *.dbmdl
229 | *.dbproj.schemaview
230 | *.jfm
231 | *.pfx
232 | *.publishsettings
233 | orleans.codegen.cs
234 |
235 | # Including strong name files can present a security risk
236 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
237 | #*.snk
238 |
239 | # Since there are multiple workflows, uncomment next line to ignore bower_components
240 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
241 | #bower_components/
242 |
243 | # RIA/Silverlight projects
244 | Generated_Code/
245 |
246 | # Backup & report files from converting an old project file
247 | # to a newer Visual Studio version. Backup files are not needed,
248 | # because we have git ;-)
249 | _UpgradeReport_Files/
250 | Backup*/
251 | UpgradeLog*.XML
252 | UpgradeLog*.htm
253 | ServiceFabricBackup/
254 | *.rptproj.bak
255 |
256 | # SQL Server files
257 | *.mdf
258 | *.ldf
259 | *.ndf
260 |
261 | # Business Intelligence projects
262 | *.rdl.data
263 | *.bim.layout
264 | *.bim_*.settings
265 | *.rptproj.rsuser
266 | *- [Bb]ackup.rdl
267 | *- [Bb]ackup ([0-9]).rdl
268 | *- [Bb]ackup ([0-9][0-9]).rdl
269 |
270 | # Microsoft Fakes
271 | FakesAssemblies/
272 |
273 | # GhostDoc plugin setting file
274 | *.GhostDoc.xml
275 |
276 | # Node.js Tools for Visual Studio
277 | .ntvs_analysis.dat
278 | node_modules/
279 |
280 | # Visual Studio 6 build log
281 | *.plg
282 |
283 | # Visual Studio 6 workspace options file
284 | *.opt
285 |
286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
287 | *.vbw
288 |
289 | # Visual Studio LightSwitch build output
290 | **/*.HTMLClient/GeneratedArtifacts
291 | **/*.DesktopClient/GeneratedArtifacts
292 | **/*.DesktopClient/ModelManifest.xml
293 | **/*.Server/GeneratedArtifacts
294 | **/*.Server/ModelManifest.xml
295 | _Pvt_Extensions
296 |
297 | # Paket dependency manager
298 | .paket/paket.exe
299 | paket-files/
300 |
301 | # FAKE - F# Make
302 | .fake/
303 |
304 | # CodeRush personal settings
305 | .cr/personal
306 |
307 | # Python Tools for Visual Studio (PTVS)
308 | __pycache__/
309 | *.pyc
310 |
311 | # Cake - Uncomment if you are using it
312 | # tools/**
313 | # !tools/packages.config
314 |
315 | # Tabs Studio
316 | *.tss
317 |
318 | # Telerik's JustMock configuration file
319 | *.jmconfig
320 |
321 | # BizTalk build output
322 | *.btp.cs
323 | *.btm.cs
324 | *.odx.cs
325 | *.xsd.cs
326 |
327 | # OpenCover UI analysis results
328 | OpenCover/
329 |
330 | # Azure Stream Analytics local run output
331 | ASALocalRun/
332 |
333 | # MSBuild Binary and Structured Log
334 | *.binlog
335 |
336 | # NVidia Nsight GPU debugger configuration file
337 | *.nvuser
338 |
339 | # MFractors (Xamarin productivity tool) working folder
340 | .mfractor/
341 |
342 | # Local History for Visual Studio
343 | .localhistory/
344 |
345 | # BeatPulse healthcheck temp database
346 | healthchecksdb
347 |
348 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
349 | MigrationBackup/
350 |
351 | # Ionide (cross platform F# VS Code tools) working folder
352 | .ionide/
--------------------------------------------------------------------------------
/OpenScreen.Core/Server/StreamingServer.cs:
--------------------------------------------------------------------------------
1 | using OpenScreen.Core.Mjpeg;
2 | using OpenScreen.Core.Screenshot;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Drawing;
6 | using System.IO;
7 | using System.Net;
8 | using System.Net.Sockets;
9 | using System.Threading;
10 |
11 | namespace OpenScreen.Core.Server
12 | {
13 | public class StreamingServer
14 | {
15 | private static readonly object SyncRoot = new object();
16 | private static StreamingServer _serverInstance;
17 |
18 | private IEnumerable _images;
19 | private Socket _serverSocket;
20 | private Thread _thread;
21 |
22 | public int Delay { get; }
23 |
24 | public List Clients { get; }
25 |
26 | public bool IsRunning => _thread != null && _thread.IsAlive;
27 |
28 | ///
29 | /// Initializes the fields and properties of the class for the screen stream.
30 | ///
31 | private StreamingServer(Resolution.Resolutions imageResolution, Fps fps, bool isDisplayCursor)
32 | : this(Screenshot.Screenshot.TakeSeriesOfScreenshots(imageResolution, isDisplayCursor), fps)
33 | {
34 |
35 | }
36 |
37 | ///
38 | /// Initializes the fields and properties of the class to stream a specific application window.
39 | ///
40 | private StreamingServer(string applicationName, Fps fps, bool isDisplayCursor)
41 | : this(Screenshot.Screenshot.TakeSeriesOfScreenshotsAppWindow(applicationName, isDisplayCursor), fps)
42 | {
43 |
44 | }
45 |
46 | ///
47 | /// The constructor of the class that initializes the fields of the class.
48 | ///
49 | private StreamingServer(IEnumerable images, Fps fps)
50 | {
51 | _thread = null;
52 | _images = images;
53 |
54 | Clients = new List();
55 | Delay = (int)fps;
56 | }
57 |
58 | ///
59 | /// Provides a server object for a screen stream.
60 | ///
61 | /// Stream Resolution.
62 | /// FPS.
63 | /// Whether to display the cursor in screenshots.
64 | /// The object of the StreamingServer class.
65 | public static StreamingServer GetInstance(Resolution.Resolutions resolutions,
66 | Fps fps, bool isDisplayCursor)
67 | {
68 | lock (SyncRoot)
69 | {
70 | _serverInstance ??= new StreamingServer(resolutions, fps, isDisplayCursor);
71 | }
72 |
73 | return _serverInstance;
74 | }
75 |
76 | ///
77 | /// Provides an object for a window stream of a specific application.
78 | ///
79 | /// The title of the main application window.
80 | /// FPS.
81 | /// Whether to display the cursor in screenshots.
82 | /// The object of the StreamingServer class.
83 | public static StreamingServer GetInstance(string applicationName,
84 | Fps fps, bool isDisplayCursor)
85 | {
86 | lock (SyncRoot)
87 | {
88 | _serverInstance ??= new StreamingServer(applicationName, fps, isDisplayCursor);
89 | }
90 |
91 | return _serverInstance;
92 | }
93 |
94 | ///
95 | /// Starts the server on the specified port.
96 | ///
97 | /// The IP address on which to start the server.
98 | /// Server port.
99 | public void Start(IPAddress ipAddress, int port)
100 | {
101 | var serverConfig = new ServerConfig(ipAddress, port);
102 |
103 | lock (this)
104 | {
105 | _thread = new Thread(StartServerThread)
106 | {
107 | IsBackground = true
108 | };
109 |
110 | _thread.Start(serverConfig);
111 | }
112 | }
113 |
114 | ///
115 | /// Stops the server.
116 | ///
117 | public void Stop()
118 | {
119 | if (!IsRunning)
120 | {
121 | return;
122 | }
123 |
124 | try
125 | {
126 | _serverSocket.Shutdown(SocketShutdown.Both);
127 | }
128 | catch
129 | {
130 | _serverSocket.Close();
131 | }
132 | finally
133 | {
134 | _thread = null;
135 | _images = null;
136 | _serverInstance = null;
137 | }
138 | }
139 |
140 | ///
141 | /// Starts the server in a separate thread.
142 | ///
143 | /// IP address and port on which you want to start the server.
144 | private void StartServerThread(object config)
145 | {
146 | var serverConfig = (ServerConfig)config;
147 |
148 | try
149 | {
150 | _serverSocket = new Socket(AddressFamily.InterNetwork,
151 | SocketType.Stream, ProtocolType.Tcp);
152 |
153 | _serverSocket.Bind(new IPEndPoint(serverConfig.IpAddress,
154 | serverConfig.Port));
155 | _serverSocket.Listen(10);
156 |
157 | foreach (var client in _serverSocket.GetIncomingConnections())
158 | {
159 | ThreadPool.QueueUserWorkItem(StartClientThread, client);
160 | }
161 | }
162 | catch (SocketException)
163 | {
164 | foreach (var client in Clients.ToArray())
165 | {
166 | try
167 | {
168 | client.Shutdown(SocketShutdown.Both);
169 | }
170 | catch (ObjectDisposedException)
171 | {
172 | client.Close();
173 | }
174 |
175 | Clients.Remove(client);
176 | }
177 | }
178 | }
179 |
180 | ///
181 | /// Starts a thread to handle clients.
182 | ///
183 | /// Client socket.
184 | private void StartClientThread(object client)
185 | {
186 | var clientSocket = (Socket)client;
187 | clientSocket.SendTimeout = 10000;
188 |
189 | Clients.Add(clientSocket);
190 |
191 | try
192 | {
193 | using var mjpegWriter = new MjpegWriter(new NetworkStream(clientSocket, true));
194 | // Writes the response header to the client.
195 | mjpegWriter.WriteHeaders();
196 |
197 | // Streams the images from the source to the client.
198 | foreach (var imgStream in _images.GetMjpegStream())
199 | {
200 | Thread.Sleep(Delay);
201 |
202 | mjpegWriter.WriteImage(imgStream);
203 | }
204 | }
205 | catch (SocketException)
206 | {
207 |
208 | }
209 | catch (IOException)
210 | {
211 |
212 | }
213 | catch (Exception)
214 | {
215 |
216 | }
217 | finally
218 | {
219 | try
220 | {
221 | clientSocket.Shutdown(SocketShutdown.Both);
222 | }
223 | catch (ObjectDisposedException)
224 | {
225 | clientSocket.Close();
226 | }
227 |
228 | lock (Clients)
229 | {
230 | Clients.Remove(clientSocket);
231 | }
232 | }
233 | }
234 | }
235 | }
--------------------------------------------------------------------------------
/OpenScreen.Core/Screenshot/WinFeatures/RunningApplications.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Runtime.InteropServices;
4 | using System.Text;
5 |
6 | namespace OpenScreen.Core.Screenshot.WinFeatures
7 | {
8 | ///
9 | /// Provides information about running applications that you can stream.
10 | ///
11 | public static class RunningApplications
12 | {
13 | private const int GwlStyle = -16; // Sets a new window style.
14 | private const int WsCaption = 0xC00000; // The window has a title bar (includes the WS_BORDER style)
15 |
16 | ///
17 | /// Flags to specify window attributes for Desktop Window Manager (DWM) non-client rendering.
18 | ///
19 | private enum WindowAttributes : uint
20 | {
21 | NotClientRenderingEnabled = 1,
22 | NotClientRenderingPolicy,
23 | TransitionsForceDisabled,
24 | AllowNotClientPaint,
25 | CaptionButtonBounds,
26 | NotClientRtlLayout,
27 | ForceIconicRepresentation,
28 | Flip3DPolicy,
29 | ExtendedFrameBounds,
30 | HasIconicBitmap,
31 | DisallowPeek,
32 | ExcludedFromPeek,
33 | Cloak,
34 | Cloaked,
35 | FreezeRepresentation
36 | }
37 |
38 | #region Import Windows Functions
39 |
40 | ///
41 | /// Determines the visibility state of the specified window.
42 | ///
43 | /// A handle to the window to be tested.
44 | /// If the specified window, its parent window, its parent's parent window,
45 | /// and so forth, have the WS_VISIBLE style, the return value is nonzero.
46 | /// Otherwise, the return value is zero.
47 | [DllImport("user32.dll")]
48 | [return: MarshalAs(UnmanagedType.Bool)]
49 | private static extern bool IsWindowVisible(IntPtr handle);
50 |
51 | ///
52 | /// Copies the text of the specified window's title bar (if it has one) into a buffer.
53 | /// If the specified window is a control, the text of the control is copied.
54 | ///
55 | /// A handle to the window or control containing the text.
56 | /// The buffer that will receive the text.
57 | /// If the string is as long or longer than the buffer,
58 | /// the string is truncated and terminated with a null character.
59 | /// The maximum number of characters to copy to the buffer,
60 | /// including the null character. If the text exceeds this limit, it is truncated.
61 | /// If the function succeeds, the return value is the length, in characters,
62 | /// of the copied string, not including the terminating null character.
63 | [DllImport("user32.dll", EntryPoint = "GetWindowText",
64 | ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
65 | private static extern int GetWindowTitle(IntPtr handle, StringBuilder buffer, int maxCount);
66 |
67 | ///
68 | /// Retrieves information about the specified window.
69 | ///
70 | /// A handle to the window and, indirectly, the class to which the window belongs.
71 | /// The zero-based offset to the value to be retrieved.
72 | /// If the function succeeds, the return value is the requested value.
73 | [DllImport("user32.dll", SetLastError = true)]
74 | private static extern int GetWindowLong(IntPtr handle, int index);
75 |
76 | ///
77 | /// Determines whether the specified window is minimized (iconic).
78 | ///
79 | /// A handle to the window to be tested.
80 | /// If the window is iconic, the return value is nonzero.
81 | [DllImport("User32.dll")]
82 | [return: MarshalAs(UnmanagedType.Bool)]
83 | private static extern bool IsIconic(IntPtr handle);
84 |
85 | ///
86 | /// Enumerates all top-level windows associated with the specified desktop.
87 | /// It passes the handle to each window, in turn, to an application-defined callback function.
88 | ///
89 | /// A handle to the desktop whose top-level windows are to be enumerated.
90 | /// A pointer to an application-defined callback function.
91 | /// An application-defined value to be passed to the callback function.
92 | /// If the function fails or is unable to perform the enumeration, the return value is zero.
93 | [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows",
94 | ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
95 | private static extern bool EnumDesktopWindows(IntPtr desktopHandle, Callback callbackFunction, IntPtr callbackParam);
96 |
97 | ///
98 | /// Retrieves the current value of a specified Desktop Window Manager (DWM) attribute applied to a window.
99 | ///
100 | /// The handle to the window from which the attribute value is to be retrieved.
101 | /// A flag describing which value to retrieve,
102 | /// specified as a value of the WindowAttributes enumeration.
103 | /// A pointer to a value which, when this function returns successfully,
104 | /// receives the current value of the attribute.
105 | /// The size, in bytes, of the attribute value being received via the pvAttribute parameter.
106 | /// If the function succeeds, it returns S_OK.
107 | [DllImport("dwmapi.dll")]
108 | private static extern int DwmGetWindowAttribute(IntPtr handle, WindowAttributes dwAttribute,
109 | out bool pvAttribute, int cbAttribute);
110 |
111 | #endregion
112 |
113 | ///
114 | /// Callback for the EnumDesktopWindows function
115 | ///
116 | /// A handle to the desktop whose top-level windows are to be enumerated.
117 | /// An application-defined value to be passed to the callback function.
118 | /// If the function fails or is unable to perform the enumeration, the return value is zero.
119 | private delegate bool Callback(IntPtr desktopHandle, int callbackParam);
120 |
121 | ///
122 | /// Filters the headers of running applications.
123 | ///
124 | /// A handle to the window to be tested.
125 | /// Result of checking.
126 | private static bool IsHasCaption(IntPtr handle)
127 | {
128 | return (GetWindowLong(handle, GwlStyle) & WsCaption) == WsCaption;
129 | }
130 |
131 | ///
132 | /// Provides a list of running applications that you can stream.
133 | ///
134 | /// List of running applications that you can stream.
135 | public static IEnumerable GetListOfRunningApps()
136 | {
137 | var runningApps = new List();
138 |
139 | bool FilterCallback(IntPtr handle, int callbackParam)
140 | {
141 | var stringBuilder = new StringBuilder(255);
142 | int _ = GetWindowTitle(handle, stringBuilder, stringBuilder.Capacity + 1);
143 | string appTitle = stringBuilder.ToString();
144 |
145 | if (IsWindowVisible(handle) && !string.IsNullOrEmpty(appTitle) && IsHasCaption(handle))
146 | {
147 | runningApps.Add(appTitle);
148 | }
149 |
150 | DwmGetWindowAttribute(handle, WindowAttributes.Cloaked, out bool windowAttribute,
151 | sizeof(int));
152 |
153 | if (IsIconic(handle) || windowAttribute)
154 | {
155 | runningApps.Remove(appTitle);
156 | }
157 |
158 | return true;
159 | }
160 |
161 | EnumDesktopWindows(IntPtr.Zero, FilterCallback, IntPtr.Zero);
162 |
163 | return runningApps;
164 | }
165 | }
166 | }
--------------------------------------------------------------------------------
/OpenScreen/OpenScreen.xaml.cs:
--------------------------------------------------------------------------------
1 | using OpenScreen.Core.Screenshot;
2 | using OpenScreen.Core.Screenshot.WinFeatures;
3 | using OpenScreen.Core.Server;
4 | using OpenScreen.Properties;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Net;
9 | using System.Net.Sockets;
10 | using System.Windows;
11 | using System.Windows.Documents;
12 | using System.Windows.Threading;
13 |
14 | namespace OpenScreen
15 | {
16 | public partial class MainWindow
17 | {
18 | private StreamingServer _streamingServer;
19 |
20 | public MainWindow()
21 | {
22 | InitializeComponent();
23 | }
24 |
25 | private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
26 | {
27 | TbIpAddress.Text = Settings.Default["IpAddress"].ToString();
28 | TbPort.Text = Settings.Default["Port"].ToString();
29 |
30 | // Filling the combo box with running applications.
31 | var runningApps = GetInfoAboutRunningApps();
32 | foreach (string runningApp in runningApps)
33 | {
34 | CbAppWindow.Items.Add(runningApp);
35 | }
36 |
37 | CbAppWindow.SelectedIndex = 0;
38 | }
39 |
40 | private void RbOption_Checked(object sender, RoutedEventArgs e)
41 | {
42 | if (RbFullScreen.IsChecked == true)
43 | {
44 | if (GbFullScreenSettings != null)
45 | {
46 | GbFullScreenSettings.IsEnabled = true;
47 | }
48 |
49 | if (GbAppWinSettings != null)
50 | {
51 | GbAppWinSettings.IsEnabled = false;
52 | }
53 | }
54 | else
55 | {
56 | if (GbAppWinSettings != null)
57 | {
58 | GbAppWinSettings.IsEnabled = true;
59 | }
60 | if (GbFullScreenSettings != null)
61 | {
62 | GbFullScreenSettings.IsEnabled = false;
63 | }
64 | }
65 | }
66 |
67 | private void CbAppWindow_OnDropDownOpened(object sender, EventArgs e)
68 | {
69 | var runningApps = GetInfoAboutRunningApps();
70 | var appList = new string[CbAppWindow.Items.Count];
71 | CbAppWindow.Items.CopyTo(appList, 0);
72 |
73 | var arrayOfRunningApps = runningApps as string[] ?? runningApps.ToArray();
74 |
75 | foreach (string item in appList)
76 | {
77 | if (!arrayOfRunningApps.Contains(item))
78 | {
79 | CbAppWindow.Items.Remove(item);
80 | }
81 | }
82 |
83 | foreach (string runningApp in arrayOfRunningApps.Where(runningApp =>
84 | !CbAppWindow.Items.Contains(runningApp)))
85 | {
86 | CbAppWindow.Items.Add(runningApp);
87 | }
88 | }
89 |
90 | private void BtnStartStopStream_Click(object sender, RoutedEventArgs e)
91 | {
92 | // A timer that will check the number of users connected to the server every 30 seconds.
93 | var timer = new DispatcherTimer();
94 |
95 | timer.Tick += TimerTick;
96 | timer.Interval = new TimeSpan(0, 0, 30);
97 |
98 | if (BtnStartStopStream.Content.ToString() == UiConstants.StartStream)
99 | {
100 | try
101 | {
102 | ConfigureUiAtServerStartup();
103 |
104 | PrintInfo(UiConstants.ServerConfiguration);
105 |
106 | var ipAddress = IPAddress.Parse(TbIpAddress.Text);
107 | int port = int.Parse(TbPort.Text);
108 | var fps = GetFpsFromComboBox(CbFps.Text);
109 |
110 | CheckSocket(ipAddress, port);
111 |
112 | TbUrl.Text = $"http://{ipAddress}:{port}";
113 |
114 | PrintInfo(UiConstants.StartingServer);
115 |
116 | StartStreamingServer(ipAddress, port, fps);
117 |
118 | PrintInfo(UiConstants.ServerIsStarted + TbUrl.Text + UiConstants.NewLine);
119 |
120 | timer.Start();
121 |
122 | Settings.Default["IpAddress"] = TbIpAddress.Text;
123 | Settings.Default["Port"] = TbPort.Text;
124 | Settings.Default.Save();
125 | }
126 | catch (FormatException)
127 | {
128 | MessageBox.Show(UiConstants.PortOrIpErrorMessage, UiConstants.ErrorTitle,
129 | MessageBoxButton.OK, MessageBoxImage.Error);
130 |
131 | ConfigureUiWhenServerStops();
132 | PrintInfo(UiConstants.ServerStop);
133 | }
134 | catch (SocketException)
135 | {
136 | MessageBox.Show(UiConstants.IpAddressErrorMessage, UiConstants.ErrorTitle,
137 | MessageBoxButton.OK, MessageBoxImage.Error);
138 |
139 | ConfigureUiWhenServerStops();
140 | PrintInfo(UiConstants.ServerStop);
141 | }
142 | }
143 | else
144 | {
145 | PrintInfo(UiConstants.ServerStop);
146 |
147 | _streamingServer.Stop();
148 | timer.Stop();
149 |
150 | PrintInfo(UiConstants.ServerIsStopped);
151 |
152 | ConfigureUiWhenServerStops();
153 | }
154 | }
155 |
156 | private void MainWindow_OnClosed(object sender, EventArgs e)
157 | {
158 | _streamingServer?.Stop();
159 | }
160 |
161 | private void BtnClearInfo_Click(object sender, RoutedEventArgs e)
162 | {
163 | RtbInfo.Document.Blocks.Clear();
164 | }
165 |
166 | ///
167 | /// Provides information about running applications on a PC.
168 | ///
169 | /// The titles of the main windows of running applications.
170 | private static IEnumerable GetInfoAboutRunningApps()
171 | {
172 | return RunningApplications.GetListOfRunningApps();
173 | }
174 |
175 | ///
176 | /// Checks the correctness of the IP address and port.
177 | ///
178 | /// IP address.
179 | /// Port.
180 | private static void CheckSocket(IPAddress ipAddress, int port)
181 | {
182 | Socket testSocket = null;
183 |
184 | try
185 | {
186 | testSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
187 | ProtocolType.Tcp);
188 | testSocket.Bind(new IPEndPoint(ipAddress, port));
189 | }
190 | finally
191 | {
192 | try
193 | {
194 | testSocket?.Shutdown(SocketShutdown.Both);
195 | }
196 | catch
197 | {
198 | testSocket?.Close();
199 | }
200 | }
201 | }
202 |
203 | ///
204 | /// Provides FPS Stream.
205 | ///
206 | /// FPS selected by user.
207 | /// FPS.
208 | private static Fps GetFpsFromComboBox(string selectedFps)
209 | {
210 | switch (selectedFps)
211 | {
212 | case UiConstants.OneHundredAndTwentyFps:
213 | return Fps.OneHundredAndTwenty;
214 | case UiConstants.SixtyFps:
215 | return Fps.Sixty;
216 | case UiConstants.ThirtyFps:
217 | return Fps.Thirty;
218 | case UiConstants.FifteenFps:
219 | return Fps.Fifteen;
220 | default:
221 | return Fps.Thirty;
222 | }
223 | }
224 |
225 | ///
226 | /// Provides stream resolutions.
227 | ///
228 | /// Resolution selected by user.
229 | /// Resolution.
230 | private static Resolution.Resolutions GetResolutionFromComboBox(string selectedScreenResolution)
231 | {
232 | switch (selectedScreenResolution)
233 | {
234 | case UiConstants.OneThousandAndEightyP:
235 | return Resolution.Resolutions.OneThousandAndEightyP;
236 | case UiConstants.SevenHundredAndTwentyP:
237 | return Resolution.Resolutions.SevenHundredAndTwentyP;
238 | case UiConstants.FourHundredAndEightyP:
239 | return Resolution.Resolutions.FourHundredAndEightyP;
240 | case UiConstants.ThreeHundredAndSixtyP:
241 | return Resolution.Resolutions.ThreeHundredAndSixtyP;
242 | case UiConstants.TwoHundredAndFortyP:
243 | return Resolution.Resolutions.TwoHundredAndFortyP;
244 | default:
245 | return Resolution.Resolutions.SevenHundredAndTwentyP;
246 | }
247 | }
248 |
249 | ///
250 | /// Provides information about connected clients.
251 | ///
252 | private void TimerTick(object sender, EventArgs e)
253 | {
254 | int numberOfConnectedUsers = _streamingServer?.Clients?.Count ?? 0;
255 |
256 | LblConnectedUsers.Content = UiConstants.ConnectedUsers + numberOfConnectedUsers;
257 | }
258 |
259 | ///
260 | /// Starts the streaming server.
261 | ///
262 | /// IP address of the server.
263 | /// Server port.
264 | /// FPS stream.
265 | private void StartStreamingServer(IPAddress ipAddress, int port, Fps fps)
266 | {
267 | if (RbFullScreen.IsChecked == true)
268 | {
269 | var resolution = GetResolutionFromComboBox(CbScreenResolution.Text);
270 | bool isDisplayCursor = ChBFullScreenShowCursor.IsChecked != null
271 | && (bool)ChBFullScreenShowCursor.IsChecked;
272 |
273 | _streamingServer = StreamingServer.GetInstance(resolution, fps, isDisplayCursor);
274 | _streamingServer.Start(ipAddress, port);
275 | }
276 | else if (RbAppWindow.IsChecked == true)
277 | {
278 | string applicationName = CbAppWindow.Text;
279 | bool isDisplayCursor = ChBAppWindowShowCursor.IsChecked != null
280 | && (bool)ChBAppWindowShowCursor.IsChecked;
281 |
282 | _streamingServer = StreamingServer.GetInstance(applicationName, fps, isDisplayCursor);
283 | _streamingServer.Start(ipAddress, port);
284 | }
285 | }
286 |
287 | ///
288 | /// Configures the UI when the stream starts.
289 | ///
290 | private void ConfigureUiAtServerStartup()
291 | {
292 | TbIpAddress.IsEnabled = false;
293 | TbPort.IsEnabled = false;
294 | CbFps.IsEnabled = false;
295 | RbFullScreen.IsEnabled = false;
296 | RbAppWindow.IsEnabled = false;
297 | GbFullScreenSettings.IsEnabled = false;
298 | GbAppWinSettings.IsEnabled = false;
299 | LblConnectedUsers.Content = UiConstants.ConnectedUsersZero;
300 |
301 | BtnStartStopStream.Content = UiConstants.StopStream;
302 | }
303 |
304 | ///
305 | /// Configures the UI when the stream stops.
306 | ///
307 | private void ConfigureUiWhenServerStops()
308 | {
309 | TbIpAddress.IsEnabled = true;
310 | TbPort.IsEnabled = true;
311 | CbFps.IsEnabled = true;
312 | RbFullScreen.IsEnabled = true;
313 | RbAppWindow.IsEnabled = true;
314 | GbFullScreenSettings.IsEnabled = true;
315 | GbAppWinSettings.IsEnabled = false;
316 | RbFullScreen.IsChecked = true;
317 | TbUrl.Text = string.Empty;
318 | LblConnectedUsers.Content = UiConstants.ConnectedUsersZero;
319 |
320 | BtnStartStopStream.Content = UiConstants.StartStream;
321 | }
322 |
323 | ///
324 | /// Displays server status information.
325 | ///
326 | /// Server Information
327 | private void PrintInfo(string serverInfo)
328 | {
329 | var _ = new TextRange(RtbInfo.Document.ContentEnd,
330 | RtbInfo.Document.ContentEnd)
331 | {
332 | Text = serverInfo
333 | };
334 | }
335 | }
336 | }
--------------------------------------------------------------------------------
/OpenScreen.Installer/OpenScreen.Installer.vdproj:
--------------------------------------------------------------------------------
1 | "DeployProject"
2 | {
3 | "VSVersion" = "3:800"
4 | "ProjectType" = "8:{978C614F-708E-4E1A-B201-565925725DBA}"
5 | "IsWebType" = "8:FALSE"
6 | "ProjectName" = "8:OpenScreen.Installer"
7 | "LanguageId" = "3:1033"
8 | "CodePage" = "3:1252"
9 | "UILanguageId" = "3:1033"
10 | "SccProjectName" = "8:"
11 | "SccLocalPath" = "8:"
12 | "SccAuxPath" = "8:"
13 | "SccProvider" = "8:"
14 | "Hierarchy"
15 | {
16 | "Entry"
17 | {
18 | "MsmKey" = "8:_190FC70280884313A63789D9F937DDA8"
19 | "OwnerKey" = "8:_UNDEFINED"
20 | "MsmSig" = "8:_UNDEFINED"
21 | }
22 | "Entry"
23 | {
24 | "MsmKey" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
25 | "OwnerKey" = "8:_UNDEFINED"
26 | "MsmSig" = "8:_UNDEFINED"
27 | }
28 | "Entry"
29 | {
30 | "MsmKey" = "8:_56ED481DF20EEA7CB91BA9F7D04B658F"
31 | "OwnerKey" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
32 | "MsmSig" = "8:_UNDEFINED"
33 | }
34 | "Entry"
35 | {
36 | "MsmKey" = "8:_F3778D33864EE7D62FB1CCA256364597"
37 | "OwnerKey" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
38 | "MsmSig" = "8:_UNDEFINED"
39 | }
40 | "Entry"
41 | {
42 | "MsmKey" = "8:_UNDEFINED"
43 | "OwnerKey" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
44 | "MsmSig" = "8:_UNDEFINED"
45 | }
46 | "Entry"
47 | {
48 | "MsmKey" = "8:_UNDEFINED"
49 | "OwnerKey" = "8:_F3778D33864EE7D62FB1CCA256364597"
50 | "MsmSig" = "8:_UNDEFINED"
51 | }
52 | "Entry"
53 | {
54 | "MsmKey" = "8:_UNDEFINED"
55 | "OwnerKey" = "8:_56ED481DF20EEA7CB91BA9F7D04B658F"
56 | "MsmSig" = "8:_UNDEFINED"
57 | }
58 | }
59 | "Configurations"
60 | {
61 | "Debug"
62 | {
63 | "DisplayName" = "8:Debug"
64 | "IsDebugOnly" = "11:TRUE"
65 | "IsReleaseOnly" = "11:FALSE"
66 | "OutputFilename" = "8:Debug\\OpenScreen.Installer.msi"
67 | "PackageFilesAs" = "3:2"
68 | "PackageFileSize" = "3:-2147483648"
69 | "CabType" = "3:1"
70 | "Compression" = "3:2"
71 | "SignOutput" = "11:FALSE"
72 | "CertificateFile" = "8:"
73 | "PrivateKeyFile" = "8:"
74 | "TimeStampServer" = "8:"
75 | "InstallerBootstrapper" = "3:2"
76 | "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
77 | {
78 | "Enabled" = "11:TRUE"
79 | "PromptEnabled" = "11:TRUE"
80 | "PrerequisitesLocation" = "2:1"
81 | "Url" = "8:"
82 | "ComponentsUrl" = "8:"
83 | "Items"
84 | {
85 | "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
86 | {
87 | "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
88 | "ProductCode" = "8:.NETFramework,Version=v4.7.2"
89 | }
90 | }
91 | }
92 | }
93 | "Release"
94 | {
95 | "DisplayName" = "8:Release"
96 | "IsDebugOnly" = "11:FALSE"
97 | "IsReleaseOnly" = "11:TRUE"
98 | "OutputFilename" = "8:Release\\OpenScreen.Installer.msi"
99 | "PackageFilesAs" = "3:2"
100 | "PackageFileSize" = "3:-2147483648"
101 | "CabType" = "3:1"
102 | "Compression" = "3:2"
103 | "SignOutput" = "11:FALSE"
104 | "CertificateFile" = "8:"
105 | "PrivateKeyFile" = "8:"
106 | "TimeStampServer" = "8:"
107 | "InstallerBootstrapper" = "3:2"
108 | "BootstrapperCfg:{63ACBE69-63AA-4F98-B2B6-99F9E24495F2}"
109 | {
110 | "Enabled" = "11:TRUE"
111 | "PromptEnabled" = "11:TRUE"
112 | "PrerequisitesLocation" = "2:1"
113 | "Url" = "8:"
114 | "ComponentsUrl" = "8:"
115 | "Items"
116 | {
117 | "{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
118 | {
119 | "Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
120 | "ProductCode" = "8:.NETFramework,Version=v4.7.2"
121 | }
122 | }
123 | }
124 | }
125 | }
126 | "Deployable"
127 | {
128 | "CustomAction"
129 | {
130 | }
131 | "DefaultFeature"
132 | {
133 | "Name" = "8:DefaultFeature"
134 | "Title" = "8:"
135 | "Description" = "8:"
136 | }
137 | "ExternalPersistence"
138 | {
139 | "LaunchCondition"
140 | {
141 | "{A06ECF26-33A3-4562-8140-9B0E340D4F24}:_51EED621091C41A5A5B82B3D97C63546"
142 | {
143 | "Name" = "8:.NET Framework"
144 | "Message" = "8:[VSDNETMSG]"
145 | "FrameworkVersion" = "8:.NETFramework,Version=v4.7.2"
146 | "AllowLaterVersions" = "11:FALSE"
147 | "InstallUrl" = "8:http://go.microsoft.com/fwlink/?LinkId=863262"
148 | }
149 | }
150 | }
151 | "File"
152 | {
153 | "{1FB2D0AE-D3B9-43D4-B9DD-F88EC61E35DE}:_190FC70280884313A63789D9F937DDA8"
154 | {
155 | "SourcePath" = "8:..\\OpenScreen\\favicon.ico"
156 | "TargetName" = "8:favicon.ico"
157 | "Tag" = "8:"
158 | "Folder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
159 | "Condition" = "8:"
160 | "Transitive" = "11:FALSE"
161 | "Vital" = "11:TRUE"
162 | "ReadOnly" = "11:FALSE"
163 | "Hidden" = "11:FALSE"
164 | "System" = "11:FALSE"
165 | "Permanent" = "11:FALSE"
166 | "SharedLegacy" = "11:FALSE"
167 | "PackageAs" = "3:1"
168 | "Register" = "3:1"
169 | "Exclude" = "11:FALSE"
170 | "IsDependency" = "11:FALSE"
171 | "IsolateTo" = "8:"
172 | }
173 | "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_56ED481DF20EEA7CB91BA9F7D04B658F"
174 | {
175 | "AssemblyRegister" = "3:1"
176 | "AssemblyIsInGAC" = "11:FALSE"
177 | "AssemblyAsmDisplayName" = "8:System.Net.Http, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
178 | "ScatterAssemblies"
179 | {
180 | "_56ED481DF20EEA7CB91BA9F7D04B658F"
181 | {
182 | "Name" = "8:System.Net.Http.dll"
183 | "Attributes" = "3:512"
184 | }
185 | }
186 | "SourcePath" = "8:System.Net.Http.dll"
187 | "TargetName" = "8:"
188 | "Tag" = "8:"
189 | "Folder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
190 | "Condition" = "8:"
191 | "Transitive" = "11:FALSE"
192 | "Vital" = "11:TRUE"
193 | "ReadOnly" = "11:FALSE"
194 | "Hidden" = "11:FALSE"
195 | "System" = "11:FALSE"
196 | "Permanent" = "11:FALSE"
197 | "SharedLegacy" = "11:FALSE"
198 | "PackageAs" = "3:1"
199 | "Register" = "3:1"
200 | "Exclude" = "11:FALSE"
201 | "IsDependency" = "11:TRUE"
202 | "IsolateTo" = "8:"
203 | }
204 | "{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_F3778D33864EE7D62FB1CCA256364597"
205 | {
206 | "AssemblyRegister" = "3:1"
207 | "AssemblyIsInGAC" = "11:FALSE"
208 | "AssemblyAsmDisplayName" = "8:OpenScreen.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"
209 | "ScatterAssemblies"
210 | {
211 | "_F3778D33864EE7D62FB1CCA256364597"
212 | {
213 | "Name" = "8:OpenScreen.Core.dll"
214 | "Attributes" = "3:512"
215 | }
216 | }
217 | "SourcePath" = "8:OpenScreen.Core.dll"
218 | "TargetName" = "8:"
219 | "Tag" = "8:"
220 | "Folder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
221 | "Condition" = "8:"
222 | "Transitive" = "11:FALSE"
223 | "Vital" = "11:TRUE"
224 | "ReadOnly" = "11:FALSE"
225 | "Hidden" = "11:FALSE"
226 | "System" = "11:FALSE"
227 | "Permanent" = "11:FALSE"
228 | "SharedLegacy" = "11:FALSE"
229 | "PackageAs" = "3:1"
230 | "Register" = "3:1"
231 | "Exclude" = "11:FALSE"
232 | "IsDependency" = "11:TRUE"
233 | "IsolateTo" = "8:"
234 | }
235 | }
236 | "FileType"
237 | {
238 | }
239 | "Folder"
240 | {
241 | "{1525181F-901A-416C-8A58-119130FE478E}:_3B66264648C34A9D96314DEE6B88856C"
242 | {
243 | "Name" = "8:#1916"
244 | "AlwaysCreate" = "11:FALSE"
245 | "Condition" = "8:"
246 | "Transitive" = "11:FALSE"
247 | "Property" = "8:DesktopFolder"
248 | "Folders"
249 | {
250 | }
251 | }
252 | "{3C67513D-01DD-4637-8A68-80971EB9504F}:_B519726EA64F4E3CB3EB0A6DA800C5B0"
253 | {
254 | "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]"
255 | "Name" = "8:#1925"
256 | "AlwaysCreate" = "11:FALSE"
257 | "Condition" = "8:"
258 | "Transitive" = "11:FALSE"
259 | "Property" = "8:TARGETDIR"
260 | "Folders"
261 | {
262 | }
263 | }
264 | "{1525181F-901A-416C-8A58-119130FE478E}:_E9B41392470A4C70AD2DCA582BA77D09"
265 | {
266 | "Name" = "8:#1919"
267 | "AlwaysCreate" = "11:FALSE"
268 | "Condition" = "8:"
269 | "Transitive" = "11:FALSE"
270 | "Property" = "8:ProgramMenuFolder"
271 | "Folders"
272 | {
273 | "{9EF0B969-E518-4E46-987F-47570745A589}:_FED608165A1C454EB1B58F3B0CFD38D2"
274 | {
275 | "Name" = "8:OpenScreen"
276 | "AlwaysCreate" = "11:FALSE"
277 | "Condition" = "8:"
278 | "Transitive" = "11:FALSE"
279 | "Property" = "8:_04530401BB0A440990A1AA005A35E776"
280 | "Folders"
281 | {
282 | }
283 | }
284 | }
285 | }
286 | }
287 | "LaunchCondition"
288 | {
289 | }
290 | "Locator"
291 | {
292 | }
293 | "MsiBootstrapper"
294 | {
295 | "LangId" = "3:1033"
296 | "RequiresElevation" = "11:FALSE"
297 | }
298 | "Product"
299 | {
300 | "Name" = "8:Microsoft Visual Studio"
301 | "ProductName" = "8:OpenScreen"
302 | "ProductCode" = "8:{D0658EEB-C374-4C7D-9CA1-221A14C1202B}"
303 | "PackageCode" = "8:{37DF107B-7F8E-4F81-B579-73EF56EE9A3A}"
304 | "UpgradeCode" = "8:{5E189F74-E8FD-4F8D-8E41-D82D210DCC42}"
305 | "AspNetVersion" = "8:4.0.30319.0"
306 | "RestartWWWService" = "11:FALSE"
307 | "RemovePreviousVersions" = "11:FALSE"
308 | "DetectNewerInstalledVersion" = "11:TRUE"
309 | "InstallAllUsers" = "11:FALSE"
310 | "ProductVersion" = "8:1.0.0"
311 | "Manufacturer" = "8:MrKonstantinSh"
312 | "ARPHELPTELEPHONE" = "8:"
313 | "ARPHELPLINK" = "8:"
314 | "Title" = "8:OpenScreen"
315 | "Subject" = "8:"
316 | "ARPCONTACT" = "8:MrKonstantinSh"
317 | "Keywords" = "8:"
318 | "ARPCOMMENTS" = "8:Screen share program."
319 | "ARPURLINFOABOUT" = "8:"
320 | "ARPPRODUCTICON" = "8:"
321 | "ARPIconIndex" = "3:0"
322 | "SearchPath" = "8:"
323 | "UseSystemSearchPath" = "11:TRUE"
324 | "TargetPlatform" = "3:0"
325 | "PreBuildEvent" = "8:"
326 | "PostBuildEvent" = "8:"
327 | "RunPostBuildEvent" = "3:0"
328 | }
329 | "Registry"
330 | {
331 | "HKLM"
332 | {
333 | "Keys"
334 | {
335 | "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_A9DC181496244DDDA207B207CF879C83"
336 | {
337 | "Name" = "8:Software"
338 | "Condition" = "8:"
339 | "AlwaysCreate" = "11:FALSE"
340 | "DeleteAtUninstall" = "11:FALSE"
341 | "Transitive" = "11:FALSE"
342 | "Keys"
343 | {
344 | "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2728288D45B24E428055836E9A54B76C"
345 | {
346 | "Name" = "8:[Manufacturer]"
347 | "Condition" = "8:"
348 | "AlwaysCreate" = "11:FALSE"
349 | "DeleteAtUninstall" = "11:FALSE"
350 | "Transitive" = "11:FALSE"
351 | "Keys"
352 | {
353 | }
354 | "Values"
355 | {
356 | }
357 | }
358 | }
359 | "Values"
360 | {
361 | }
362 | }
363 | }
364 | }
365 | "HKCU"
366 | {
367 | "Keys"
368 | {
369 | "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_2D2B9EA3AEAE4FCC8008FA8DF38EED68"
370 | {
371 | "Name" = "8:Software"
372 | "Condition" = "8:"
373 | "AlwaysCreate" = "11:FALSE"
374 | "DeleteAtUninstall" = "11:FALSE"
375 | "Transitive" = "11:FALSE"
376 | "Keys"
377 | {
378 | "{60EA8692-D2D5-43EB-80DC-7906BF13D6EF}:_5679C2D7BFAD4EB8AD00E34DFF912E45"
379 | {
380 | "Name" = "8:[Manufacturer]"
381 | "Condition" = "8:"
382 | "AlwaysCreate" = "11:FALSE"
383 | "DeleteAtUninstall" = "11:FALSE"
384 | "Transitive" = "11:FALSE"
385 | "Keys"
386 | {
387 | }
388 | "Values"
389 | {
390 | }
391 | }
392 | }
393 | "Values"
394 | {
395 | }
396 | }
397 | }
398 | }
399 | "HKCR"
400 | {
401 | "Keys"
402 | {
403 | }
404 | }
405 | "HKU"
406 | {
407 | "Keys"
408 | {
409 | }
410 | }
411 | "HKPU"
412 | {
413 | "Keys"
414 | {
415 | }
416 | }
417 | }
418 | "Sequences"
419 | {
420 | }
421 | "Shortcut"
422 | {
423 | "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_A44827854AEE4133B0AF305D01560A05"
424 | {
425 | "Name" = "8:OpenScreen"
426 | "Arguments" = "8:"
427 | "Description" = "8:"
428 | "ShowCmd" = "3:1"
429 | "IconIndex" = "3:0"
430 | "Transitive" = "11:FALSE"
431 | "Target" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
432 | "Folder" = "8:_FED608165A1C454EB1B58F3B0CFD38D2"
433 | "WorkingFolder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
434 | "Icon" = "8:_190FC70280884313A63789D9F937DDA8"
435 | "Feature" = "8:"
436 | }
437 | "{970C0BB2-C7D0-45D7-ABFA-7EC378858BC0}:_CD445717BFD1431896713B2FE3B7B128"
438 | {
439 | "Name" = "8:OpenScreen"
440 | "Arguments" = "8:"
441 | "Description" = "8:"
442 | "ShowCmd" = "3:1"
443 | "IconIndex" = "3:0"
444 | "Transitive" = "11:FALSE"
445 | "Target" = "8:_514B7EF9EDF34AEDB25BD5622BE0143B"
446 | "Folder" = "8:_3B66264648C34A9D96314DEE6B88856C"
447 | "WorkingFolder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
448 | "Icon" = "8:_190FC70280884313A63789D9F937DDA8"
449 | "Feature" = "8:"
450 | }
451 | }
452 | "UserInterface"
453 | {
454 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_36F5395C6960418DA2B509858CABC29F"
455 | {
456 | "Name" = "8:#1901"
457 | "Sequence" = "3:1"
458 | "Attributes" = "3:2"
459 | "Dialogs"
460 | {
461 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_60F0AC77D0E4447998379B789AB02AC1"
462 | {
463 | "Sequence" = "3:100"
464 | "DisplayName" = "8:Progress"
465 | "UseDynamicProperties" = "11:TRUE"
466 | "IsDependency" = "11:FALSE"
467 | "SourcePath" = "8:\\VsdProgressDlg.wid"
468 | "Properties"
469 | {
470 | "BannerBitmap"
471 | {
472 | "Name" = "8:BannerBitmap"
473 | "DisplayName" = "8:#1001"
474 | "Description" = "8:#1101"
475 | "Type" = "3:8"
476 | "ContextData" = "8:Bitmap"
477 | "Attributes" = "3:4"
478 | "Setting" = "3:1"
479 | "UsePlugInResources" = "11:TRUE"
480 | }
481 | "ShowProgress"
482 | {
483 | "Name" = "8:ShowProgress"
484 | "DisplayName" = "8:#1009"
485 | "Description" = "8:#1109"
486 | "Type" = "3:5"
487 | "ContextData" = "8:1;True=1;False=0"
488 | "Attributes" = "3:0"
489 | "Setting" = "3:0"
490 | "Value" = "3:1"
491 | "DefaultValue" = "3:1"
492 | "UsePlugInResources" = "11:TRUE"
493 | }
494 | }
495 | }
496 | }
497 | }
498 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_3C8FC7DFCB064B279FE8A23ED53631FD"
499 | {
500 | "Name" = "8:#1900"
501 | "Sequence" = "3:2"
502 | "Attributes" = "3:1"
503 | "Dialogs"
504 | {
505 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_17E581BA435F4A96ADCACE113C7C4D2B"
506 | {
507 | "Sequence" = "3:200"
508 | "DisplayName" = "8:Installation Folder"
509 | "UseDynamicProperties" = "11:TRUE"
510 | "IsDependency" = "11:FALSE"
511 | "SourcePath" = "8:\\VsdAdminFolderDlg.wid"
512 | "Properties"
513 | {
514 | "BannerBitmap"
515 | {
516 | "Name" = "8:BannerBitmap"
517 | "DisplayName" = "8:#1001"
518 | "Description" = "8:#1101"
519 | "Type" = "3:8"
520 | "ContextData" = "8:Bitmap"
521 | "Attributes" = "3:4"
522 | "Setting" = "3:1"
523 | "UsePlugInResources" = "11:TRUE"
524 | }
525 | }
526 | }
527 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_3072F2758FA5450DB31275B3F4A89A8A"
528 | {
529 | "Sequence" = "3:300"
530 | "DisplayName" = "8:Confirm Installation"
531 | "UseDynamicProperties" = "11:TRUE"
532 | "IsDependency" = "11:FALSE"
533 | "SourcePath" = "8:\\VsdAdminConfirmDlg.wid"
534 | "Properties"
535 | {
536 | "BannerBitmap"
537 | {
538 | "Name" = "8:BannerBitmap"
539 | "DisplayName" = "8:#1001"
540 | "Description" = "8:#1101"
541 | "Type" = "3:8"
542 | "ContextData" = "8:Bitmap"
543 | "Attributes" = "3:4"
544 | "Setting" = "3:1"
545 | "UsePlugInResources" = "11:TRUE"
546 | }
547 | }
548 | }
549 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_894F8463C19A44BD8F395B3181FAC7F9"
550 | {
551 | "Sequence" = "3:100"
552 | "DisplayName" = "8:Welcome"
553 | "UseDynamicProperties" = "11:TRUE"
554 | "IsDependency" = "11:FALSE"
555 | "SourcePath" = "8:\\VsdAdminWelcomeDlg.wid"
556 | "Properties"
557 | {
558 | "BannerBitmap"
559 | {
560 | "Name" = "8:BannerBitmap"
561 | "DisplayName" = "8:#1001"
562 | "Description" = "8:#1101"
563 | "Type" = "3:8"
564 | "ContextData" = "8:Bitmap"
565 | "Attributes" = "3:4"
566 | "Setting" = "3:1"
567 | "UsePlugInResources" = "11:TRUE"
568 | }
569 | "CopyrightWarning"
570 | {
571 | "Name" = "8:CopyrightWarning"
572 | "DisplayName" = "8:#1002"
573 | "Description" = "8:#1102"
574 | "Type" = "3:3"
575 | "ContextData" = "8:"
576 | "Attributes" = "3:0"
577 | "Setting" = "3:1"
578 | "Value" = "8:#1202"
579 | "DefaultValue" = "8:#1202"
580 | "UsePlugInResources" = "11:TRUE"
581 | }
582 | "Welcome"
583 | {
584 | "Name" = "8:Welcome"
585 | "DisplayName" = "8:#1003"
586 | "Description" = "8:#1103"
587 | "Type" = "3:3"
588 | "ContextData" = "8:"
589 | "Attributes" = "3:0"
590 | "Setting" = "3:1"
591 | "Value" = "8:#1203"
592 | "DefaultValue" = "8:#1203"
593 | "UsePlugInResources" = "11:TRUE"
594 | }
595 | }
596 | }
597 | }
598 | }
599 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_5A1AB0A621394EF79945B91B5460E442"
600 | {
601 | "Name" = "8:#1900"
602 | "Sequence" = "3:1"
603 | "Attributes" = "3:1"
604 | "Dialogs"
605 | {
606 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_35D647F1050246FDA0A4F437AD571DC1"
607 | {
608 | "Sequence" = "3:200"
609 | "DisplayName" = "8:Installation Folder"
610 | "UseDynamicProperties" = "11:TRUE"
611 | "IsDependency" = "11:FALSE"
612 | "SourcePath" = "8:\\VsdFolderDlg.wid"
613 | "Properties"
614 | {
615 | "BannerBitmap"
616 | {
617 | "Name" = "8:BannerBitmap"
618 | "DisplayName" = "8:#1001"
619 | "Description" = "8:#1101"
620 | "Type" = "3:8"
621 | "ContextData" = "8:Bitmap"
622 | "Attributes" = "3:4"
623 | "Setting" = "3:1"
624 | "UsePlugInResources" = "11:TRUE"
625 | }
626 | "InstallAllUsersVisible"
627 | {
628 | "Name" = "8:InstallAllUsersVisible"
629 | "DisplayName" = "8:#1059"
630 | "Description" = "8:#1159"
631 | "Type" = "3:5"
632 | "ContextData" = "8:1;True=1;False=0"
633 | "Attributes" = "3:0"
634 | "Setting" = "3:0"
635 | "Value" = "3:1"
636 | "DefaultValue" = "3:1"
637 | "UsePlugInResources" = "11:TRUE"
638 | }
639 | }
640 | }
641 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_538A72BBAA9A439A85F6BD0B5D687D21"
642 | {
643 | "Sequence" = "3:300"
644 | "DisplayName" = "8:Confirm Installation"
645 | "UseDynamicProperties" = "11:TRUE"
646 | "IsDependency" = "11:FALSE"
647 | "SourcePath" = "8:\\VsdConfirmDlg.wid"
648 | "Properties"
649 | {
650 | "BannerBitmap"
651 | {
652 | "Name" = "8:BannerBitmap"
653 | "DisplayName" = "8:#1001"
654 | "Description" = "8:#1101"
655 | "Type" = "3:8"
656 | "ContextData" = "8:Bitmap"
657 | "Attributes" = "3:4"
658 | "Setting" = "3:1"
659 | "UsePlugInResources" = "11:TRUE"
660 | }
661 | }
662 | }
663 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5E4BB9CBE54C424DA782B964081B065C"
664 | {
665 | "Sequence" = "3:100"
666 | "DisplayName" = "8:Welcome"
667 | "UseDynamicProperties" = "11:TRUE"
668 | "IsDependency" = "11:FALSE"
669 | "SourcePath" = "8:\\VsdWelcomeDlg.wid"
670 | "Properties"
671 | {
672 | "BannerBitmap"
673 | {
674 | "Name" = "8:BannerBitmap"
675 | "DisplayName" = "8:#1001"
676 | "Description" = "8:#1101"
677 | "Type" = "3:8"
678 | "ContextData" = "8:Bitmap"
679 | "Attributes" = "3:4"
680 | "Setting" = "3:1"
681 | "UsePlugInResources" = "11:TRUE"
682 | }
683 | "CopyrightWarning"
684 | {
685 | "Name" = "8:CopyrightWarning"
686 | "DisplayName" = "8:#1002"
687 | "Description" = "8:#1102"
688 | "Type" = "3:3"
689 | "ContextData" = "8:"
690 | "Attributes" = "3:0"
691 | "Setting" = "3:1"
692 | "Value" = "8:#1202"
693 | "DefaultValue" = "8:#1202"
694 | "UsePlugInResources" = "11:TRUE"
695 | }
696 | "Welcome"
697 | {
698 | "Name" = "8:Welcome"
699 | "DisplayName" = "8:#1003"
700 | "Description" = "8:#1103"
701 | "Type" = "3:3"
702 | "ContextData" = "8:"
703 | "Attributes" = "3:0"
704 | "Setting" = "3:1"
705 | "Value" = "8:#1203"
706 | "DefaultValue" = "8:#1203"
707 | "UsePlugInResources" = "11:TRUE"
708 | }
709 | }
710 | }
711 | }
712 | }
713 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_70F8CA7BBECC43E48C2066357D0EAC10"
714 | {
715 | "Name" = "8:#1901"
716 | "Sequence" = "3:2"
717 | "Attributes" = "3:2"
718 | "Dialogs"
719 | {
720 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_1E8FEF619C5D46C6BEB2FC22D39F7D08"
721 | {
722 | "Sequence" = "3:100"
723 | "DisplayName" = "8:Progress"
724 | "UseDynamicProperties" = "11:TRUE"
725 | "IsDependency" = "11:FALSE"
726 | "SourcePath" = "8:\\VsdAdminProgressDlg.wid"
727 | "Properties"
728 | {
729 | "BannerBitmap"
730 | {
731 | "Name" = "8:BannerBitmap"
732 | "DisplayName" = "8:#1001"
733 | "Description" = "8:#1101"
734 | "Type" = "3:8"
735 | "ContextData" = "8:Bitmap"
736 | "Attributes" = "3:4"
737 | "Setting" = "3:1"
738 | "UsePlugInResources" = "11:TRUE"
739 | }
740 | "ShowProgress"
741 | {
742 | "Name" = "8:ShowProgress"
743 | "DisplayName" = "8:#1009"
744 | "Description" = "8:#1109"
745 | "Type" = "3:5"
746 | "ContextData" = "8:1;True=1;False=0"
747 | "Attributes" = "3:0"
748 | "Setting" = "3:0"
749 | "Value" = "3:1"
750 | "DefaultValue" = "3:1"
751 | "UsePlugInResources" = "11:TRUE"
752 | }
753 | }
754 | }
755 | }
756 | }
757 | "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_A1C6DE2ED28C4B33A6A4826D830E4A8C"
758 | {
759 | "UseDynamicProperties" = "11:FALSE"
760 | "IsDependency" = "11:FALSE"
761 | "SourcePath" = "8:\\VsdBasicDialogs.wim"
762 | }
763 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_C27EE5A9A30A410A86F960D49B9C7539"
764 | {
765 | "Name" = "8:#1902"
766 | "Sequence" = "3:1"
767 | "Attributes" = "3:3"
768 | "Dialogs"
769 | {
770 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_5E7E2D56289C47278C7B0F7A3877AAD1"
771 | {
772 | "Sequence" = "3:100"
773 | "DisplayName" = "8:Finished"
774 | "UseDynamicProperties" = "11:TRUE"
775 | "IsDependency" = "11:FALSE"
776 | "SourcePath" = "8:\\VsdFinishedDlg.wid"
777 | "Properties"
778 | {
779 | "BannerBitmap"
780 | {
781 | "Name" = "8:BannerBitmap"
782 | "DisplayName" = "8:#1001"
783 | "Description" = "8:#1101"
784 | "Type" = "3:8"
785 | "ContextData" = "8:Bitmap"
786 | "Attributes" = "3:4"
787 | "Setting" = "3:1"
788 | "UsePlugInResources" = "11:TRUE"
789 | }
790 | "UpdateText"
791 | {
792 | "Name" = "8:UpdateText"
793 | "DisplayName" = "8:#1058"
794 | "Description" = "8:#1158"
795 | "Type" = "3:15"
796 | "ContextData" = "8:"
797 | "Attributes" = "3:0"
798 | "Setting" = "3:1"
799 | "Value" = "8:#1258"
800 | "DefaultValue" = "8:#1258"
801 | "UsePlugInResources" = "11:TRUE"
802 | }
803 | }
804 | }
805 | }
806 | }
807 | "{2479F3F5-0309-486D-8047-8187E2CE5BA0}:_D7C94F7043444B69B0AB4068C43A9EDE"
808 | {
809 | "UseDynamicProperties" = "11:FALSE"
810 | "IsDependency" = "11:FALSE"
811 | "SourcePath" = "8:\\VsdUserInterface.wim"
812 | }
813 | "{DF760B10-853B-4699-99F2-AFF7185B4A62}:_FF962A920CEC4EED9C437E8564E44469"
814 | {
815 | "Name" = "8:#1902"
816 | "Sequence" = "3:2"
817 | "Attributes" = "3:3"
818 | "Dialogs"
819 | {
820 | "{688940B3-5CA9-4162-8DEE-2993FA9D8CBC}:_4502447F3D984A138B6557C1DB9175C7"
821 | {
822 | "Sequence" = "3:100"
823 | "DisplayName" = "8:Finished"
824 | "UseDynamicProperties" = "11:TRUE"
825 | "IsDependency" = "11:FALSE"
826 | "SourcePath" = "8:\\VsdAdminFinishedDlg.wid"
827 | "Properties"
828 | {
829 | "BannerBitmap"
830 | {
831 | "Name" = "8:BannerBitmap"
832 | "DisplayName" = "8:#1001"
833 | "Description" = "8:#1101"
834 | "Type" = "3:8"
835 | "ContextData" = "8:Bitmap"
836 | "Attributes" = "3:4"
837 | "Setting" = "3:1"
838 | "UsePlugInResources" = "11:TRUE"
839 | }
840 | }
841 | }
842 | }
843 | }
844 | }
845 | "MergeModule"
846 | {
847 | }
848 | "ProjectOutput"
849 | {
850 | "{5259A561-127C-4D43-A0A1-72F10C7B3BF8}:_514B7EF9EDF34AEDB25BD5622BE0143B"
851 | {
852 | "SourcePath" = "8:..\\OpenScreen\\obj\\Release\\OpenScreen.exe"
853 | "TargetName" = "8:"
854 | "Tag" = "8:"
855 | "Folder" = "8:_B519726EA64F4E3CB3EB0A6DA800C5B0"
856 | "Condition" = "8:"
857 | "Transitive" = "11:FALSE"
858 | "Vital" = "11:TRUE"
859 | "ReadOnly" = "11:FALSE"
860 | "Hidden" = "11:FALSE"
861 | "System" = "11:FALSE"
862 | "Permanent" = "11:FALSE"
863 | "SharedLegacy" = "11:FALSE"
864 | "PackageAs" = "3:1"
865 | "Register" = "3:1"
866 | "Exclude" = "11:FALSE"
867 | "IsDependency" = "11:FALSE"
868 | "IsolateTo" = "8:"
869 | "ProjectOutputGroupRegister" = "3:1"
870 | "OutputConfiguration" = "8:"
871 | "OutputGroupCanonicalName" = "8:Built"
872 | "OutputProjectGuid" = "8:{B088B160-DBC1-484C-BEF7-62BF5F15BC98}"
873 | "ShowKeyOutput" = "11:TRUE"
874 | "ExcludeFilters"
875 | {
876 | }
877 | }
878 | }
879 | }
880 | }
881 |
--------------------------------------------------------------------------------