private static void PlatformInitializeAdapters(out ReadOnlyCollection <GraphicsAdapter> adapters)
        {
            var factory = new SharpDX.DXGI.Factory1();

            var adapterCount = factory.GetAdapterCount();
            var adapterList  = new List <GraphicsAdapter>(adapterCount);

            for (var i = 0; i < adapterCount; i++)
            {
                var device = factory.GetAdapter1(i);

                var monitorCount = device.GetOutputCount();
                for (var j = 0; j < monitorCount; j++)
                {
                    var monitor = device.GetOutput(j);

                    var adapter = CreateAdapter(device, monitor);
                    adapterList.Add(adapter);

                    monitor.Dispose();
                }
            }

            factory.Dispose();

            adapters = new ReadOnlyCollection <GraphicsAdapter>(adapterList);
        }
 public void TestDXGI()
 {
     // Force to load DXGI assembly
     var factory = new Factory1();
     factory.Dispose();
     // Look for DXGI descriptor SharpDX.DXGI.ResultCode.DeviceRemoved
     var descriptor = ResultDescriptor.Find(0x887A0005);
     Assert.AreEqual(descriptor.NativeApiCode, "DXGI_ERROR_DEVICE_REMOVED");
 }
Example #3
0
        public override void Dispose()
        {
            if (dx11Device != null)
            {
                dx11Device.Dispose();
            }
            if (dx11Factory != null)
            {
                dx11Factory.Dispose();
            }
            if (dx11Output != null)
            {
                dx11Output.Dispose();
            }
            if (dx11DuplicatedOutput != null)
            {
                dx11DuplicatedOutput.Dispose();
            }
            if (dx11ScreenTexture != null)
            {
                dx11ScreenTexture.Dispose();
            }
            if (dx11ScreenResource != null)
            {
                dx11ScreenResource.Dispose();
            }
            if (dx11ScreenSurface != null)
            {
                dx11ScreenSurface.Dispose();
            }

            if (screenShot != null)
            {
                screenShot.Dispose();
            }

            dx11Device           = null;
            dx11Factory          = null;
            dx11Output           = null;
            dx11DuplicatedOutput = null;
            dx11ScreenTexture    = null;
            dx11ScreenResource   = null;
            dx11ScreenSurface    = null;
            screenShot           = null;

            bmpData = null;
            GC.SuppressFinalize(this);
        }
Example #4
0
        public void Dispose()
        {
            d2dContext.Target = null;
            bitmap.Dispose();
            d2dContext.Dispose();
            d2dDevice.Dispose();
            d2dFactory.Dispose();

            dxgiSurface.Dispose();
            swapChain.Dispose();
            dxgiFactory.Dispose();
            dxgiDevice.Dispose();

            d3dDevice.Dispose();

            form.Dispose();
        }
        public static Bitmap CaptureScreen()
        {
            // # of graphics card adapter
            const int numAdapter = 0;

            // # of output device (i.e. monitor)
            const int numOutput = 1;

            // Create DXGI Factory1
            var factory = new Factory1();
            var adapter = factory.GetAdapter1(numAdapter);

            // Create device from Adapter
            var device = new Device(adapter);

            // Get DXGI.Output
            var output = adapter.GetOutput(numOutput);
            var output1 = output.QueryInterface<Output1>();

            // Width/Height of desktop to capture
            int width = ((Rectangle)output.Description.DesktopBounds).Width;
            //width = 1024;
            int height = ((Rectangle)output.Description.DesktopBounds).Height;
            //height = 1024;

            // Create Staging texture CPU-accessible
            var textureDesc = new Texture2DDescription
            {
                CpuAccessFlags = CpuAccessFlags.Read,
                BindFlags = BindFlags.None,
                Format = Format.B8G8R8A8_UNorm,
                Width = width,
                Height = height,
                OptionFlags = ResourceOptionFlags.None,
                MipLevels = 1,
                ArraySize = 1,
                SampleDescription = { Count = 1, Quality = 0 },
                Usage = ResourceUsage.Staging
            };
            var screenTexture = new Texture2D(device, textureDesc);

            // Duplicate the output
            var duplicatedOutput = output1.DuplicateOutput(device);

            bool captureDone = false;
            Bitmap bitmap = null;

            for (int i = 0; !captureDone; i++)
            {
                try
                {
                    SharpDX.DXGI.Resource screenResource;
                    OutputDuplicateFrameInformation duplicateFrameInformation;

                    // Try to get duplicated frame within given time
                    duplicatedOutput.AcquireNextFrame(10000, out duplicateFrameInformation, out screenResource);

                    if (i > 0)
                    {
                        // copy resource into memory that can be accessed by the CPU
                        using (var screenTexture2D = screenResource.QueryInterface<Texture2D>())
                            device.ImmediateContext.CopyResource(screenTexture2D, screenTexture);

                        // Get the desktop capture texture
                        var mapSource = device.ImmediateContext.MapSubresource(screenTexture, 0, MapMode.Read, MapFlags.None);

                        // Create Drawing.Bitmap
                        bitmap = new System.Drawing.Bitmap(width, height, PixelFormat.Format32bppArgb);
                        var boundsRect = new System.Drawing.Rectangle(0, 0, width, height);

                        // Copy pixels from screen capture Texture to GDI bitmap
                        var mapDest = bitmap.LockBits(boundsRect, ImageLockMode.WriteOnly, bitmap.PixelFormat);
                        var sourcePtr = mapSource.DataPointer;
                        var destPtr = mapDest.Scan0;
                        for (int y = 0; y < height; y++)
                        {
                            // Copy a single line 
                            Utilities.CopyMemory(destPtr, sourcePtr, width * 4);

                            // Advance pointers
                            sourcePtr = IntPtr.Add(sourcePtr, mapSource.RowPitch);
                            destPtr = IntPtr.Add(destPtr, mapDest.Stride);
                        }

                        // Release source and dest locks
                        bitmap.UnlockBits(mapDest);
                        device.ImmediateContext.UnmapSubresource(screenTexture, 0);

                        // Capture done
                        captureDone = true;
                    }

                    screenResource.Dispose();
                    duplicatedOutput.ReleaseFrame();

                }
                catch (SharpDXException e)
                {
                    if (e.ResultCode.Code != SharpDX.DXGI.ResultCode.WaitTimeout.Result.Code)
                    {
                        throw e;
                    }
                }
            }

            duplicatedOutput.Dispose();
            screenTexture.Dispose();
            output1.Dispose();
            output.Dispose();
            device.Dispose();
            adapter.Dispose();
            factory.Dispose();

            return bitmap;
        }
        public void Init()
        {
            logger.Debug("DesktopDuplicationManager::Init(...)");

            CaptureMouse        = true;
            this.AllScreensRect = SystemInformation.VirtualScreen;

            //var rawRect = new RawRectangle
            //{
            //    Left = AllScreensRect.Left,
            //    Right = AllScreensRect.Right,
            //    Top = AllScreensRect.Top,
            //    Bottom = AllScreensRect.Bottom,
            //};

            // SetupRegions(rawRect, )

            SharpDX.DXGI.Factory1 dxgiFactory = null;
            Adapter1 adapter = null;
            Output   output  = null;

            try
            {
                dxgiFactory = new SharpDX.DXGI.Factory1();

                logger.Info(MediaFoundation.DxTool.LogDxAdapters(dxgiFactory.Adapters1));

                if (adapter == null)
                {// первым идет адаптер с которому подключен primary монитор
                    adapter = dxgiFactory.GetAdapter1(0);
                }

                AdapterId = adapter.Description.Luid;

                //logger.Info("Screen source info: " + adapter.Description.Description + " " + output.Description.DeviceName);

                var deviceCreationFlags =
                    //DeviceCreationFlags.Debug |
                    DeviceCreationFlags.VideoSupport |
                    DeviceCreationFlags.BgraSupport;


                device = new Device(adapter, deviceCreationFlags);
                using (var multiThread = device.QueryInterface <SharpDX.Direct3D11.Multithread>())
                {
                    multiThread.SetMultithreadProtected(true);
                }

                if (deskDupls != null)
                {
                    //...
                }


                deskDupls = new List <_DesktopDuplicator>();

                foreach (var _output in adapter.Outputs)
                {
                    var descr = _output.Description;

                    var desktopBounds = descr.DesktopBounds;

                    var desktopRect = new GDI.Rectangle
                    {
                        X      = desktopBounds.Left,
                        Y      = desktopBounds.Top,
                        Width  = desktopBounds.Right - desktopBounds.Left,
                        Height = desktopBounds.Bottom - desktopBounds.Top,
                    };

                    _DesktopDuplicator deskDupl = new _DesktopDuplicator(device);
                    deskDupl.Init(_output, desktopRect);
                    deskDupl.CaptureMouse = this.CaptureMouse;

                    deskDupls.Add(deskDupl);

                    //var rect = GDI.Rectangle.Intersect(desktopRect, SrcRect);
                    //if (rect.Width > 0 && rect.Height > 0)
                    //{
                    //    logger.Info("Screen source info: " + adapter.Description.Description + " " + descr.DeviceName);

                    //    DesktopDuplicator deskDupl = new DesktopDuplicator(device);

                    //    deskDupl.Init(_output, SrcRect);
                    //    deskDupl.CaptureMouse = this.CaptureMouse;

                    //    deskDupls.Add(deskDupl);
                    //}
                    //else
                    //{
                    //    logger.Debug("No common area: " + descr.DeviceName + " " + SrcRect.ToString());
                    //    continue;
                    //}

                    _output.Dispose();
                }
            }
            finally
            {
                if (adapter != null)
                {
                    adapter.Dispose();
                    adapter = null;
                }

                if (output != null)
                {
                    output.Dispose();
                    output = null;
                }

                if (dxgiFactory != null)
                {
                    dxgiFactory.Dispose();
                    dxgiFactory = null;
                }
            }

            compositionTexture = new Texture2D(device,
                                               new Texture2DDescription
            {
                CpuAccessFlags = CpuAccessFlags.None,
                BindFlags      = BindFlags.ShaderResource,
                Format         = Format.B8G8R8A8_UNorm,

                Width             = AllScreensRect.Width,
                Height            = AllScreensRect.Height,
                MipLevels         = 1,
                ArraySize         = 1,
                SampleDescription = { Count = 1, Quality = 0 },
                Usage             = ResourceUsage.Default,
            });


            initialized = true;
        }
Example #7
0
 public void Dispose()
 {
     _swapChain?.Dispose();
     _factory?.Dispose();
 }
        public void Run()
        {
            var form = new RenderForm("2d and 3d combined...it's like magic");
            form.KeyDown += (sender, args) => { if (args.KeyCode == Keys.Escape) form.Close(); };

            // DirectX DXGI 1.1 factory
            var factory1 = new Factory1();

            // The 1st graphics adapter
            var adapter1 = factory1.GetAdapter1(0);

            // ---------------------------------------------------------------------------------------------
            // Setup direct 3d version 11. It's context will be used to combine the two elements
            // ---------------------------------------------------------------------------------------------

            var description = new SwapChainDescription
                {
                    BufferCount = 1,
                    ModeDescription = new ModeDescription(0, 0, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                    IsWindowed = true,
                    OutputHandle = form.Handle,
                    SampleDescription = new SampleDescription(1, 0),
                    SwapEffect = SwapEffect.Discard,
                    Usage = Usage.RenderTargetOutput,
                    Flags = SwapChainFlags.AllowModeSwitch
                };

            Device11 device11;
            SwapChain swapChain;

            Device11.CreateWithSwapChain(adapter1, DeviceCreationFlags.None, description, out device11, out swapChain);

            // create a view of our render target, which is the backbuffer of the swap chain we just created
            RenderTargetView renderTargetView;
            using (var resource = Resource.FromSwapChain<Texture2D>(swapChain, 0))
                renderTargetView = new RenderTargetView(device11, resource);

            // setting a viewport is required if you want to actually see anything
            var context = device11.ImmediateContext;

            var viewport = new Viewport(0.0f, 0.0f, form.ClientSize.Width, form.ClientSize.Height);
            context.OutputMerger.SetTargets(renderTargetView);
            context.Rasterizer.SetViewports(viewport);

            //
            // Create the DirectX11 texture2D. This texture will be shared with the DirectX10 device.
            //
            // The DirectX10 device will be used to render text onto this texture.
            // DirectX11 will then draw this texture (blended) onto the screen.
            // The KeyedMutex flag is required in order to share this resource between the two devices.
            var textureD3D11 = new Texture2D(device11, new Texture2DDescription
            {
                Width = form.ClientSize.Width,
                Height = form.ClientSize.Height,
                MipLevels = 1,
                ArraySize = 1,
                Format = Format.B8G8R8A8_UNorm,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.SharedKeyedmutex
            });

            // ---------------------------------------------------------------------------------------------
            // Setup a direct 3d version 10.1 adapter
            // ---------------------------------------------------------------------------------------------
            var device10 = new Device10(adapter1, SharpDX.Direct3D10.DeviceCreationFlags.BgraSupport, FeatureLevel.Level_10_0);

            // ---------------------------------------------------------------------------------------------
            // Setup Direct 2d
            // ---------------------------------------------------------------------------------------------

            // Direct2D Factory
            var factory2D = new SharpDX.Direct2D1.Factory(FactoryType.SingleThreaded, DebugLevel.Information);

            // Here we bind the texture we've created on our direct3d11 device through the direct3d10
            // to the direct 2d render target....
            var sharedResource = textureD3D11.QueryInterface<SharpDX.DXGI.Resource>();
            var textureD3D10 = device10.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(sharedResource.SharedHandle);

            var surface = textureD3D10.AsSurface();
            var rtp = new RenderTargetProperties
                {
                    MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_10,
                    Type = RenderTargetType.Hardware,
                    PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)
                };

            var renderTarget2D = new RenderTarget(factory2D, surface, rtp);
            var solidColorBrush = new SolidColorBrush(renderTarget2D, Colors.Red);

            // ---------------------------------------------------------------------------------------------------
            // Setup the rendering data
            // ---------------------------------------------------------------------------------------------------

            // Load Effect. This includes both the vertex and pixel shaders.
            // Also can include more than one technique.
            ShaderBytecode shaderByteCode = ShaderBytecode.CompileFromFile(
                "effectDx11.fx",
                "fx_5_0",
                ShaderFlags.EnableStrictness);

            var effect = new Effect(device11, shaderByteCode);

            // create triangle vertex data, making sure to rewind the stream afterward
            var verticesTriangle = new DataStream(VertexPositionColor.SizeInBytes * 3, true, true);
            verticesTriangle.Write(new VertexPositionColor(new Vector3(0.0f, 0.5f, 0.5f),new Color4(1.0f, 0.0f, 0.0f, 1.0f)));
            verticesTriangle.Write(new VertexPositionColor(new Vector3(0.5f, -0.5f, 0.5f),new Color4(0.0f, 1.0f, 0.0f, 1.0f)));
            verticesTriangle.Write(new VertexPositionColor(new Vector3(-0.5f, -0.5f, 0.5f),new Color4(0.0f, 0.0f, 1.0f, 1.0f)));

            verticesTriangle.Position = 0;

            // create the triangle vertex layout and buffer
            var layoutColor = new InputLayout(device11, effect.GetTechniqueByName("Color").GetPassByIndex(0).Description.Signature, VertexPositionColor.inputElements);
            var vertexBufferColor = new Buffer(device11, verticesTriangle, (int)verticesTriangle.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            verticesTriangle.Close();

            // create overlay vertex data, making sure to rewind the stream afterward
            // Top Left of screen is -1, +1
            // Bottom Right of screen is +1, -1
            var verticesText = new DataStream(VertexPositionTexture.SizeInBytes * 4, true, true);
            verticesText.Write(new VertexPositionTexture(new Vector3(-1, 1, 0),new Vector2(0, 0f)));
            verticesText.Write(new VertexPositionTexture(new Vector3(1, 1, 0),new Vector2(1, 0)));
            verticesText.Write(new VertexPositionTexture(new Vector3(-1, -1, 0),new Vector2(0, 1)));
            verticesText.Write(new VertexPositionTexture(new Vector3(1, -1, 0),new Vector2(1, 1)));

            verticesText.Position = 0;

            // create the overlay vertex layout and buffer
            var layoutOverlay = new InputLayout(device11, effect.GetTechniqueByName("Overlay").GetPassByIndex(0).Description.Signature, VertexPositionTexture.inputElements);
            var vertexBufferOverlay = new Buffer(device11, verticesText, (int)verticesText.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
            verticesText.Close();

            // Think of the shared textureD3D10 as an overlay.
            // The overlay needs to show the 2d content but let the underlying triangle (or whatever)
            // show thru, which is accomplished by blending.
            var bsd = new BlendStateDescription();
            bsd.RenderTarget[0].IsBlendEnabled = true;
            bsd.RenderTarget[0].SourceBlend = BlendOption.SourceColor;
            bsd.RenderTarget[0].DestinationBlend = BlendOption.BlendFactor;
            bsd.RenderTarget[0].BlendOperation = BlendOperation.Add;
            bsd.RenderTarget[0].SourceAlphaBlend = BlendOption.One;
            bsd.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
            bsd.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
            bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

            var blendStateTransparent = new BlendState(device11, bsd);

            // ---------------------------------------------------------------------------------------------------
            // Create and tesselate an ellipse
            // ---------------------------------------------------------------------------------------------------
            var center = new DrawingPointF(form.ClientSize.Width/2.0f, form.ClientSize.Height/2.0f);
            var ellipse = new EllipseGeometry(factory2D, new Ellipse(center, form.ClientSize.Width / 2.0f, form.ClientSize.Height / 2.0f));

            // Populate a PathGeometry from Ellipse tessellation
            var tesselatedGeometry = new PathGeometry(factory2D);
            _geometrySink = tesselatedGeometry.Open();

            // Force RoundLineJoin otherwise the tesselated looks buggy at line joins
            _geometrySink.SetSegmentFlags(PathSegment.ForceRoundLineJoin);

            // Tesselate the ellipse to our TessellationSink
            ellipse.Tessellate(1, this);

            _geometrySink.Close();

            // ---------------------------------------------------------------------------------------------------
            // Acquire the mutexes. These are needed to assure the device in use has exclusive access to the surface
            // ---------------------------------------------------------------------------------------------------

            var device10Mutex = textureD3D10.QueryInterface<KeyedMutex>();
            var device11Mutex = textureD3D11.QueryInterface<KeyedMutex>();

            // ---------------------------------------------------------------------------------------------------
            // Main rendering loop
            // ---------------------------------------------------------------------------------------------------

            bool first = true;

            RenderLoop
                .Run(form,
                     () =>
                         {
                             if(first)
                             {
                                 form.Activate();
                                 first = false;
                             }

                             // clear the render target to black
                             context.ClearRenderTargetView(renderTargetView, Colors.DarkSlateGray);

                             // Draw the triangle
                             context.InputAssembler.InputLayout = layoutColor;
                             context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
                             context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferColor, VertexPositionColor.SizeInBytes, 0));
                             context.OutputMerger.BlendState = null;
                             var currentTechnique = effect.GetTechniqueByName("Color");
                             for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass)
                             {
                                 using (var effectPass = currentTechnique.GetPassByIndex(pass))
                                 {
                                     System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass");
                                     effectPass.Apply(context);
                                 }
                                 context.Draw(3, 0);
                             };

                             // Draw Ellipse on the shared Texture2D
                             device10Mutex.Acquire(0, 100);
                             renderTarget2D.BeginDraw();
                             renderTarget2D.Clear(Colors.Black);
                             renderTarget2D.DrawGeometry(tesselatedGeometry, solidColorBrush);
                             renderTarget2D.DrawEllipse(new Ellipse(center, 200, 200), solidColorBrush, 20, null);
                             renderTarget2D.EndDraw();
                             device10Mutex.Release(0);

                             // Draw the shared texture2D onto the screen, blending the 2d content in
                             device11Mutex.Acquire(0, 100);
                             var srv = new ShaderResourceView(device11, textureD3D11);
                             effect.GetVariableByName("g_Overlay").AsShaderResource().SetResource(srv);
                             context.InputAssembler.InputLayout = layoutOverlay;
                             context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip;
                             context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferOverlay, VertexPositionTexture.SizeInBytes, 0));
                             context.OutputMerger.BlendState = blendStateTransparent;
                             currentTechnique = effect.GetTechniqueByName("Overlay");

                             for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass)
                             {
                                 using (var effectPass = currentTechnique.GetPassByIndex(pass))
                                 {
                                     System.Diagnostics.Debug.Assert(effectPass.IsValid, "Invalid EffectPass");
                                     effectPass.Apply(context);
                                 }
                                 context.Draw(4, 0);
                             }
                             srv.Dispose();
                             device11Mutex.Release(0);

                             swapChain.Present(0, PresentFlags.None);
                         });

            // dispose everything
            vertexBufferColor.Dispose();
            vertexBufferOverlay.Dispose();
            layoutColor.Dispose();
            layoutOverlay.Dispose();
            effect.Dispose();
            shaderByteCode.Dispose();
            renderTarget2D.Dispose();
            swapChain.Dispose();
            device11.Dispose();
            device10.Dispose();
            textureD3D10.Dispose();
            textureD3D11.Dispose();
            factory1.Dispose();
            adapter1.Dispose();
            sharedResource.Dispose();
            factory2D.Dispose();
            surface.Dispose();
            solidColorBrush.Dispose();
            blendStateTransparent.Dispose();

            device10Mutex.Dispose();
            device11Mutex.Dispose();
        }
Example #9
0
        public ScreenDublicator()
        {
            Adapter adapter = null;
            Output output = null;
            Output1 output1 = null;
            try
            { 
                //Адаптер
                
                adapter = new Factory1().GetAdapter1(this.ADAPTER);
            
                //Устройство

                this._device = new Device(adapter);
                output = adapter.GetOutput(this.MONITOR);
            
                //Выход

                output1 = output.QueryInterface<Output1>();
                this._outputDesc = output.Description;
                this._width = this._outputDesc.DesktopBounds.Right - this._outputDesc.DesktopBounds.Left;
                this._height = this._outputDesc.DesktopBounds.Bottom - this._outputDesc.DesktopBounds.Top;
                this._textureDesc = new Texture2DDescription()
                {
                    CpuAccessFlags = CpuAccessFlags.Read,
                    BindFlags = BindFlags.None,
                    Format = Format.B8G8R8A8_UNorm,
                    Width = this._width,
                    Height = this._height,
                    OptionFlags = ResourceOptionFlags.None,
                    MipLevels = 1,
                    ArraySize = 1,
                    SampleDescription = { Count = 1, Quality = 0 },
                    Usage = ResourceUsage.Staging
                };
                this._outputDublication = output1.DuplicateOutput(this._device);

                //Текстура

                this._desktopTexture = new Texture2D(this._device, this._textureDesc);
            }
            catch(SharpDXException sdxex)
            {
                if (sdxex.ResultCode.Code == SharpDX.DXGI.ResultCode.NotCurrentlyAvailable.Result.Code)
                {
                    throw new ScreenDublicatorException("Достигнут предел приложений, работающих с API)");
                }
                else
                {
                    string message = String.Format("Не удалось создать дублирующий выход");
                    Debug.WriteLine(message + "\n{0}\n{1}", sdxex.Message, sdxex.StackTrace);
                    throw new ScreenDublicatorException(message);
                }
            }
            catch(Exception ex)
            {
                string message = String.Format("Ошибка при инициализации объекта\n{0}\n{1}", ex.Message, ex.StackTrace);
                throw new ScreenDublicatorException(message);
            }
            finally
            {
                if(adapter != null) { adapter.Dispose(); }
                if(output != null) { output.Dispose(); }
                if(output1 != null) { output1.Dispose(); }
            }
        }