├── 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=