├── Image
└── readme_screenshot.png
├── src
├── MacroRecoderCsScript
│ ├── Properties
│ │ ├── Settings.settings
│ │ ├── Settings.Designer.cs
│ │ ├── AssemblyInfo.cs
│ │ ├── Resources.Designer.cs
│ │ └── Resources.resx
│ ├── ButtonState.cs
│ ├── App.xaml
│ ├── KeyHookStruct.cs
│ ├── MainWindow.xaml.cs
│ ├── MouseHookStruct.cs
│ ├── WindowHookEvent.cs
│ ├── CommonUtil.cs
│ ├── NativeMethods.cs
│ ├── SendInputWrapper.cs
│ ├── DelegateCommand.cs
│ ├── ScriptExecuter.cs
│ ├── AsyncDelegateCommand.cs
│ ├── AppEnvironment.cs
│ ├── App.xaml.cs
│ ├── MainWindow.xaml
│ ├── UserInputHook.cs
│ ├── ScriptRecorder.cs
│ ├── Input.cs
│ ├── App.config
│ ├── packages.config
│ ├── MainWindowViewModel.cs
│ ├── Logger.cs
│ ├── MacroScript.cs
│ └── MacroRecoderCsScript.csproj
├── MacroRecoderCsScript.sln
└── SampleScript
│ ├── sample_key.csx
│ └── sample_mouse.csx
├── LICENSE
├── README.md
└── .gitignore
/Image/readme_screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hukatama024e/MacroRecoderCsScript/HEAD/Image/readme_screenshot.png
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/ButtonState.cs:
--------------------------------------------------------------------------------
1 | namespace MacroRecoderCsScript
2 | {
3 | public class ButtonState
4 | {
5 | public bool IsRecording { get; set; } = false;
6 | public bool IsPlaying { get; set; } = false;
7 |
8 | public ButtonState()
9 | {
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/KeyHookStruct.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MacroRecoderCsScript
4 | {
5 | [Flags]
6 | public enum LowLevelKeyEvent : uint
7 | {
8 | None = 0x00,
9 | Extended = 0x01,
10 | Injected = 0x10,
11 | AltDown = 0x20,
12 | Up = 0x80
13 | };
14 |
15 | public struct KeyHookStruct
16 | {
17 | public ushort virtualKey;
18 | public ushort scanCode;
19 | public LowLevelKeyEvent flags;
20 | public uint time;
21 | public IntPtr extraInfo;
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace MacroRecoderCsScript
4 | {
5 | ///
6 | /// MainWindow.xaml の相互作用ロジック
7 | ///
8 | public partial class MainWindow : Window
9 | {
10 | private MainWindowViewModel userModel = new MainWindowViewModel();
11 | public MainWindow()
12 | {
13 | DataContext = userModel;
14 | InitializeComponent();
15 |
16 | AppEnvironment.GetInstance().DpiSetting();
17 | userModel.WinDispacher = Application.Current.Dispatcher;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/MouseHookStruct.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace MacroRecoderCsScript
4 | {
5 | [Flags]
6 | public enum LowLevelMouseEvent : uint
7 | {
8 | None = 0x00,
9 | Injected = 0x01,
10 | LowerIntegrityLevelInjected = 0x02
11 | };
12 |
13 | public struct Point
14 | {
15 | public int x;
16 | public int y;
17 | }
18 |
19 | public struct MouseHookStruct
20 | {
21 | public Point coordinatePoint;
22 | public int mouseData;
23 | public LowLevelMouseEvent flags;
24 | public uint time;
25 | public IntPtr extraInfo;
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/WindowHookEvent.cs:
--------------------------------------------------------------------------------
1 | namespace MacroRecoderCsScript
2 | {
3 | public enum WindowsHookID : int
4 | {
5 | KeyBoardLowLevel = 13,
6 | MouseLowLevel = 14
7 | };
8 |
9 | public enum KeyHookEvent : int
10 | {
11 | KeyDown = 0x100,
12 | KeyUp = 0x101,
13 | SysKeyDown = 0x104,
14 | SysKeyUp = 0x105
15 | };
16 |
17 | public enum MouseHookEvent : int
18 | {
19 | Move = 0x0200,
20 | LeftDown = 0x0201,
21 | LeftUp = 0x0202,
22 | RightDown = 0x0204,
23 | RightUp = 0x0205,
24 | MiddleDown = 0x0207,
25 | MiddleUp = 0x0208,
26 | Wheel = 0x020A,
27 | Hwheel = 0x020E
28 | };
29 | }
30 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26014.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MacroRecoderCsScript", "MacroRecoderCsScript\MacroRecoderCsScript.csproj", "{5310FD6C-59A1-415D-862B-2612FFE09427}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {5310FD6C-59A1-415D-862B-2612FFE09427}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {5310FD6C-59A1-415D-862B-2612FFE09427}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {5310FD6C-59A1-415D-862B-2612FFE09427}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {5310FD6C-59A1-415D-862B-2612FFE09427}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/src/SampleScript/sample_key.csx:
--------------------------------------------------------------------------------
1 | #r "PresentationCore"
2 |
3 | using System.Diagnostics;
4 | using System.Threading.Tasks;
5 | using System.Windows.Input;
6 |
7 | enum DebugMode : byte
8 | {
9 | None = 0x00,
10 | MouseOnly = 0x01,
11 | KeyOnly = 0x02,
12 | CreateLog = 0x04
13 | };
14 |
15 | await SetMode( ( byte )DebugMode.KeyOnly | ( byte )DebugMode.CreateLog );
16 |
17 | await Task.Run( () => { Process.Start( "Notepad" ); } );
18 | await Delay(500);
19 |
20 | await KeyInput( Key.A );
21 | await PressKey( (ushort)KeyInterop.VirtualKeyFromKey( Key.LeftShift ) );
22 | await KeyInput( Key.B );
23 | await KeyInput( Key.C );
24 | await ReleaseKey( (ushort)KeyInterop.VirtualKeyFromKey( Key.LeftShift ) );
25 | await PressKey( (ushort)KeyInterop.VirtualKeyFromKey( Key.LeftCtrl ) );
26 | await KeyInput( Key.S );
27 | await ReleaseKey( (ushort)KeyInterop.VirtualKeyFromKey( Key.LeftCtrl ) );
28 |
29 | async Task KeyInput( Key key )
30 | {
31 | ushort virtualKey = (ushort)KeyInterop.VirtualKeyFromKey( key );
32 |
33 | await PressKey( virtualKey );
34 | await Delay( 100 );
35 | await ReleaseKey( virtualKey );
36 | await Delay( 100 );
37 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 fukatama024e
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // このコードはツールによって生成されました。
4 | // ランタイム バージョン:4.0.30319.42000
5 | //
6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、
7 | // コードが再生成されるときに損失したりします。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace MacroRecoderCsScript.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/CommonUtil.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using System.Windows;
4 |
5 | namespace MacroRecoderCsScript
6 | {
7 | class CommonUtil
8 | {
9 | public static bool CheckMode( ModeKind mode )
10 | {
11 | var currentMode = AppEnvironment.GetInstance().Mode;
12 | return ( currentMode & mode ) == mode;
13 | }
14 |
15 | public async static Task HandleExceptionAsync( Exception ex )
16 | {
17 | await Logger.WriteErrorLogAsync( ex );
18 | await Task.Run( () => ProcessException( ex ) );
19 | }
20 |
21 | public static void HandleException( Exception ex )
22 | {
23 | Logger.WriteErrorLog( ex );
24 | ProcessException( ex );
25 | }
26 |
27 | public static void WriteToConsole( string str )
28 | {
29 | NativeMethods.AttachConsole( NativeMethods.ATTACH_PARENT_PROCESS );
30 | Console.WriteLine( str );
31 | NativeMethods.FreeConsole();
32 | }
33 |
34 | private static void ProcessException( Exception ex )
35 | {
36 | if( AppEnvironment.GetInstance().IsConsoleMode ) {
37 | WriteToConsole( ex.ToString() );
38 | }
39 | else {
40 | MessageBox.Show( ex.ToString(), "Error" );
41 | }
42 |
43 | // for executing destructor of hook
44 | GC.Collect();
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace MacroRecoderCsScript
5 | {
6 | internal static class NativeMethods
7 | {
8 | internal const int SEND_INPUT_FAILED = 0;
9 | internal const int ATTACH_PARENT_PROCESS = -1;
10 |
11 | internal delegate int HookProc( int hookCode, IntPtr wParam, IntPtr lParam );
12 |
13 | [DllImport( "user32.dll", SetLastError = true )]
14 | internal static extern IntPtr SetWindowsHookEx( int hookEventId, [MarshalAs( UnmanagedType.FunctionPtr )] HookProc hook, IntPtr module, uint threadId );
15 |
16 | [DllImport( "user32.dll", SetLastError = true )]
17 | internal static extern bool UnhookWindowsHookEx( IntPtr hookHandle );
18 |
19 | [DllImport( "user32.dll", SetLastError = true )]
20 | internal static extern int CallNextHookEx( IntPtr hookHandle, int hookCode, IntPtr wParam, IntPtr lParam );
21 |
22 | [DllImport( "user32.dll", SetLastError = true )]
23 | internal static extern uint SendInput( uint inputNum, Input[] inputs, int inputStructSize );
24 |
25 | [DllImport( "Kernel32.dll", SetLastError = true )]
26 | internal static extern bool AttachConsole( int processId );
27 |
28 | [DllImport( "Kernel32.dll", SetLastError = true )]
29 | internal static extern bool FreeConsole();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/SendInputWrapper.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.ComponentModel;
3 |
4 | namespace MacroRecoderCsScript
5 | {
6 | public static class SendInputWrapper
7 | {
8 | public static void SendMouseInput( MouseInput[] mouseInput )
9 | {
10 | uint result;
11 |
12 | Input[] input = new Input[ mouseInput.Length ];
13 |
14 | for( int i = 0; i < mouseInput.Length; i++ ) {
15 | input[ i ].type = InputType.Mouse;
16 | input[ i ].inputInfo.mouseInput = mouseInput[ i ];
17 | }
18 |
19 | result = NativeMethods.SendInput( ( uint ) input.Length, input, Marshal.SizeOf( input[ 0 ] ) );
20 |
21 | if( result == NativeMethods.SEND_INPUT_FAILED ) {
22 | throw new Win32Exception();
23 | }
24 | }
25 |
26 | public static void SendKeyInput( KeyInput[] keyInput )
27 | {
28 | uint result;
29 |
30 | Input[] input = new Input[ keyInput.Length ];
31 |
32 | for( int i = 0; i < keyInput.Length; i++ ) {
33 | input[ i ].type = InputType.Keyboard;
34 | input[ i ].inputInfo.keyInput = keyInput[ i ];
35 | }
36 |
37 | result = NativeMethods.SendInput( ( uint ) input.Length, input, Marshal.SizeOf( input[ 0 ] ) );
38 |
39 | if( result == NativeMethods.SEND_INPUT_FAILED ) {
40 | throw new Win32Exception();
41 | }
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/DelegateCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Input;
3 |
4 | namespace MacroRecoderCsScript
5 | {
6 | class DelegateCommand : ICommand
7 | {
8 | private readonly Action command;
9 | private readonly Func executable;
10 |
11 | public DelegateCommand( Action execute, Func canExecute )
12 | {
13 | command = execute;
14 | executable = canExecute;
15 | }
16 |
17 | public DelegateCommand( Action execute )
18 | {
19 | command = execute;
20 | executable = () => true; // default
21 | }
22 |
23 | public event EventHandler CanExecuteChanged
24 | {
25 | add { CommandManager.RequerySuggested += value; }
26 | remove { CommandManager.RequerySuggested -= value; }
27 | }
28 | protected void RaiseCanExecuteChanged()
29 | {
30 | CommandManager.InvalidateRequerySuggested();
31 | }
32 |
33 | public bool CanExecute( object parameter )
34 | {
35 | bool canExecute = true;
36 |
37 | try {
38 | canExecute = executable();
39 | }
40 | catch( Exception ex ) {
41 | CommonUtil.HandleException( ex );
42 | }
43 |
44 | return canExecute;
45 | }
46 |
47 | public void Execute( object parameter )
48 | {
49 | try {
50 | command();
51 | }
52 | catch( Exception ex ) {
53 | CommonUtil.HandleException( ex );
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/ScriptExecuter.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Threading.Tasks;
3 | using Microsoft.CodeAnalysis.Scripting;
4 | using Microsoft.CodeAnalysis.CSharp.Scripting;
5 |
6 | namespace MacroRecoderCsScript
7 | {
8 | static class ScriptExecuter
9 | {
10 | public static async Task ExecuteAsync( string scriptPath )
11 | {
12 | using( var hook = new UserInputHook() ) {
13 | HookSetting( hook );
14 |
15 | var script = CSharpScript.Create( File.ReadAllText( scriptPath ), ScriptOptions.Default, typeof( MacroScript ) );
16 | await script.RunAsync( new MacroScript() );
17 | }
18 | }
19 |
20 | private static void LoggingMouseMacro( MouseHookStruct mouseHookStr, int mouseEvent )
21 | {
22 | if( CommonUtil.CheckMode( ModeKind.CreateLog ) ) {
23 | Logger.WriteMouseEvent( mouseHookStr, ( MouseHookEvent ) mouseEvent );
24 | }
25 | }
26 |
27 | private static void LoggingKeyMacro( KeyHookStruct keyHookStr, int keyEvent )
28 | {
29 | if( CommonUtil.CheckMode( ModeKind.CreateLog ) ) {
30 | Logger.WriteKeyEvent( keyHookStr, ( KeyHookEvent ) keyEvent );
31 | }
32 | }
33 |
34 | private static void HookSetting( UserInputHook hook )
35 | {
36 | hook.MouseHook = LoggingMouseMacro;
37 | hook.KeyHook = LoggingKeyMacro;
38 | hook.HookErrorProc = CommonUtil.HandleException;
39 |
40 | hook.RegisterKeyHook();
41 | hook.RegisterMouseHook();
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/AsyncDelegateCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using System.Windows.Input;
4 |
5 | namespace MacroRecoderCsScript
6 | {
7 | class AsyncDelegateCommand : ICommand
8 | {
9 | private readonly Func command;
10 | private readonly Func executable;
11 |
12 | public AsyncDelegateCommand( Func execute, Func canExecute )
13 | {
14 | command = execute;
15 | executable = canExecute;
16 | }
17 |
18 | public AsyncDelegateCommand( Func execute )
19 | {
20 | command = execute;
21 | executable = () => true; // default
22 | }
23 |
24 | public event EventHandler CanExecuteChanged
25 | {
26 | add { CommandManager.RequerySuggested += value; }
27 | remove { CommandManager.RequerySuggested -= value; }
28 | }
29 | protected void RaiseCanExecuteChanged()
30 | {
31 | CommandManager.InvalidateRequerySuggested();
32 | }
33 |
34 | public bool CanExecute( object parameter )
35 | {
36 | bool canExecute = true;
37 |
38 | try {
39 | canExecute = executable();
40 | }
41 | catch(Exception ex) {
42 | CommonUtil.HandleException( ex );
43 | }
44 |
45 | return canExecute;
46 | }
47 |
48 | public async void Execute( object parameter )
49 | {
50 | try {
51 | await ExcecuteAsync();
52 | }
53 | catch( Exception ex ) {
54 | await CommonUtil.HandleExceptionAsync( ex );
55 | }
56 | }
57 |
58 | private Task ExcecuteAsync()
59 | {
60 | return command();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/SampleScript/sample_mouse.csx:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | [Flags]
6 | enum DebugMode : byte
7 | {
8 | None = 0x00,
9 | MouseOnly = 0x01,
10 | KeyOnly = 0x02,
11 | CreateLog = 0x04
12 | };
13 |
14 | await SetMode( ( byte )DebugMode.MouseOnly | ( byte )DebugMode.CreateLog );
15 |
16 | await SetCoordinate(100, 100);
17 | await SetCoordinate(200, 100);
18 | await SetCoordinate(300, 100);
19 | await SetCoordinate(400, 100);
20 | await SetCoordinate(500, 100);
21 | await SetCoordinate(600, 100);
22 | await SetCoordinate(700, 100);
23 | await SetCoordinate(800, 100);
24 | await SetCoordinate(900, 100);
25 | await SetCoordinate(1000, 100);
26 |
27 | await WriteCustomLog( "test custom log" );
28 |
29 | await SetCoordinate(900, 100);
30 | await SetCoordinate(800, 100);
31 | await SetCoordinate(700, 100);
32 | await SetCoordinate(600, 100);
33 | await SetCoordinate(500, 100);
34 | await SetCoordinate(400, 100);
35 | await SetCoordinate(300, 100);
36 | await SetCoordinate(200, 100);
37 | await SetCoordinate(100, 100);
38 |
39 | async Task SetCoordinate( int x, int y )
40 | {
41 | await SetMousePos( x, y );
42 | await Delay( 100 );
43 | }
44 |
45 | async Task WriteCustomLog( string message )
46 | {
47 | await Task.Run( () => {
48 | var userCustomDic = new Dictionary
49 | {
50 | { "ScriptName", "sample_mouse" },
51 | { "Message", message }
52 | };
53 |
54 | WriteUserCustomLog( userCustomDic );
55 | } );
56 | }
--------------------------------------------------------------------------------
/src/MacroRecoderCsScript/AppEnvironment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Windows;
4 | using System.Windows.Interop;
5 | using System.Windows.Media;
6 |
7 | namespace MacroRecoderCsScript
8 | {
9 | [Flags]
10 | public enum ModeKind : byte
11 | {
12 | None = 0x00,
13 | MouseOnly = 0x01,
14 | KeyOnly = 0x02,
15 | CreateLog = 0x04
16 | };
17 |
18 | class AppEnvironment
19 | {
20 | private static AppEnvironment instance = new AppEnvironment();
21 | public ModeKind Mode { get; set; } = ModeKind.None;
22 | public bool IsConsoleMode { get; set; } = true;
23 | public double DpiWidth { get; internal set; } = 1.0;
24 | public double DpiHeight { get; internal set; } = 1.0;
25 | public CancellationToken CancelToken { get; set; }
26 |
27 | private AppEnvironment()
28 | {
29 | }
30 |
31 | public static AppEnvironment GetInstance()
32 | {
33 | return instance;
34 | }
35 |
36 | public void DpiSetting()
37 | {
38 | var transform = GetTransform();
39 | DpiWidth = transform.M22;
40 | DpiHeight = transform.M11;
41 | }
42 |
43 | private Matrix GetTransform()
44 | {
45 | Matrix transform;
46 |
47 | var window = Application.Current.MainWindow ?? new MainWindow();
48 | var srcFromWindow = PresentationSource.FromVisual( window );
49 |
50 | if( srcFromWindow != null ) {
51 | transform = srcFromWindow.CompositionTarget.TransformFromDevice;
52 | }
53 | else {
54 | using( var hwndSrc = new HwndSource( new HwndSourceParameters() ) ) {
55 | transform = hwndSrc.CompositionTarget.TransformFromDevice;
56 | }
57 | }
58 |
59 | return transform;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MacroRecoderCsScript
2 | macro recorder written by C# script with Roslyn for Scripting
3 |
4 | ## Feature
5 |
6 | * Record key and mouse macro
7 | Record mouse and key input.
8 | Recorded input is writed to macro with C# script.
9 |
10 | * Execute Record key and mouse macro
11 | Execute macro script writed by C# script.
12 |
13 | * Command line mode
14 | Execute macro script in command line.
15 | In this mode, Application is not shown.
16 |
17 | ## Usage
18 | ![Screen Shot]
19 |
20 |
21 | (1) Record button. When this button pushed, Application record mouse and key input.
22 | (2) Play button. When this button pushed, Application play macro.
23 | (3) Stop button. this button is enabled when Application record or play.
24 | When this button pushed in recording, stop recording and open file dialog for saving macro to C# script.
25 | When this button pushed in playing macro, cancel playing macro.
26 | (4) File path of C# script.
27 | (5) Browse button. When this button pushed, Open file dialog and input file path of selected C# script.
28 | (6) Error information. View expected error. For example, compile error for C# script.
29 |
30 | ### Command line mode
31 |
32 | ```
33 | MacroRecoderCsScript -script=