Git Product home page Git Product logo

direct3dhook's People

Contributors

gitter-badger avatar justinstenning avatar marcellvokk avatar mathewsachin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

direct3dhook's Issues

DrawLine in D3D11 Hook?

Hey @spazzarama !

Is there any possibility to easily add Lines Drawing to DXOverlayEngine in directX 11 ??

  • Is it possible to make PresentHook work with hooked APP resizing?

Capturing screenshot causes DirectX application to crash

My application captures a screenshot of a 32-bit DirectX application (BlueStacks) whenever it needs it. It works fine, but after about 150 calls, it crashes BlueStacks (not the program that is performing the capture). So I tested it with the "Load Test" button on the TestScreenshot application. It does not crash BlueStacks. However, if I execute the code below from a button click in the TestScreenshot application, it does crash BlueStacks. Is there something I am doing wrong with this? Here is the code:

private void button1_Click(object sender, EventArgs e)
{ 
    new Thread(testCapture).Start();
}
public void testCapture()
{
    for (int i = 0; i < 200; i++)
    {
        Bitmap b = _captureProcess.CaptureInterface.GetScreenshot().CapturedBitmap.ToBitmap();
        b.Dispose();
     }
}

Memory leak in captured program

Dear Spazzarama,

I've noticed that, when capturing VLC, the memory footprint of VLC remains stable, until I start capturing screenshots. In that case, VLC's memory consumption will quickly reach > 1 Gb (on Windows 8). How can I prevent this from happening?

Cheers,
Erik

Font Ghosting/Crashing

My Repo:
https://github.com/Icehunter/ffxivapp-hooker

That is a combined implementation between your library and the one stored in:
https://github.com/HearthstoneTracker/HearthstoneTracker

I've removed some extra files and tried to go back to as much of the basic that I can.

I've got the font rendering now without any issues and I'll be working on your overlay engine as well (that's another thing all together).

I have two issues with mine currently that I can't explain.

Ghosting as seen here:
directx-ghosting

The top left smaller one is the original.

Occasional crashing when switching between full screen/windowed but with no consistent behavior.

Is this something you've seen or anyone else viewing this issue?

Ironically while in-game sometimes the FPS will lock itself to an NPC name and even if I rotate the camera it sicks with the NPC. Down the road that would be awesome to do on purpose, like drawing an arrow in the direction to run to avoid something.

Thanks for your hard work!

Why i can't use breakpoints on the Capture project in the namespace Capture.Hook ?

For example i added some breakpoints in the Capture project in the FramesPerSecond.cs but when i'm running the program what i'm doing it never stop at this breakpoints.
If i'm adding breakpoints to the Interface part of the Capture project it does get and stop at this breakpoints.

Any ideas why it never stop at the FramesPerSecond.cs ? And can i fix it ?

Just to mention if it's any important i'm running the program as admin.

PresentHook Exception when trying to Record Screens from Rise of the Tomb Raider

Hello,

First, thank you so much for creating this tool! Without it I don't know how I'd capture screenshots from Direct3D games.

Most games (like Portal 2) work fine using the capture.dll straight from a clone of master (ie: I made no changes to the Direct3DHook code). When I try to get screenshots from Rise of the Tomb Raider the following exception occurs:

DXHookD3D11: PresentHook: Request Start

DXHookD3D11: PresentHook: Exeception: SharpDX.SharpDXException: SharpDX.SharpDXException: HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect.

at SharpDX.Result.CheckError()
at SharpDX.Direct3D11.Device.CreateTexture2D(Texture2DDescription& descRef, DataBox[] initialDataRef, Texture2D texture2DOut)
at SharpDX.Direct3D11.Texture2D..ctor(Device device, Texture2DDescription description)
at Capture.Hook.DXHookD3D11.EnsureResources(Device device, Texture2DDescription description, Rectangle captureRegion, ScreenshotRequest request) in C:\Users\fores\git\Direct3DHook\Capture\Hook\DXHookD3D11.cs:line 280
at Capture.Hook.DXHookD3D11.PresentHook(IntPtr swapChainPtr, Int32 syncInterval, PresentFlags flags) in C:\Users\fores\git\Direct3DHook\Capture\Hook\DXHookD3D11.cs:line 355

When I load the symbols for capture.dll the debugger never stops at the code listed in this exception. For reference, I have DirectX12 installed and am running Windows 10. I've tried the game with DirectX 12 enabled and disabled.

This could very well be an issue with my code, but that exception doesn't tell me what argument is wrong or why it is wrong.

Here is my calling code:

`
using System;
using System.Diagnostics;
using System.Threading;
using System.Drawing;
using Capture.Hook;
using Capture.Interface;
using Capture;
using System.IO;

namespace GamePlayTest
{
    class Direct3DVideo : Video
    {
        private const int MAX_HOOK_RETRY = 20;
        private int processId = 0;
        private Process process;
        private CaptureProcess captureProcess;
        private int frame = 0;
        private Size? resize = null;
        private OutputDirectory outputDirectory;
        private static Stopwatch stopWatch;


        /// <summary>
        /// Generates the Videos by gathering frames and processing via FFMPEG.
        /// </summary>
        public override void RecordScreenTillGameEnd(string exe, OutputDirectory outputDirectoryArg, CustomMessageBox alertBox, Thread workerThreadArg)
        {
            stopWatch = null;
            workerThread = workerThreadArg;
            outputDirectory = outputDirectoryArg;
            int retry = 45;
            bool found = false;

            do
            {
                if (WinProcess.Count(exe) <= 0) retry--;
                else found = true;
            } while (retry > 0 && !found);

            AttachProcess(exe);
            stopWatch = Stopwatch.StartNew(); //creates and start the instance of Stopwatch
            RequestD3DScreenShot();

            workerThread.Join();

            alertBox.Show();
        }

        public override bool IsStarted()
        {
            return (stopWatch != null);
        }

        void RequestD3DScreenShot()
        {
            captureProcess.CaptureInterface.BeginGetScreenshot(new Rectangle(0, 0, 0, 0), new TimeSpan(0, 0, 2), 
                Callback, resize, (ImageFormat)Enum.Parse(typeof(ImageFormat), "Bitmap"));
        }

        private void AttachProcess(string exe)
        {
            int retry = MAX_HOOK_RETRY;
            while (captureProcess == null && --retry > 0)
            {
                Thread.Sleep(100);
                Process[] processes = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(exe));
                foreach (Process currProcess in processes)
                {
                    // Simply attach to the first one found.

                    // If the process doesn't have a mainwindowhandle yet, skip it (we need to be able to get the hwnd to set foreground etc)
                    if (currProcess.MainWindowHandle == IntPtr.Zero || HookManager.IsHooked(currProcess.Id))
                    {
                        continue;
                    }

                    Direct3DVersion direct3DVersion = Direct3DVersion.AutoDetect;

                    CaptureConfig cc = new CaptureConfig()
                    {
                        Direct3DVersion = direct3DVersion,
                        ShowOverlay = false
                    };

                    processId = currProcess.Id;
                    process = currProcess;

                    var captureInterface = new CaptureInterface();
                    captureInterface.RemoteMessage += new MessageReceivedEvent(CaptureInterface_RemoteMessage);
                    captureProcess = new CaptureProcess(process, cc, captureInterface);

                    break;
                }
                Thread.Sleep(10);
            }

            if (captureProcess == null)
            {
                ShowUser.Exception("No DirectX executable found matching: '" + exe + "' !  Is this a DirectX game?");
                Environment.Exit(0);
            }
        }

        /// <summary>
        /// The callback for when the screenshot has been taken
        /// </summary>
        /// <param name="clientPID"></param>
        /// <param name="status"></param>
        /// <param name="screenshotResponse"></param>
        void Callback(IAsyncResult result)
        {
            try
            {
                using (Screenshot screenshot = captureProcess.CaptureInterface.EndGetScreenshot(result))
                {
                    if (screenshot != null && screenshot.Data != null)
                    {
                        if (image != null)
                        {
                            image.Dispose();
                        }

                        image = screenshot.ToBitmap();
                        if (resize == null)
                        {
                            resize = new Size(image.Width / SIZE_MODIFIER, image.Height / SIZE_MODIFIER);
                        }
                        else
                        {
                            AppendTime();
                            image.Save(outputDirectory.pathToArtifacts + "\\tempGameScreenshot" + frame.ToString().PadLeft(5, '0') + ".png",
                                System.Drawing.Imaging.ImageFormat.Png);
                            frame++;
                        }
                    }

                    if (workerThread.IsAlive)
                    {
                        while (frame >= ExpectedFrames(stopWatch.ElapsedMilliseconds))
                        {
                            Thread.Sleep(SLEEP_INTERVAL);
                        }

                        Thread t = new Thread(new ThreadStart(RequestD3DScreenShot));
                        t.Start();
                    }
                    else
                    {
                        Logger.log.Info("Total frames: " + frame + " Expected frames: " + (ExpectedFrames(stopWatch.ElapsedMilliseconds) - 1));
                        Logger.log.Info("Done getting shots from D3D.");
                    }
                }
            }
            catch (System.Runtime.Remoting.RemotingException ex)
            {
                Logger.log.Debug(ex.Message);
            }
        }

        private void AppendTime()
        {
            using (Graphics graphics = Graphics.FromImage(image))
            {
                using (Font arialFont = new Font("Arial", 10))
                {
                    graphics.DrawString(Controller.time.CurrentTime(), arialFont, Brushes.DarkRed, new PointF(0f, 0f));
                }
            }
        }

        public override void StopRecording(CustomMessageBox alertBox)
        {
            int cnt = 1;
            Thread ffmpgSave = LaunchSave();

            do
            {
                alertBox.descriptionLabel.Text = "Please wait " + new string('.', cnt++ % 10);
                alertBox.UpdateDescription();
                Thread.Sleep(Controller.THREAD_SLEEP_TIME);
            } while (ffmpgSave.IsAlive);
        }

        public Thread LaunchSave()
        {
            Thread workerThread = new Thread(this.Save);
            workerThread.Start();
            Logger.log.Info("Starting monitor game thread...");
            return workerThread;
        }

        private void Save()
        {
            if (resize == null)
            {
                return;
            }

            string arg = "-framerate " + VID_FRAME_FPS + " -i " + outputDirectory.pathToArtifacts +
                "\\tempGameScreenshot%05d.png -c:v libx264 -pix_fmt yuv420p -preset ultrafast -s " + 
                resize.Value.Width + "x" + resize.Value.Height + CODEC_CMDS + "-y \"" + outputDirectory.pathToVideo;

            Logger.log.Debug("Launching FFMPEG with arguments:" + arg);
            Process proc = new Process
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = "ffmpeg",
                    Arguments = arg,
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true,
                    RedirectStandardError = true
                }
            };
            proc.Start();

            // May want to remove this ffmpeg info from the console in the future.
            while (!proc.StandardError.EndOfStream)
            {
                Logger.log.Error(proc.StandardError.ReadLine());
            }
#if DEBUG
            while (!proc.StandardOutput.EndOfStream)
            {
                Logger.log.Debug(proc.StandardOutput.ReadLine());
            }
#endif
            var dir = new DirectoryInfo(outputDirectory.pathToArtifacts);

            foreach (var file in dir.EnumerateFiles("tempGameScreenshot*.png"))
            {
                file.Delete();
            }
        }

        /// <summary>
        /// Display messages from the target process
        /// </summary>
        /// <param name="message"></param>
        private void CaptureInterface_RemoteMessage(MessageReceivedEventArgs message)
        {
            Logger.log.Info(message);
        }
    }
}

`

Any help would be greatly appreciated. Thank you!

Memory leak in ImageElement

Upon further inspection using a bigger image, recreating a new ImageElement every frame does indeed create a memory leak.

Some code.

The bitmap created on start up:
var bm = new Bitmap(/* path to big image*/);

The main loop:

using (Bitmap doubleBuffer = new Bitmap(ScreenSize.Width, ScreenSize.Height,
            PixelFormat.Format32bppArgb))
{
    using (var graphics = Graphics.FromImage(doubleBuffer))
    {
        graphics.DrawImage(bm, new Point(0, 0));
    }

    DirectXHook.SetBitmap(doubleBuffer);
}

Same results can be achieved by just calling SetBitmap without a doublebuffer.

DirectXHook.SetBitmap(bm);

SetBitmap method, where this.OverlayEngine.Overlays[0].Elements[1] is an ImageElement

((ImageElement)this.OverlayEngine.Overlays[0].Elements[1]).Dispose();
this.OverlayEngine.Overlays[0].Elements.RemoveAt(1);
this.OverlayEngine.Overlays[0].Elements.Add(new Common.ImageElement(bt, true)
{
    Location = new System.Drawing.Point(0, 0)
});

this.OverlayEngine.FlushCache();

Finally, FlushCache method

public void FlushCache()
{
    lock (_imageCache)
    {
        foreach (var dxImage in _imageCache)
        {
            dxImage.Value?.Dispose();
            ((ImageElement)dxImage.Key).Dispose();
        }

        foreach (var element in Overlays[0].Elements.OfType<ImageElement>())
        {
            DXImage result = ToDispose(new DXImage(_device, _deviceContext));
            result.Initialise(element.Bitmap);
            _imageCache[element] = result;
        }
    }
}

SharpDX.ObjectTracker output

Count per Type:
BlendState : 1
Buffer : 2
Device : 2
DeviceContext : 3
Effect : 1
InputLayout : 1
RenderTargetView : 1
ShaderResourceView : 2
SwapChain : 28
Texture2D : 50

Texture2D never goes above 50

Test Screenshot Crashes with Borderlands 2 and XCOM Enemy Within

Thanks for the great work!

When trying to Inject to XComEW.exe TestScreenshot produces the exception below and fails.

The test is on a Steam game XCOM Enemy Within, running on Windows 8.1 64bit
As a positive result, the Steam game Wasteland 2 overlays work fine on the same machine (using Direct3D v9)

I'm not compentent to understand any of the below I'm afraid, so I was hoping you could determine what the issue is.

Here are the error details:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected C++ completion routine. (Code: 14)

Server stack trace: 
   at EasyHook.NativeAPI.Force(Int32 InErrorCode)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at EasyHook.HelperServiceInterface.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHook\Capture\CaptureProcess.cs:line 67
   --- End of inner exception stack trace ---
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in i:\code\Direct3DHook\Capture\CaptureProcess.cs:line 92
   at TestScreenshot.Form1.AttachProcess() in i:\code\Direct3DHook\TestScreenshot\Form1.cs:line 134
   at TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) in i:\code\Direct3DHook\TestScreenshot\Form1.cs:line 52
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34014 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
----------------------------------------
TestScreenshot
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///I:/code/Direct3DHook/bin/TestScreenshot.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34003 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
EasyHook
    Assembly Version: 2.7.4761.0
    Win32 Version: 2.7.4761.0
    CodeBase: file:///I:/code/Direct3DHook/bin/EasyHook.DLL
----------------------------------------
Capture
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///I:/code/Direct3DHook/bin/Capture.DLL
----------------------------------------
System.Runtime.Remoting
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.34107 built by: FX45W81RTMGDR
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
System.Configuration
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.33440 built by: FX45W81RTMREL
    CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------

After making inject and then in the game i injected to i'm doing Alt+Tab the game crash any idea why ?

The game in this case is using DX9.
If i just run the game and make many times Alt+Tab(to return back to windows) it's working good no problems i can keep making Alt+Tab and return to the game and so on.

But once i did inject and now im in the game when i'm doing Alt+Tab after one time or two times the game crash for example: BouT2.exe has stopped working...
And it happen only after doing inject in the program.

I can make choose debug or close if i make debug using my visual studio 2012 i see:

Unhandled exception at 0x76FDF8A2 (ntdll.dll) in BouT2.exe: 0xC0000005: Access violation writing location 0x0000009C.

Why it happen only after making inject and then when doing in the game Alt+Tab to get to the windows ? And idea how to solve it ?

Direct3D auto-detect incorrectly finds DirectX 11 for DirectX 9/10 application

Can't remember the exact scenario now, but under some circumstances the DirectX 11 library will be loaded for a DirectX 9/10 application.

The current logic will incorrectly choose DirectX 11. Instead we could hook all loaded DirectX versions and then we will be correctly capturing which ever is actually presenting.

Exception is thrown when trying to capture screenshot on dx11 game how can i fix it ?

I'm running battlefield bad company 2 and it's working on dx11.
When i'm clicking on the Request Capture button after some seconds it's throwing an exception in Form1.cs in the method DoRequest() the exception message is:

Could not set process window to the foreground

It didn't happen on DX9 game only on this battlefield bad company 2.

This is the full exception error message:

System.Exception was unhandled
HResult=-2146233088
Message=Could not set process window to the foreground
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at TestScreenshot.Form1.DoRequest() in c:\Temp\spazz\Direct3DHook-master\TestScreenshot\Form1.cs:line 218
at TestScreenshot.Form1.btnCapture_Click(Object sender, EventArgs e) in c:\Temp\spazz\Direct3DHook-master\TestScreenshot\Form1.cs:line 196
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at TestScreenshot.Program.Main() in c:\Temp\spazz\Direct3DHook-master\TestScreenshot\Program.cs:line 18
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

Line 196 in form1 is:

DoRequest();

And line 218 in form1 is: progressBar1.Invoke(new MethodInvoker(delegate()
And the whole code in the DoRequest() method is marked with yellow when the exception is show up.

And so far it happen only on dx11 game battlefield bad company 2 and only when i click the button Request Capture

when i hook ppsspp direct3d9, it can not capture anything

image

Debug: DXHookD3D9: Hook: End
Debug: DXHookD3D9: Hook: Device created
Debug: DXHookD3D9: Hook: Before device creation
Debug: DXHookD3D9: Hook: Begin
Debug: Autodetect found Direct3D 9
Information: Remote process is a 32-bit process.
Information: Injected into process Id:18368.

qq 20170526145131

screenshot is null and i do not know how to find what is the reason and deal with it

Could not load file or assembly SharpDX.DXGI

I keep getting the error below. I am using VS2013 (Windows 8). As you can see, I already enabled the logging for assembly binding.

Information: Disconnecting from process 10488
Error: Error in InitialiseHook: System.IO.FileNotFoundException: Could not load file or assembly 'SharpDX.DXGI, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a' or one of its dependencies. The system cannot find the file specified.
File name: 'SharpDX.DXGI, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a'
   at Capture.Hook.DXHookD3D11.Hook()
   at Capture.EntryPoint.InitialiseDirectXHook(CaptureConfig config)

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  D:\Program Files (x86)\Origin Games\Need for Speed(TM) Most Wanted\NFS13.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = SharpDX.DXGI, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a
 (Fully-specified)
LOG: Appbase = file:///D:/Program Files (x86)/Origin Games/Need for Speed(TM) Most Wanted/
LOG: Initial PrivatePath = NULL
Calling assembly : Capture, Version=1.0.0.0, Culture=neutral, PublicKeyToken=025161b358ea1a36.
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: SharpDX.DXGI, Version=2.4.2.0, Culture=neutral, PublicKeyToken=627a3d6d1956f55a
LOG: Attempting download of new URL file:///D:/Program Files (x86)/Origin Games/Need for Speed(TM) Most Wanted/SharpDX.DXGI.DLL.
LOG: Attempting download of new URL file:///D:/Program Files (x86)/Origin Games/Need for Speed(TM) Most Wanted/SharpDX.DXGI/SharpDX.DXGI.DLL.
LOG: Attempting download of new URL file:///D:/Program Files (x86)/Origin Games/Need for Speed(TM) Most Wanted/SharpDX.DXGI.EXE.
LOG: Attempting download of new URL file:///D:/Program Files (x86)/Origin Games/Need for Speed(TM) Most Wanted/SharpDX.DXGI/SharpDX.DXGI.EXE.

Debug: Autodetect found Direct3D 11
Information: Remote process is a 32-bit process.
Information: Injected into process Id:10488.

After Injection Game FPS becomes 15

Hello Justin,

After the last commit I think something in Direct3DHook got broken. After injecting into any game the game FPS becomes too low to play and the TestScreenshot software gives an error:

Debug: DXHookD3D9: System.NullReferenceException: Object reference not set to an instance of an object.
at Capture.Hook.DXHookD3D9.DoCaptureRenderTarget(Device device, String hook) in C:\Users\User\Desktop\New\Direct3DHook-master\Capture\Hook\DXHookD3D9.cs:line 381
Debug: DXHookD3D9: System.NullReferenceException: Object reference not set to an instance of an object.
...
at System.Drawing.Bitmap..ctor(String filename)
at Capture.Hook.Common.ImageElement..ctor(String filename) in C:\Users\User\Desktop\New\Direct3DHook-master\Capture\Hook\Common\ImageElement.cs:line 34
at Capture.Hook.DXHookD3D9.DoCaptureRenderTarget(Device device, String hook) in C:\Users\User\Desktop\New\Direct3DHook-master\Capture\Hook\DXHookD3D9.cs:line 389
Debug: DXHookD3D9: Hook: End
Debug: DXHookD3D9: Hook: DeviceEx created - PresentEx supported
Debug: DXHookD3D9: Hook: Direct3DEx...
Debug: DXHookD3D9: Hook: Device created
Debug: DXHookD3D9: Hook: Before device creation
Debug: DXHookD3D9: Hook: Begin
Debug: Autodetect found Direct3D 9
Information: Remote process is a 32-bit process.
Information: Injected into process Id:27676.

No FPS overlay is also coming. Just the huge FPS lag and this nullreference error continuously.

Hope you will solve it soon.

Thanks in advance....

Injection to the target process failed. Unable to load DLL 'EasyHook32.dll'

I cloned the project and compiled it. However when I entered the process name and click Inject, TestScreenshot.exe crashed. Here is the exception message:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.DllNotFoundException: Unable to load DLL 'EasyHook32.dll': The specified procedure could not be found. (Exception from HRESULT: 0x8007007F)
   at EasyHook.NativeAPI_x86.RhInjectLibrary(Int32 InTargetPID, Int32 InWakeUpTID, Int32 InInjectionOptions, String InLibraryPath_x86, String InLibraryPath_x64, IntPtr InPassThruBuffer, Int32 InPassThruSize)
   at EasyHook.NativeAPI.RhInjectLibraryEx(Int32 InTargetPID, Int32 InWakeUpTID, Int32 InInjectionOptions, String InLibraryPath_x86, String InLibraryPath_x64, IntPtr InPassThruBuffer, Int32 InPassThruSize)
   at EasyHook.RemoteHooking.InjectEx(Int32 InHostPID, Int32 InTargetPID, Int32 InWakeUpTID, Int32 InNativeOptions, String InLibraryPath_x86, String InLibraryPath_x64, Boolean InCanBypassWOW64, Boolean InCanCreateService, Boolean InRequireStrongName, Object[] InPassThruArgs)
   at EasyHook.RemoteHooking.Inject(Int32 InTargetPID, InjectionOptions InOptions, String InLibraryPath_x86, String InLibraryPath_x64, Object[] InPassThruArgs)
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in c:\Download\Direct3DHook-master\Direct3DHook-master\Capture\CaptureProcess.cs:line 67
   --- End of inner exception stack trace ---
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in c:\Download\Direct3DHook-master\Direct3DHook-master\Capture\CaptureProcess.cs:line 79
   at TestScreenshot.Form1.AttachProcess() in c:\Download\Direct3DHook-master\Direct3DHook-master\TestScreenshot\Form1.cs:line 131
   at TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) in c:\Download\Direct3DHook-master\Direct3DHook-master\TestScreenshot\Form1.cs:line 52
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.2034 (RTMLDR.030319-2000)
    CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
TestScreenshot
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Download/Direct3DHook-master/Direct3DHook-master/bin/TestScreenshot.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.2003 built by: RTMLDR
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.2001 built by: RTMLDR
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.2001 built by: RTMLDR
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
Capture
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Download/Direct3DHook-master/Direct3DHook-master/bin/Capture.DLL
----------------------------------------
EasyHook
    Assembly Version: 2.7.5726.0
    Win32 Version: 2.7.5726.0
    CodeBase: file:///C:/Download/Direct3DHook-master/Direct3DHook-master/bin/EasyHook.DLL
----------------------------------------
System.Runtime.Remoting
    Assembly Version: 4.0.0.0
    Win32 Version: 4.0.30319.1 (RTMRel.030319-0100)
    CodeBase: file:///C:/WINDOWS/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

I am sure that the directory of TestScreenshot.exe has the dll "EasyHook32.dll".
So why would this happened?

Games that Change Resolution Crash

For some games, such as Guns of Icarus or Aerena - Clash of Champions, I get the following error:
resolutionerror

For Guns of Icarus it happens if I attach and then detach before exiting the game, and then on exit, even though everything should be detached, the error is shown and the game crashes.

I believe the issue is occuring for any game that tries to change resolution for whatever reason after it has be attached and detached. It seems like some disposal is not happening fully or properly, something is lingering? What could it be?

Overlaying 2D graphics

How to overlay a plain red 2D rectangle with your library?

Specificially, with the SharpDX.Direct3D9.Device available from the library that sets up a Direct3D v9 device for me, so I'm hoping to be able to use that?

Found a tutorial on how to use Direct2D1 to draw a basic rectangle, but the code seems to be dependent on a Direct3D11 device, which I don't have - I need to be able to get the job done without Direct3D11 and without Direct3D10

unsafe int PresentHook(IntPtr devicePtr, SharpDX.Rectangle* pSourceRect, SharpDX.Rectangle* pDestRect, IntPtr hDestWindowOverride, IntPtr pDirtyRegion)
{
    _isUsingPresent = true;

    SharpDX.Direct3D9.Device device = (SharpDX.Direct3D9.Device)devicePtr;

    // How to draw rectangle here?

    if (pSourceRect == null || *pSourceRect == SharpDX.Rectangle.Empty)
        device.Present();
    else
    {
        if (hDestWindowOverride != IntPtr.Zero)
            device.Present(*pSourceRect, *pDestRect, hDestWindowOverride);
        else
            device.Present(*pSourceRect, *pDestRect);
    }
    return SharpDX.Result.Ok.Code;
}

I asked this question elsewhere, but noone knew how to use the managed code you have provided:
http://stackoverflow.com/questions/31099504/drawing-a-2d-rectangle-with-sharpdx

DirectX surface size in windowed mode, and testing whether a directX surface is present.

Hi,

I am currently using your great program to capture screenshots from DirectX devices like VLC or a game. As I am no DirectX expert, I wonder if you can help me with two issues:

  • When selecting the program to hook, I can enter the name of a program that has no DirectX support (e.g. notepad). This causes your program to stop responding. Do you know how I can test whether a program runs under DirectX (so I should be able to inject)?
  • When the captured program is running in windowed mode, what is the size of the visible DirectX surface? E.g. when I capture VLC, its size also contains the Window frame, and is therefore larger than the actual display surface.

Finally, as you are also the author of Easyhook, I wonder if it is possible to remove the hook injected via Easyhook? And is there a way to test whether an application is already hooked (or if I try to hook an app twice, will it only be hooked once)?

Thanks for any help you can give me!
Erik

Screenshot severe memory leak

Hey,

I don't know if you're still active on this project, but I have been playing with your code and found a severe memory leak.

The Screenshot (MarshalByRefObject) object is never released and it doesn't implement IDisposable.

If capturing a lot of screenshots, memory in the target process keeps growing.

In my case, this resulted in a OOM exception after ~30 seconds of getting consecutive screenshots.

Fix is simple, implement IDisposable, and call RemotingServices.Disconnect(this).

Then, make sure to call Dispose (or the using() construct) in the client application.

public class Screenshot : MarshalByRefObject, IDisposable
{
    private bool _disposed;

    public Screenshot(Guid requestId, byte[] capturedBitmap)
    {
        _requestId = requestId;
        _capturedBitmap = capturedBitmap;
    }

    ~Screenshot()
    {
        Dispose(false);
    }

    /// <summary>
    /// Disconnects the remoting channel(s) of this object and all nested objects.
    /// </summary>
    private void Disconnect()
    {
        RemotingServices.Disconnect(this);
    }

    [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.Infrastructure)]
    public override object InitializeLifetimeService()
    {
        //
        // Returning null designates an infinite non-expiring lease.
        // We must therefore ensure that RemotingServices.Disconnect() is called when
        // it's no longer needed otherwise there will be a memory leak.
        //
        return null;

        //var lease = (ILease)base.InitializeLifetimeService();
        //if (lease.CurrentState == LeaseState.Initial)
        //{
        //    lease.InitialLeaseTime = TimeSpan.FromSeconds(2);
        //    lease.SponsorshipTimeout = TimeSpan.FromSeconds(5);
        //    lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
        //}
        //return lease;
    }

    Guid _requestId;
    public Guid RequestId
    {
        get
        {
            return _requestId;
        }
    }

    byte[] _capturedBitmap;
    public byte[] CapturedBitmap
    {
        get
        {
            return _capturedBitmap;
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                Disconnect();
            }
            _disposed = true;
        }
    }
}

Hope that helps.

Windows 7 and DirectX11 crashes with the “Display Driver AMD stopped responding" message

While I was trying to run the project on Windows 7 as well, I managed to easily hook to a simple DirectX10 window, but when I tried to hook to a simple DirectX11 window, the target window became unresponsive, followed by the message “Display Driver AMD stopped responding, and was successfully restored”. The project itself kept running, and threw debug messages. The problem seems to be related to SharpDX and calling “draw” to the overlayEngine, but I am still not very familiar with the code.

Please let me know if you can help. I really appreciate it.

Have a great year to come!
Avi

This is the debug dump. The first long debug message was thrown 8 times in the activation:
Debug: DXHookD3D11: PresentHook: Exeception: SharpDX.SharpDXException: SharpDX.SharpDXException: HRESULT: [0x887A0005], Module: [SharpDX.DXGI], ApiCode: [DXGI_ERROR_DEVICE_REMOVED/DeviceRemoved], Message: Unknown
at SharpDX.Result.CheckError()
at SharpDX.Direct3D11.DeviceContext.FinishCommandListInternal(Bool restoreDeferredContextState, CommandList& commandListOut)
at SharpDX.Direct3D11.DeviceContext.FinishCommandList(Boolean restoreState)
at Capture.Hook.DX11.DXOverlayEngine.End() in c:\Cyndr\Direct3DHook-master\Capture\Hook\DX11\DXOverlayEngine.cs:line 168
at Capture.Hook.DX11.DXOverlayEngine.Draw() in c:\Cyndr\Direct3DHook-master\Capture\Hook\DX11\DXOverlayEngine.cs:line 161
at Capture.Hook.DXHookD3D11.PresentHook(IntPtr swapChainPtr, Int32 syncInterval, PresentFlags flags) in c:\Cyndr\Direct3DHook-master\Capture\Hook\DXHookD3D11.cs:line 538
Debug: DXHookD3D11: Hook: Device created
Debug: DXHookD3D11: Hook: Before device creation
Debug: DXHookD3D11: Hook: Begin
Debug: Autodetect found Direct3D 11
Information: Remote process is a 32-bit process.
Information: Injected into process Id:73912.
Reply

doesnt work on Windows 8.1

I get the following exception when i run the app on Windows 8.1. Is Windows 8 or 8.1 supported?

{System.ArgumentNullException: Value cannot be null.
Parameter name: pointer
at SlimDX.Direct3D9.Texture.FromPointer(IntPtr pointer)
at DxCapture.DwmCapture.DwmSetup() in c:\Users\username\Downloads\DxCapture (1)\DxCapture\DwmCapture.cs:line 164
at DxCapture.DwmCapture.InitializeDirect3D(IntPtr capturehWnd) in c:\Users\username\Downloads\DxCapture (1)\DxCapture\DwmCapture.cs:line 134
at DxCapture.Window1.startButton_Click(Object sender, RoutedEventArgs e) in c:\Users\username\Downloads\DxCapture (1)\DxCapture\Window1.xaml.cs:line 103
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.CrackMouseButtonEventAndReRaiseEvent(DependencyObject sender, MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.Run()
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at DxCapture.App.Main() in c:\Users\username\Downloads\DxCapture (1)\DxCapture\obj\Debug\App.g.cs:line 0
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()}

FPS are double what they should be for certain d3d11 titles

In Metro Last Light/Crysis 3/Splinter Cell Blacklist and perhaps others, displayed frames per second are twice what they should be.

before

I've found a fix for this and I've uploaded a fork. I'm not versed in GitHub but I think I've done it right.
Here's an image after the fix:

after

Because the fix breaks fps reading for d3d9 and d3d10, I made 2 separate FramesPerSecond11.cs only for d3d11. I also made minor changes to BaseDXHook.cs and DXHookD3D11.cs.

It's a different way of calculating fps based on LastPresentCount, code which I found here on GitHub.

Suggestion

Hey,

another suggestion if you start looking into this project again.

I can't send a pull request as my version has a lot of specific changes for my scenario. but here goes:

To avoid recursing into PresentHook / EndScene too much, you can do something like this:

        private static int presentHookRecurse = 0;

        ....

        if (presentHookRecurse <= 0)
        {
            DoCaptureRenderTarget(device, "PresentEx");
        }

        presentHookRecurse++;
        //    Region region = new Region(pDirtyRegion);
        if (pSourceRect == null || *pSourceRect == SharpDX.Rectangle.Empty)
            device.PresentEx(dwFlags);
        else
        {
            if (hDestWindowOverride != IntPtr.Zero)
                device.PresentEx(dwFlags, *pSourceRect, *pDestRect, hDestWindowOverride);
            else
                device.PresentEx(dwFlags, *pSourceRect, *pDestRect);
        }
        presentHookRecurse--;

Note the ++ / -- on presenthook.

This makes the game not wait for your own code to finish so it can continue at it's own pace.

I think you''ll understand what it does.

Test Screenshot crashes with Overwatch

When trying to inject into Overwatch Test Screenshot produces the following exception and fails, but when injecting into CS:GO it works completely fine.

Capture.InjectionFailedException occurred
  HResult=0x80131500
  Message=Injection to the target process failed. See InnerException for more detail.
  Source=Capture
  StackTrace:
   at Capture.CaptureProcess..ctor(Process process, CaptureConfig config, CaptureInterface captureInterface) in C:\Users\Che\Documents\Visual Studio 2017\Projects\Direct3DHook-master\Capture\CaptureProcess.cs:line 79
   at TestScreenshot.Form1.AttachProcess() in C:\Users\Che\Documents\Visual Studio 2017\Projects\Direct3DHook-master\TestScreenshot\Form1.cs:line 131
   at TestScreenshot.Form1.btnInject_Click(Object sender, EventArgs e) in C:\Users\Che\Documents\Visual Studio 2017\Projects\Direct3DHook-master\TestScreenshot\Form1.cs:line 52
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at TestScreenshot.Program.Main() in C:\Users\Che\Documents\Visual Studio 2017\Projects\Direct3DHook-master\TestScreenshot\Program.cs:line 18

Inner Exception 1:
ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected assembler code. (Code: 6553600)

Cannot move files, C++ error

All the files are in the /bin/ folder it works fine for example i move /bin/ folder to c:\ it doesnt working giving Capture.InjectionFailedException: Injection to the target process failed. See InnerException for more detail. ---> System.ApplicationException: STATUS_INTERNAL_ERROR: Unknown error in injected C++ completion routine. (Code: 15)

.

.

I added a new class to Capture.Hook.common but getting exception Index was outside the bounds of the array why ?

Let me explain.
In the class DXHookD3D11.cs there is a line that write to the screen the frames per second.

new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true },

I created inside Capture.Hook.Common a new class called it TimeRunning this is the class code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Capture.Hook.Common
{
public class TimeRunning : TextElement
{
DateTime _startTime = DateTime.Now;
TimeSpan RunTime;

    string _fpsFormat = "{0:c} fps";
    public override string Texts
    {
        get
        {
            return String.Format(_fpsFormat, GetFPS());
        }
        set
        {
            _fpsFormat = value;
        }
    }

    int _frames = 0;
    int _lastTickCount = 0;
    float _lastFrameRate = 0;

    public TimeRunning(System.Drawing.Font font)
        : base(font)
    {
    }

    public override void Frame()
    {
        RunTime = DateTime.Now - _startTime;
    }

    public TimeSpan GetFPS()//float GetFPS()
    {
        return RunTime;//_lastFrameRate;
    }
}

}

Then in the DXHookD3D11.cs inside the Elements =
Under the line with the FramesPerSecond:

new Capture.Hook.Common.TimeRunning(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,30), Color = System.Drawing.Color.Red, AntiAliased = true }

So now it look like this:

_overlayEngine.Overlays.Add(new Capture.Hook.Common.Overlay
{
Elements =
{
new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true },
new Capture.Hook.Common.TimeRunning(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,30), Color = System.Drawing.Color.Red, AntiAliased = true }
}
});

But when running the program and inject to a game i'm getting this exception:

Debug: DXHookD3D11: PresentHook: Exeception: System.IndexOutOfRangeException: System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Capture.Hook.DX11.DXFont.GetCharRect(Char c) in c:\Temp\hook\Direct3DHook-master\Capture\Hook\DX11\DXFont.cs:line 251
at Capture.Hook.DX11.DXSprite.DrawString(Int32 X, Int32 Y, String text, Int32 R, Int32 G, Int32 B, Int32 A, DXFont F) in c:\Temp\hook\Direct3DHook-master\Capture\Hook\DX11\DXSprite.cs:line 258
at Capture.Hook.DX11.DXOverlayEngine.Draw() in c:\Temp\hook\Direct3DHook-master\Capture\Hook\DX11\DXOverlayEngine.cs:line 145
at Capture.Hook.DXHookD3D11.PresentHook(IntPtr swapChainPtr, Int32 syncInterval, PresentFlags flags) in c:\Temp\hook\Direct3DHook-master\Capture\Hook\DXHookD3D11.cs:line 401

How can i fix it ? I want that the TimeRunning will be display on screen under the FramesPerSecond.

How can i write a text to screen in the DXHookD3D11.cs ?

For example this line in DXHookD3D11.cs write on the screen the fps(frames per second).

new Capture.Hook.Common.FramesPerSecond(new System.Drawing.Font("Arial", 16)) { Location = new System.Drawing.Point(5,5), Color = System.Drawing.Color.Red, AntiAliased = true }

Now let's say i want to write on screen something else for example the words "Hello World" on location instead 5,5 but 5,30

How can i do it ? So when i'm running the game a Directx 11 game i will see the frapes per second and under it i will see the text "Hello World"

I tried to read about how making a Font in directx11 . For example i searched in google and found about DirectWrite: http://sharpdx.org/documentation/api/n-sharpdx-directwrite
But i didn't understand how to use it since in the Capture project the SharpDX dosen't have the namespace DirectWrite.

Maybe you know and can show me how to add more text on screen ? Like it show the frames per second on screen so show other texts.

I found how to do it in DXHookD3D9.cs but in the DXHookD3D11.cs it's hard i couldn't find how to dit yet.

How to change the FPS string?

Already asked here: https://easyhook.codeplex.com/workitem/25879

I have this great project running. All is fine. I injected a game client (Hearthstone, DX9). And it shows the ... fps thing.

That is great for testing and works perfect. Now I was thinking about replacing the ... fps with something else, just to test.

But I'm not able to get it working. It does not matter what I change of the String. It always shows up ... fps. Why is it like that?

I changed in DXHookD3D9.cs:

if (this.FPS.GetFPS() >= 1)
                        {
                            font.DrawText(null, String.Format("{0:N0} fps", this.FPS.GetFPS()), 5, 5, SharpDX.Color.Red);
                        }

into...

font.DrawText(null, String.Format("{0:N0} blablabla", this.FPS.GetFPS()), 5, 5, 

I for sure cleaned the project and rebuild it. Nothing helped.

What am I doing wrong? Is there something else I need to rebuild?

Btw changing things of the Forms works. So it seems just not to work on the dll's somehow.

PS: the TakeScreenshot is just working when I chosse "Autodetect". If I take Direct 3D 9 it does not inject into the game. But in the log when I use Autodetect, it tells me Direct 3D 9.

I have no clue =/

Pull EasyHook from Nuget

Hey, I was just looking into updating EasyHook to the newest version, but I see that you've also put it on Nuget.

Is there anything that would make this transition non trivial? Or has it not been done yet just due to time constraints?

Edit: Should SharpDX be updated while we're at it?

How can i save screenshots to the hard disk according to the fps the program get from a game ?

For example i'm running a game inject and hook the game and i see on the game window the frames per second running in this case for example average of 60-61fps.
Now i want that the program will automatic save to the hard disk screenshots captured every second 60-61 images. Just like the program get from the game if it's 60fps then save 60 images on hard disk in a second if it change to 43fps then now save 43 images to the hard disk.

I did changes and added my code to the file DXHookD3D9.cs

This is the changes i did: http://pastebin.com/wc7vxQvD

First at the top i added: long counter = 0;
Then under: #region Screenshot Request i added my own IF with a request inside.
Then more in the bottom inside the ProcessRequest method i added my oqn thread called it t_1 and after this method added my oqn code with my oqn method called: SaveToDiskImageData

The problem is that it's too slow it's not saving to the hard disk 60-61 frames(screenshots/images) per second and another problem is after some time it's wroking when it's saving like 1000 images to the hard disk it's throwing an exception.

What i want to do in general is first to capture and save to the hard disk the images in real time according to the current fps and then later if it will work to create in real time an avi file.

But first how do i make this part to work good ?

This is the link again to the changes i did in DXHookD3D9.cs: http://pastebin.com/wc7vxQvD

How can i pass/connect variables between the Capture project and the TestScreenshot project ?

For example i create a public variable type bool in the TestScreenshot project and now i want to use this variable in the Capture project so when i set for example in the TestScreenshot if i click on a button and change the bool variable to false when i use it in the Capture project it will be false and if i click on another button then it will be true also in the Capture project.

Error with TestScreenshot app - support fallback to non-shared texture in D3D 11 if fails

When request capture


Debug: DXHookD3D11: PresentHook: Request Start
Debug: Disposing of hooks...
Debug: DXHookD3D11: PresentHook: Exeception: SharpDX.SharpDXException: SharpDX.SharpDXException: HRESULT: [0x80070057], Module: [General], ApiCode: [E_INVALIDARG/Invalid Arguments], Message: The parameter is incorrect.

   at SharpDX.Result.CheckError()
   at SharpDX.Direct3D11.Device.CreateTexture2D(Texture2DDescription& descRef, DataBox[] initialDataRef, Texture2D texture2DOut)
   at SharpDX.Direct3D11.Texture2D..ctor(Device device, Texture2DDescription description)
   at Capture.Hook.DXHookD3D11.EnsureResources(Device device, Texture2DDescription description, Rectangle captureRegion, ScreenshotRequest request) in C:\Users\Administrator\Downloads\Direct3DHook-master\Capture\Hook\DXHookD3D11.cs:line 280
   at Capture.Hook.DXHookD3D11.PresentHook(IntPtr swapChainPtr, Int32 syncInterval, PresentFlags flags) in C:\Users\Administrator\Downloads\Direct3DHook-master\Capture\Hook\DXHookD3D11.cs:line 355

CaptureInterface.DisplayInGameText not working, cannot add overlay from program.

I tested on "TestScreenshot", It's not sending "Screenshot captured..." text to game.

And another problem is I cant add (for example image) from CaptureProcess It self, cannot find another way to add too (without changing dll)

I'm using windows 10.
Debug log:
Debug: Autodetect found Direct3D 9
Debug: Autodetect found Direct3D 11
Information: Remote process is a 32-bit process.
Information: Injected into process Id:27212.

Draw Overlay not working with DirectX9 - CoD4 MW, Need for Speed Most Wanted

Hello Justin,

After re-cloning your latest source and compiling it I cannot make it to work with my DirectX9 Games. Injection is all well now. But when I try to capture an image it crashes the game and gives error. I got two types of error for testing it in two different games. The picture of the errors were attached.

1st Game : Call Of Duty 4 Modern Warfare
direct3d-problem

2nd Game : Need For Speed Most Wanted
direct3d-problem2

Please try to solve these bugs as soon possible. For these the whole project seems broken.

Thanks in advance.....

STATUS_ACCESS_DENIED: The given process is not accessible. (Code: 5)

when i hook war3.

Error: An unexpected error occured: System.AccessViolationException: STATUS_ACCESS_DENIED: The given process is not accessible. (Code: 5)
在 EasyHook.NativeAPI.Force(Int32 InErrorCode)
在 EasyHook.NativeAPI.RhIsX64Process(Int32 InProcessId, Boolean& OutResult)
在 EasyHook.RemoteHooking.IsX64Process(Int32 InTargetPID)
在 Capture.EntryPoint.InitialiseDirectXHook(CaptureConfig config) 位置 e:\c\game\Direct3DHook\Capture\EntryPoint.cs:行号 146
在 Capture.EntryPoint.Run(IContext context, String channelName, CaptureConfig config) 位置 e:\c\game\Direct3DHook\Capture\EntryPoint.cs:行号 70
Information: Injected into process Id:12068.

bool isX64Process = EasyHook.RemoteHooking.IsX64Process(EasyHook.RemoteHooking.GetCurrentProcessId());

Add Direct3D 12 / DX12 Support

This one is definitely an improvement/addition to be made, but I'd love to see this have DX12 support added. I know there is a SharpDX12 available so hopefully that is possible. I'm currently working around this project at the moment for my own, and need to impliment DX12 anyway so perhaps if I get it working I can send it over to try and help you. I'm certainly not knowledgeable enough to do it alone though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.