├── Project ├── CodeerFriendlyWindowsCore │ ├── pch.cpp │ ├── pch.h │ ├── framework.h │ ├── CodeerFriendlyWindowsCore.def │ ├── CodeerFriendlyWindowsCore.sln │ └── dllmain.cpp ├── Codeer.Friendly.Windows │ ├── Properties │ │ ├── Resources.ja.Designer.cs │ │ └── AssemblyInfo.cs │ ├── Codeer.Friendly.Windows.snk │ ├── packages.config │ ├── Resources │ │ ├── CodeerFriendlyWindows_x64.dll │ │ ├── CodeerFriendlyWindows_x86.dll │ │ ├── Codeer.Friendly.Windows.Step.dll │ │ ├── CodeerFriendlyWindowsCore_x64.dll │ │ └── CodeerFriendlyWindowsCore_x86.dll │ ├── Inside │ │ ├── SystemControlType.cs │ │ ├── DotNetExecutor │ │ │ ├── IAsyncInvoke.cs │ │ │ ├── UniqueNoManager.cs │ │ │ ├── DotNetFriendlyControl.cs │ │ │ ├── VarAndType.cs │ │ │ ├── VarPool.cs │ │ │ └── TypeFinder.cs │ │ ├── SerializeUtility.cs │ │ ├── SystemControlInfo.cs │ │ ├── ContextOrderProtocolInfo.cs │ │ ├── Debug.cs │ │ ├── CopyDataProtocol │ │ │ ├── CopyDataProtocolInfo.cs │ │ │ ├── ReceiveAfterSend.cs │ │ │ ├── CopyDataProtocolTalker.cs │ │ │ └── ReceiveForm.cs │ │ ├── CpuTargetCheckUtility.cs │ │ ├── ProtocolMessageManager.cs │ │ ├── FriendlyConnectorWindowInAppManager.cs │ │ ├── TargetWindowExecutor.cs │ │ ├── WindowsAppExpanderInApp.cs │ │ ├── SystemController.cs │ │ ├── FriendlyConnectorWindowInApp.cs │ │ ├── CommunicationWindowManager.cs │ │ ├── SystemStartResponseReciever.cs │ │ └── SystemControlWindowInApp.cs │ ├── ICustomSerializer.cs │ ├── Codeer.Friendly.Windows.sln │ └── ExecuteContext.cs ├── TestTargetCore │ ├── global.json │ ├── App.xaml │ ├── App.xaml.cs │ ├── TestTargetCore.csproj │ ├── MainWindow.xaml │ ├── TestTargetCore.sln │ └── MainWindow.xaml.cs ├── Nuget │ ├── NuGet.exe │ ├── MakeNupack.bat │ └── Friendly.Windows.nuspec ├── UnitTestCore │ ├── UnitTest1.cs │ └── UnitTestCore.csproj ├── CodeerFriendlyWindows │ ├── stdafx.cpp │ ├── stdafx.h │ ├── Starter.cpp │ ├── dllmain.cpp │ ├── targetver.h │ ├── CodeerFriendlyWindows.cpp │ ├── CodeerFriendlyWindows.def │ └── CodeerFriendlyWindows.sln ├── Attachx86 │ ├── packages.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── Attachx86.csproj ├── Test │ ├── Test │ │ ├── packages.config │ │ ├── TestWPF.cs │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── MultiDomainTest.cs │ │ └── Test.sln │ ├── WPFApp │ │ ├── Properties │ │ │ ├── Settings.settings │ │ │ ├── Settings.Designer.cs │ │ │ ├── AssemblyInfo.cs │ │ │ └── Resources.Designer.cs │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── MainWindow.xaml │ │ ├── MainWindow.xaml.cs │ │ └── WPFApp.csproj │ ├── MultiDomain_2_32 │ │ ├── Properties │ │ │ ├── Settings.settings │ │ │ ├── Settings.Designer.cs │ │ │ ├── AssemblyInfo.cs │ │ │ └── Resources.Designer.cs │ │ ├── Program.cs │ │ ├── MainForm.cs │ │ ├── MainForm.Designer.cs │ │ └── MultiDomain_2_32.csproj │ ├── MultiDomain_4_32 │ │ ├── Properties │ │ │ ├── Settings.settings │ │ │ ├── Settings.Designer.cs │ │ │ ├── AssemblyInfo.cs │ │ │ └── Resources.Designer.cs │ │ ├── Program.cs │ │ ├── MainForm.cs │ │ ├── MainForm.Designer.cs │ │ └── MultiDomain_4_32.csproj │ └── MultiDomain_4_64 │ │ ├── Properties │ │ ├── Settings.settings │ │ ├── Settings.Designer.cs │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ │ ├── Program.cs │ │ ├── MainForm.cs │ │ ├── MainForm.Designer.cs │ │ └── MultiDomain_4_64.csproj ├── Codeer.Friendly.Windows.Step │ ├── Codeer.Friendly.Windows.Step.snk │ ├── StartStepWrap.cs │ ├── AppDomainBridge.cs │ ├── Codeer.Friendly.Windows.Step.sln │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── StartStep.cs │ ├── TypeFinder.cs │ ├── AssemblyResolver.cs │ ├── Codeer.Friendly.Windows.Step.csproj │ └── AppDomainControl.cs ├── TestTargetx86 │ ├── Properties │ │ ├── Settings.settings │ │ ├── Settings.Designer.cs │ │ ├── AssemblyInfo.cs │ │ └── Resources.Designer.cs │ ├── App.xaml.cs │ ├── App.xaml │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ └── TestTargetx86.csproj ├── TestTargetCore8 │ ├── TestTargetCore8 │ │ ├── Form1.cs │ │ ├── TestTargetCore8.csproj │ │ ├── Program.cs │ │ └── Form1.Designer.cs │ └── TestTargetCore8.sln └── UnitTest │ ├── packages.config │ ├── Properties │ └── AssemblyInfo.cs │ ├── TestNetFramewrok.cs │ ├── TestHandOverResources.cs │ └── TestCore.cs ├── libraries.png ├── README.md ├── .gitignore └── .gitattributes /Project/CodeerFriendlyWindowsCore/pch.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Properties/Resources.ja.Designer.cs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Project/TestTargetCore/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "3.0.103" 4 | } 5 | } -------------------------------------------------------------------------------- /libraries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/libraries.png -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindowsCore/pch.h: -------------------------------------------------------------------------------- 1 | #ifndef PCH_H 2 | #define PCH_H 3 | #include "framework.h" 4 | #endif 5 | -------------------------------------------------------------------------------- /Project/Nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Nuget/NuGet.exe -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindowsCore/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define WIN32_LEAN_AND_MEAN 3 | #include 4 | -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindowsCore/CodeerFriendlyWindowsCore.def: -------------------------------------------------------------------------------- 1 | LIBRARY "CodeerFriendlyWindowsCore" 2 | EXPORTS 3 | InitializeFriendly -------------------------------------------------------------------------------- /Project/UnitTestCore/UnitTest1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/UnitTestCore/UnitTest1.cs -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/stdafx.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/stdafx.cpp -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/stdafx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/stdafx.h -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/Starter.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/Starter.cpp -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/dllmain.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/dllmain.cpp -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/targetver.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/targetver.h -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/CodeerFriendlyWindows.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/CodeerFriendlyWindows/CodeerFriendlyWindows.cpp -------------------------------------------------------------------------------- /Project/Attachx86/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Project/Test/Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Codeer.Friendly.Windows.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Codeer.Friendly.Windows.snk -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/CodeerFriendlyWindows.def: -------------------------------------------------------------------------------- 1 | LIBRARY "CodeerFriendlyWindows" 2 | EXPORTS 3 | InitializeFriendly 4 | EnumDomains 5 | InitializeAppDomain 6 | HasGetCLRRuntimeHost -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/Codeer.Friendly.Windows.Step.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows.Step/Codeer.Friendly.Windows.Step.snk -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindows_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindows_x64.dll -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindows_x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindows_x86.dll -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Resources/Codeer.Friendly.Windows.Step.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Resources/Codeer.Friendly.Windows.Step.dll -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindowsCore_x64.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindowsCore_x64.dll -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindowsCore_x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Codeer-Software/Friendly.Windows/HEAD/Project/Codeer.Friendly.Windows/Resources/CodeerFriendlyWindowsCore_x86.dll -------------------------------------------------------------------------------- /Project/Test/WPFApp/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Project/TestTargetx86/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/StartStepWrap.cs: -------------------------------------------------------------------------------- 1 | namespace Codeer.Friendly.Windows.Step 2 | { 3 | public class StartStepWrap 4 | { 5 | public int Start(string startInfo) 6 | { 7 | return StartStep.Start(startInfo); 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Project/TestTargetCore8/TestTargetCore8/Form1.cs: -------------------------------------------------------------------------------- 1 | namespace TestTargetCore8 2 | { 3 | public partial class Form1 : Form 4 | { 5 | public Form1() 6 | { 7 | InitializeComponent(); 8 | } 9 | 10 | string Test(int a, string b, Form x) => "" + a + b + x; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/AppDomainBridge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Codeer.Friendly.Windows.Step 4 | { 5 | public class AppDomainBridge 6 | { 7 | public int GetCurrentDomainId(string arg) 8 | { 9 | return AppDomain.CurrentDomain.Id; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Project/UnitTest/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Project/TestTargetCore8/TestTargetCore8/TestTargetCore8.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinExe 5 | net8.0-windows 6 | enable 7 | true 8 | enable 9 | 10 | 11 | -------------------------------------------------------------------------------- /Project/Nuget/MakeNupack.bat: -------------------------------------------------------------------------------- 1 | rd /s /q "../ReleaseBinary" 2 | "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe" "../Codeer.Friendly.Windows/Codeer.Friendly.Windows.sln" /rebuild Release 3 | "C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE\devenv.exe" "../Codeer.Friendly.Windows/Codeer.Friendly.Windows.sln" /rebuild Release-Eng 4 | nuget pack friendly.windows.nuspec -------------------------------------------------------------------------------- /Project/Test/WPFApp/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace WPFApp 10 | { 11 | /// 12 | /// App.xaml の相互作用ロジック 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Project/TestTargetx86/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace TestTargetx86 10 | { 11 | /// 12 | /// App.xaml の相互作用ロジック 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Project/TestTargetCore/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Project/TestTargetCore/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | 9 | namespace TestTargetCore 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Project/TestTargetx86/App.xaml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Project/TestTargetCore/TestTargetCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WinExe 5 | netcoreapp3.0 6 | true 7 | 8 | 9 | 10 | AnyCPU 11 | false 12 | 13 | 14 | -------------------------------------------------------------------------------- /Project/Attachx86/Program.cs: -------------------------------------------------------------------------------- 1 | using Codeer.Friendly.Windows; 2 | using System; 3 | using System.Diagnostics; 4 | using System.IO; 5 | 6 | namespace Attachx86 7 | { 8 | class Program 9 | { 10 | static void Main(string[] args) 11 | { 12 | var app = new WindowsAppFriend(Process.GetProcessById(int.Parse(args[0]))); 13 | var bin = app.HandOverResources(int.Parse(args[1])); 14 | File.WriteAllBytes(args[2], bin); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SystemControlType.cs: -------------------------------------------------------------------------------- 1 | namespace Codeer.Friendly.Windows.Inside 2 | { 3 | /// 4 | /// システムコントロールタイプ。 5 | /// 6 | public enum SystemControlType 7 | { 8 | /// 9 | /// Friendly通信App側ウィンドウ開始。 10 | /// 11 | StartFriendlyConnectorWindowInApp, 12 | 13 | /// 14 | /// Friendly通信App側ウィンドウ終了。 15 | /// 16 | EndFriendlyConnectorWindowInApp, 17 | 18 | /// 19 | /// システム終了。 20 | /// 21 | EndSystem, 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/IAsyncInvoke.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Codeer.Friendly.DotNetExecutor 4 | { 5 | /// 6 | /// 非同期実行インターフェイス。 7 | /// 8 | public interface IAsyncInvoke 9 | { 10 | /// 11 | /// 非同期実行。 12 | /// 13 | /// 実行メソッド。 14 | void Execute(AsyncMethod method); 15 | } 16 | 17 | /// 18 | /// 非同期実行メソッド。 19 | /// 20 | public delegate void AsyncMethod(); 21 | } 22 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace MultiDomain_2_32 6 | { 7 | static class Program 8 | { 9 | /// 10 | /// アプリケーションのメイン エントリ ポイントです。 11 | /// 12 | [STAThread] 13 | static void Main() 14 | { 15 | Application.EnableVisualStyles(); 16 | Application.SetCompatibleTextRenderingDefault(false); 17 | Application.Run(new MainForm()); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Project/TestTargetx86/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace MultiDomain_4_32 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// アプリケーションのメイン エントリ ポイントです。 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new MainForm()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace MultiDomain_4_64 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// アプリケーションのメイン エントリ ポイントです。 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new MainForm()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Project/TestTargetCore/MainWindow.xaml: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Project/TestTargetCore8/TestTargetCore8/Program.cs: -------------------------------------------------------------------------------- 1 | namespace TestTargetCore8 2 | { 3 | internal static class Program 4 | { 5 | /// 6 | /// The main entry point for the application. 7 | /// 8 | [STAThread] 9 | static void Main() 10 | { 11 | // To customize application configuration such as set high DPI settings or default font, 12 | // see https://aka.ms/applicationconfiguration. 13 | ApplicationConfiguration.Initialize(); 14 | Application.Run(new Form1()); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | 9 | namespace MultiDomain_2_32 10 | { 11 | public partial class MainForm : Form 12 | { 13 | public MainForm() 14 | { 15 | InitializeComponent(); 16 | } 17 | public void StartMultiDomain() 18 | { 19 | AppDomain.CreateDomain("XXX").DoCallBack(() => new Form().Show()); 20 | AppDomain.CreateDomain("YYY").DoCallBack(() => new Form().Show()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace MultiDomain_4_32 11 | { 12 | public partial class MainForm : Form 13 | { 14 | public MainForm() 15 | { 16 | InitializeComponent(); 17 | } 18 | public void StartMultiDomain() 19 | { 20 | AppDomain.CreateDomain("XXX").DoCallBack(() => new Form().Show()); 21 | AppDomain.CreateDomain("YYY").DoCallBack(() => new Form().Show()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/MainForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Forms; 9 | 10 | namespace MultiDomain_4_64 11 | { 12 | public partial class MainForm : Form 13 | { 14 | public MainForm() 15 | { 16 | InitializeComponent(); 17 | } 18 | public void StartMultiDomain() 19 | { 20 | AppDomain.CreateDomain("XXX").DoCallBack(() => new Form().Show()); 21 | AppDomain.CreateDomain("YYY").DoCallBack(() => new Form().Show()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Project/UnitTest/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | [assembly: AssemblyTitle("UnitTest")] 6 | [assembly: AssemblyDescription("")] 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("HP Inc.")] 9 | [assembly: AssemblyProduct("UnitTest")] 10 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2019")] 11 | [assembly: AssemblyTrademark("")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | [assembly: ComVisible(false)] 15 | 16 | [assembly: Guid("c50464c7-343a-4945-9b44-0c0e6a4c628d")] 17 | 18 | // [assembly: AssemblyVersion("1.0.*")] 19 | [assembly: AssemblyVersion("1.0.0.0")] 20 | [assembly: AssemblyFileVersion("1.0.0.0")] 21 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace WPFApp 17 | { 18 | /// 19 | /// MainWindow.xaml の相互作用ロジック 20 | /// 21 | public partial class MainWindow : Window 22 | { 23 | public MainWindow() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Project/TestTargetx86/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Data; 9 | using System.Windows.Documents; 10 | using System.Windows.Input; 11 | using System.Windows.Media; 12 | using System.Windows.Media.Imaging; 13 | using System.Windows.Navigation; 14 | using System.Windows.Shapes; 15 | 16 | namespace TestTargetx86 17 | { 18 | /// 19 | /// MainWindow.xaml の相互作用ロジック 20 | /// 21 | public partial class MainWindow : Window 22 | { 23 | public MainWindow() 24 | { 25 | InitializeComponent(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SerializeUtility.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Codeer.Friendly.Windows.Inside 4 | { 5 | class SerializeUtility 6 | { 7 | internal static ICustomSerializer Serializer { get; set; } = new DefaultSerializer(); 8 | 9 | internal static byte[] Serialize(object obj)=> Serializer.Serialize(obj); 10 | 11 | internal static object Deserialize(byte[] bin) => Serializer.Deserialize(bin); 12 | 13 | internal static string GetRequiredAssembliesStartupInfo() 14 | { 15 | var list = new List(); 16 | foreach (var assembly in Serializer.GetRequiredAssemblies()) 17 | { 18 | list.Add(assembly.FullName + "|" + assembly.Location); 19 | } 20 | if (list.Count == 0) return string.Empty; 21 | 22 | return string.Join("||", list.ToArray()) + "||"; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/UniqueNoManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Codeer.Friendly.DotNetExecutor 4 | { 5 | /// 6 | /// 固有の番号管理。 7 | /// 8 | public class UniqueNoManager 9 | { 10 | int _no; 11 | Dictionary _curretExistNo = new Dictionary(); 12 | 13 | /// 14 | /// 番号生成。 15 | /// 16 | /// 番号。 17 | /// 成否。 18 | public bool CreateNo(out int no) 19 | { 20 | no = 0; 21 | _no++; 22 | int firstNo = _no; 23 | while (_no == 0 || _curretExistNo.ContainsKey(_no)) 24 | { 25 | _no++; 26 | if (_no == firstNo) 27 | { 28 | return false; 29 | } 30 | } 31 | no = _no; 32 | _curretExistNo.Add(no, true); 33 | return true; 34 | } 35 | 36 | /// 37 | /// 番号解放。 38 | /// 39 | /// 番号。 40 | public void FreeNo(int no) 41 | { 42 | _curretExistNo.Remove(no); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SystemControlInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Codeer.Friendly.Windows.Inside 4 | { 5 | /// 6 | /// システムコントロール情報。 7 | /// 8 | [Serializable] 9 | public class SystemControlInfo 10 | { 11 | /// 12 | /// コントロールタイプ。 13 | /// 14 | public SystemControlType SystemControlType { get; set; } 15 | 16 | /// 17 | /// データ。 18 | /// コントロールタイプによって異なる。 19 | /// 20 | public object Data { get; set; } 21 | 22 | /// 23 | /// コンストラクタ 24 | /// 25 | public SystemControlInfo() { } 26 | 27 | /// 28 | /// コンストラクタ。 29 | /// 30 | /// コントロールタイプ。 31 | /// データ。 32 | public SystemControlInfo(SystemControlType systemControlType, object data) 33 | { 34 | SystemControlType = systemControlType; 35 | Data = data; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Project/Test/Test/TestWPF.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Codeer.Friendly; 4 | using Codeer.Friendly.Dynamic; 5 | using Codeer.Friendly.Windows; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Windows; 9 | using System.Threading; 10 | 11 | namespace MultiDomainTest 12 | { 13 | [TestClass] 14 | public class TestWPF 15 | { 16 | [TestMethod] 17 | public void TestClose() 18 | { 19 | if (IntPtr.Size != 4) 20 | { 21 | return; 22 | } 23 | 24 | var p = Process.Start("WPFApp.exe"); 25 | using (var app = new WindowsAppFriend(p)) 26 | { 27 | var win = app.Type().Current.MainWindow; 28 | win.Close(); 29 | // Thread.Sleep(15000); 30 | win.Close(); 31 | 32 | /* 33 | while (true) 34 | { 35 | var win = app.Type().Current.MainWindow; 36 | }*/ 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/Codeer.Friendly.Windows.Step.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codeer.Friendly.Windows.Step", "Codeer.Friendly.Windows.Step.csproj", "{CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0}" 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 | {CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.42000 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WPFApp.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.5.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 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/DotNetFriendlyControl.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.ComponentModel; 4 | using Codeer.Friendly.Inside.Protocol; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace Codeer.Friendly.DotNetExecutor 8 | { 9 | /// 10 | /// .NetのFriendly処理制御。 11 | /// 12 | public class DotNetFriendlyControl 13 | { 14 | VarPool _pool = new VarPool(); 15 | TypeFinder _typeFinder = new TypeFinder(); 16 | 17 | /// 18 | /// 処理呼び出し。 19 | /// 20 | /// 非同期実行用。 21 | /// 呼び出し情報。 22 | /// 戻り値情報。 23 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 24 | public ReturnInfo Execute(IAsyncInvoke async, ProtocolInfo info) 25 | { 26 | try 27 | { 28 | return DotNetFriendlyExecutor.Execute(async, _pool, _typeFinder, info); 29 | } 30 | catch (Exception e) 31 | { 32 | return new ReturnInfo(new ExceptionInfo(e)); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/ContextOrderProtocolInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Codeer.Friendly.Inside.Protocol; 3 | 4 | namespace Codeer.Friendly.Windows.Inside 5 | { 6 | /// 7 | /// 実行コンテキスト指定プロトコル情報 8 | /// 9 | [Serializable] 10 | public class ContextOrderProtocolInfo 11 | { 12 | /// 13 | /// プロトコル情報 14 | /// 15 | public ProtocolInfo ProtocolInfo { get; set; } 16 | 17 | /// 18 | /// 実行ウィンドウ 19 | /// 20 | public IntPtr ExecuteWindowHandle { get; set; } 21 | 22 | /// 23 | /// コンストラクタ 24 | /// 25 | public ContextOrderProtocolInfo() { } 26 | 27 | /// 28 | /// コンストラクタ 29 | /// 30 | /// プロトコル情報 31 | /// 実行ウィンドウハンドル 32 | public ContextOrderProtocolInfo(ProtocolInfo protocolInfo, IntPtr executeWindowHandle) 33 | { 34 | ProtocolInfo = protocolInfo; 35 | ExecuteWindowHandle = executeWindowHandle; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Project/TestTargetx86/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TestTargetx86.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_2_32.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_4_32.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_4_64.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Project/TestTargetCore8/TestTargetCore8.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35222.181 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestTargetCore8", "TestTargetCore8\TestTargetCore8.csproj", "{9BAE3E0D-ED12-4198-A653-2FADEE68554F}" 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 | {9BAE3E0D-ED12-4198-A653-2FADEE68554F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {9BAE3E0D-ED12-4198-A653-2FADEE68554F}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {9BAE3E0D-ED12-4198-A653-2FADEE68554F}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {9BAE3E0D-ED12-4198-A653-2FADEE68554F}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {EE8B6130-46CA-48AF-BA09-2019855D016E} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Project/Attachx86/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // 制御されます。アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更します。 8 | [assembly: AssemblyTitle("Attachx86")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Attachx86")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから 18 | // 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 19 | // その型の ComVisible 属性を true に設定します。 20 | [assembly: ComVisible(false)] 21 | 22 | // このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります 23 | [assembly: Guid("76d53d43-1ec3-4d66-aaae-0c62b9eee748")] 24 | 25 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 26 | // 27 | // メジャー バージョン 28 | // マイナー バージョン 29 | // ビルド番号 30 | // リビジョン 31 | // 32 | // すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/VarAndType.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Codeer.Friendly.DotNetExecutor 4 | { 5 | /// 6 | /// 変数とタイプ。 7 | /// タイプをマルチスレッドで参照するため、生成時に取得しておく。 8 | /// 9 | class VarAndType 10 | { 11 | object _core; 12 | Type _type; 13 | 14 | /// 15 | /// コア 16 | /// 17 | internal object Core { get { return _core; } } 18 | 19 | /// 20 | /// タイプ 21 | /// 22 | internal Type Type { get { return _type; } } 23 | 24 | /// 25 | /// コンストラクタ 26 | /// 27 | /// コア 28 | internal VarAndType(object core) 29 | { 30 | _core = core; 31 | if (core != null) 32 | { 33 | _type = core.GetType(); 34 | } 35 | } 36 | 37 | /// 38 | /// コンストラクタ 39 | /// 40 | /// コア 41 | /// タイプ 42 | internal VarAndType(object core, Type type) 43 | { 44 | _core = core; 45 | _type = type; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Project/Test/Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MultiDomainTest")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MultiDomainTest")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照できなくなります。このアセンブリ内で COM から型にアクセスする必要がある場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // このプロジェクトが COM に公開される場合、次の GUID がタイプ ライブラリの ID になります。 23 | [assembly: Guid("549206b0-b168-411d-be97-cdb59212688c")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、以下のように '*' を使用してビルド番号とリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MultiDomain_2_32")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MultiDomain_2_32")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("85bc2efe-14ce-4a47-941c-1650b7c2c2e3")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MultiDomain_4_32")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MultiDomain_4_32")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("ff41fa6f-0d16-459a-ad97-83a873cca048")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("MultiDomain_4_64")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MultiDomain_4_64")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("ed2f83e7-8e40-419e-ba33-66bc5255b16d")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/UnitTestCore/UnitTestCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0-windows 5 | enable 6 | enable 7 | true 8 | 9 | false 10 | true 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 1701;1702;NU1701 33 | 34 | 35 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("Codeer.Friendly.Windows.Step")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Codeer.Friendly.Windows.Step")] 13 | [assembly: AssemblyCopyright("Copyright © 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("1507441d-e832-4ac0-ac0e-80e5a442d7c9")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.0.0.0")] 36 | [assembly: AssemblyFileVersion("2.0.0.0")] 37 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 6 | // アセンブリに関連付けられている情報を変更するには、 7 | // これらの属性値を変更してください。 8 | [assembly: AssemblyTitle("Codeer.Friendly.Windows")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Codeer.Friendly.Windows")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから 18 | // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 19 | // その型の ComVisible 属性を true に設定してください。 20 | [assembly: ComVisible(false)] 21 | 22 | // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です 23 | [assembly: Guid("c6057bc6-5357-4fd9-8c27-c6459fee82ce")] 24 | 25 | // アセンブリのバージョン情報は、以下の 4 つの値で構成されています: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を 33 | // 既定値にすることができます: 34 | [assembly: AssemblyVersion("2.18.0.0")] 35 | [assembly: AssemblyFileVersion("2.18.0.0")] 36 | [assembly: Codeer.Friendly.Inside.FriendlyInfoAttribute("invisible")] 37 | [assembly: System.CLSCompliant(true)] 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Friendly.Windows 2 | ======== 3 | 4 | Friendly is a library for creating integration tests.
5 | It has the ability to manipulate other processes.
6 | It is currently designed for Windows Applications (**WinForms**, **WPF**, and **Win32**).
7 | The name Friendly is derived from the C++ friend class.
8 | Being friends gives you access to what you normally wouldn't be able to do.
9 | 10 | ## Friendly support .NetCore. 11 | Friendly can also operate .NetCore WinForms and WPF apps. But please write the test code in .Net Framework. Sorry. 12 | 13 | ## Features ... 14 | ### Invoke separate process's API. 15 | It's like a selenium's javascript execution.
16 | All Methods, Properties and Fields can be called regardless of being public internal protected private. 17 | ### DLL injection. 18 | It can inject .net assembly. And can execute inserted methods. 19 | 20 | ## Getting Started 21 | Install Friendly.Windows from NuGet
22 | 23 | PM> Install-Package Codeer.Friendly.Windows 24 | 25 | https://www.nuget.org/packages/Codeer.Friendly.Windows/ 26 | 27 | ## See Friendly ReadMe for details 28 | https://github.com/Codeer-Software/Friendly 29 | 30 | Initially, Friendly defined a common interface, and Friendly.Windows was positioned as a Windows application version of that, but in reality there are only Windows applications, so I decided to put the documents together. -------------------------------------------------------------------------------- /Project/TestTargetCore8/TestTargetCore8/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TestTargetCore8 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 33 | this.ClientSize = new System.Drawing.Size(800, 450); 34 | this.Text = "Form1"; 35 | } 36 | 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/StartStep.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | 4 | namespace Codeer.Friendly.Windows.Step 5 | { 6 | /// 7 | /// 開始踏み台 8 | /// 9 | public static class StartStep 10 | { 11 | /// 12 | /// 開始。 13 | /// 14 | /// 開始情報。 15 | public static int Start(string startInfo) 16 | { 17 | AssemblyResolver.EntryAssembly(typeof(StartStep).Assembly); 18 | 19 | //ここでの引数エラーはAssert。 20 | //でも、通知は仕様的にできない。 21 | string[] infos = startInfo.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries); 22 | 23 | //アセンブリ読み込み 24 | for (int i = 0; i < infos.Length - 3; i++) 25 | { 26 | string[] asmInfo = infos[i].Split('|'); 27 | AssemblyResolver.LoadAssembly(asmInfo[0], asmInfo[1]); 28 | } 29 | 30 | //メソッド実行情報取得 31 | string szTypeFullName = infos[infos.Length - 3]; 32 | string szMethod = infos[infos.Length - 2]; 33 | string arg = infos[infos.Length - 1]; 34 | 35 | //実行 36 | MethodInfo method = new TypeFinder().GetType(szTypeFullName).GetMethod(szMethod); 37 | method.Invoke(null, new object[] { arg }); 38 | return 0; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Project/Nuget/Friendly.Windows.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Codeer.Friendly.Windows 5 | 2.18.0 6 | Friendly.Windows 7 | Codeer 8 | Codeer 9 | https://github.com/Codeer-Software/Friendly.Windows/blob/master/LICENSE 10 | https://github.com/Codeer-Software/Friendly.Windows 11 | https://raw.githubusercontent.com/Codeer-Software/Friendly/master/FriendlyNuget128.png 12 | false 13 | This is used for test automation of Windows applications. You can call the API of separate process from outside. 14 | Friendly Testing Windows WPF WinForms Win32 Automation 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/Debug.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System.Windows.Forms; 3 | using System.Diagnostics.CodeAnalysis; 4 | 5 | namespace Codeer.Friendly.Windows.Inside 6 | { 7 | /// 8 | /// デバッグ用クラス 9 | /// 10 | static class Debug 11 | { 12 | static bool _isDebug; 13 | 14 | /// 15 | /// デバッグモードマーク 16 | /// 17 | internal static string DebugMark { get { return _isDebug ? ("???") : (string.Empty); } } 18 | 19 | /// 20 | /// トレース 21 | /// 22 | /// メッセージ 23 | [SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions")] 24 | internal static void Trace(string msg) 25 | { 26 | if (!_isDebug) 27 | { 28 | return; 29 | } 30 | MessageBox.Show(msg, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); 31 | } 32 | 33 | /// 34 | /// バッグモードか否かを読み取る 35 | /// 36 | /// 情報文字列 37 | /// 情報コア 38 | internal static string ReadDebugMark(string info) 39 | { 40 | string infoCore = info.Replace("???", string.Empty); 41 | _isDebug = (info != infoCore); 42 | return infoCore; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Project/UnitTest/TestNetFramewrok.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Threading; 5 | using Codeer.Friendly.Dynamic; 6 | using Codeer.Friendly.Windows; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace UnitTest 10 | { 11 | [TestClass] 12 | public class TestNetFramewrok 13 | { 14 | //半自動のテスト 15 | [TestMethod] 16 | public void TestPermission() 17 | { 18 | if (IntPtr.Size != 4) return; 19 | 20 | var processes = Process.GetProcessesByName("TestTargetx86"); 21 | if (processes.Length != 1) return; 22 | 23 | var targetApp = processes[0]; 24 | var app = new WindowsAppFriend(targetApp); 25 | 26 | //操作確認 27 | app.Type("System.Windows.Application").Current.MainWindow.Title = "xxx"; 28 | } 29 | 30 | [TestMethod] 31 | public void TestNormal() 32 | { 33 | if (IntPtr.Size != 4) return; 34 | 35 | var targetExePath = Path.GetFullPath(GetType().Assembly.Location + @"..\..\..\..\..\TestTargetx86\bin\Debug\TestTargetx86.exe"); 36 | var targetApp = Process.Start(targetExePath); 37 | var app = new WindowsAppFriend(targetApp); 38 | 39 | //操作確認 40 | app.Type("System.Windows.Application").Current.MainWindow.Title = "xxx"; 41 | 42 | targetApp.Kill(); 43 | Thread.Sleep(1000); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MultiDomain_2_32 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// 必要なデザイナー変数です。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 使用中のリソースをすべてクリーンアップします。 12 | /// 13 | /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows フォーム デザイナーで生成されたコード 24 | 25 | /// 26 | /// デザイナー サポートに必要なメソッドです。このメソッドの内容を 27 | /// コード エディターで変更しないでください。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // MainForm 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.ClientSize = new System.Drawing.Size(284, 261); 38 | this.Name = "MainForm"; 39 | this.Text = "2_32"; 40 | this.ResumeLayout(false); 41 | 42 | } 43 | 44 | #endregion 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MultiDomain_4_32 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// 必要なデザイナー変数です。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 使用中のリソースをすべてクリーンアップします。 12 | /// 13 | /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows フォーム デザイナーで生成されたコード 24 | 25 | /// 26 | /// デザイナー サポートに必要なメソッドです。このメソッドの内容を 27 | /// コード エディターで変更しないでください。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // MainForm 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.ClientSize = new System.Drawing.Size(284, 261); 38 | this.Name = "MainForm"; 39 | this.Text = "4_32"; 40 | this.ResumeLayout(false); 41 | 42 | } 43 | 44 | #endregion 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MultiDomain_4_64 2 | { 3 | partial class MainForm 4 | { 5 | /// 6 | /// 必要なデザイナー変数です。 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// 使用中のリソースをすべてクリーンアップします。 12 | /// 13 | /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows フォーム デザイナーで生成されたコード 24 | 25 | /// 26 | /// デザイナー サポートに必要なメソッドです。このメソッドの内容を 27 | /// コード エディターで変更しないでください。 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // MainForm 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.ClientSize = new System.Drawing.Size(284, 261); 38 | this.Name = "MainForm"; 39 | this.Text = "4_64"; 40 | this.ResumeLayout(false); 41 | 42 | } 43 | 44 | #endregion 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindowsCore/CodeerFriendlyWindowsCore.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29123.88 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodeerFriendlyWindowsCore", "CodeerFriendlyWindowsCore.vcxproj", "{863CE9D9-1798-4679-AD17-677B2B090A7A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Debug|x64.ActiveCfg = Debug|x64 17 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Debug|x64.Build.0 = Debug|x64 18 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Debug|x86.ActiveCfg = Debug|Win32 19 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Debug|x86.Build.0 = Debug|Win32 20 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Release|x64.ActiveCfg = Release|x64 21 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Release|x64.Build.0 = Release|x64 22 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Release|x86.ActiveCfg = Release|Win32 23 | {863CE9D9-1798-4679-AD17-677B2B090A7A}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {83E17DFB-6CC2-455F-A5AF-6C56FFE289AD} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/TypeFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Codeer.Friendly.Windows.Step 6 | { 7 | /// 8 | /// 型に関するユーティリティー。 9 | /// 10 | public class TypeFinder 11 | { 12 | Dictionary _fullNameAndType = new Dictionary(); 13 | 14 | /// 15 | /// タイプフルネームから型を取得する。 16 | /// 17 | /// タイプフルネーム。 18 | /// 取得した型。 19 | public Type GetType(string typeFullName) 20 | { 21 | lock (_fullNameAndType) 22 | { 23 | //キャッシュを見る 24 | Type type = null; 25 | if (_fullNameAndType.TryGetValue(typeFullName, out type)) 26 | { 27 | return type; 28 | } 29 | 30 | //各アセンブリに問い合わせる 31 | Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 32 | List assemblyTypes = new List(); 33 | foreach (Assembly assembly in assemblies) 34 | { 35 | type = assembly.GetType(typeFullName); 36 | if (type != null) 37 | { 38 | break; 39 | } 40 | } 41 | if (type != null) 42 | { 43 | _fullNameAndType.Add(typeFullName, type); 44 | } 45 | return type; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CopyDataProtocol/CopyDataProtocolInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.Serialization; 4 | using System.Runtime.Serialization.Formatters.Binary; 5 | 6 | namespace Codeer.Friendly.Windows.Inside.CopyDataProtocol 7 | { 8 | /// 9 | /// 通信データ。 10 | /// 11 | [Serializable] 12 | public class CopyDataProtocolInfo 13 | { 14 | /// 15 | /// 返信ウィンドウハンドル。 16 | /// 17 | public IntPtr ReturnWindowHandle { get; set; } 18 | 19 | /// 20 | /// データ。 21 | /// 22 | public object Data { get; set; } 23 | 24 | /// 25 | /// コンストラクタ 26 | /// 27 | public CopyDataProtocolInfo() { } 28 | 29 | /// 30 | /// コンストラクタ。 31 | /// 32 | /// 返信ウィンドウ。 33 | /// データ。 34 | internal CopyDataProtocolInfo(IntPtr returnWindowHandle, object data) 35 | { 36 | ReturnWindowHandle = returnWindowHandle; 37 | Data = data; 38 | } 39 | 40 | /// 41 | /// シリアライズ。 42 | /// 43 | /// バイナリ。 44 | internal byte[] Serialize() => SerializeUtility.Serialize(this); 45 | 46 | /// 47 | /// デシリアライズ。 48 | /// 49 | /// バイナリ。 50 | /// データ。 51 | internal static CopyDataProtocolInfo Deserialize(byte[] bin) => (CopyDataProtocolInfo)SerializeUtility.Deserialize(bin); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CpuTargetCheckUtility.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.Diagnostics; 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace Codeer.Friendly.Windows.Inside 7 | { 8 | /// 9 | /// CPU対象チェック 10 | /// 11 | public static class CpuTargetCheckUtility 12 | { 13 | /// 14 | /// 同一のCPUをターゲットとしているか 15 | /// 16 | /// プロセス 17 | /// テスト対象となりえるか 18 | public static bool IsSameCpu(Process process) 19 | { 20 | return IsWow64(process) == IsWow64(Process.GetCurrentProcess()); 21 | } 22 | 23 | /// 24 | /// Wow64上で動作しているか 25 | /// 26 | /// プロセス 27 | /// Wow64上で動作しているか 28 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 29 | static bool IsWow64(Process process) 30 | { 31 | //IsWow64Processが使えるか調べる 32 | IntPtr wow64Proc = NativeMethods.GetProcAddress(NativeMethods.GetModuleHandle("Kernel32.dll"), "IsWow64Process"); 33 | if (wow64Proc == IntPtr.Zero) 34 | { 35 | return false; 36 | } 37 | try 38 | { 39 | //IsWow64Processを呼び出す 40 | bool is32; 41 | if (NativeMethods.IsWow64Process(process.Handle, out is32)) 42 | { 43 | return is32; 44 | } 45 | } 46 | catch { } 47 | return false; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CopyDataProtocol/ReceiveAfterSend.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Codeer.Friendly; 4 | using Codeer.Friendly.DotNetExecutor; 5 | 6 | namespace Codeer.Friendly.Windows.Inside.CopyDataProtocol 7 | { 8 | /// 9 | /// 送信後の返信受信。 10 | /// 11 | class ReceiveAfterSend : ReceiveForm 12 | { 13 | Dictionary _recieveData = new Dictionary(); 14 | UniqueNoManager _uniqueNoManager = new UniqueNoManager(); 15 | 16 | /// 17 | /// 通信番号管理用。 18 | /// 19 | internal UniqueNoManager UniqueNoManager { get { return _uniqueNoManager; } } 20 | 21 | /// 22 | /// データ受信時の処理。 23 | /// 24 | /// 通信番号。 25 | /// 受信データ。 26 | /// 送信元ウィンドウ。 27 | protected override void OnRecieveData(int communicationNo, object recieveData, IntPtr senderWindow) 28 | { 29 | _recieveData.Remove(communicationNo); 30 | _recieveData.Add(communicationNo, recieveData); 31 | } 32 | 33 | /// 34 | /// 受信データ取得。 35 | /// 36 | /// 通信番号。 37 | /// 受信データ。 38 | /// 成否。 39 | internal bool GetReceiveData(int communicationNo, out object receieveData) 40 | { 41 | if (!_recieveData.TryGetValue(communicationNo, out receieveData)) 42 | { 43 | return false; 44 | } 45 | _recieveData.Remove(communicationNo); 46 | return true; 47 | } 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Project/TestTargetCore/TestTargetCore.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestTargetCore", "TestTargetCore.csproj", "{09199774-3433-4B37-B339-D2568E2F2E3C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|x64.ActiveCfg = Debug|Any CPU 24 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|x64.Build.0 = Debug|Any CPU 25 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|x86.ActiveCfg = Debug|Any CPU 26 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Debug|x86.Build.0 = Debug|Any CPU 27 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|x64.ActiveCfg = Release|Any CPU 30 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|x64.Build.0 = Release|Any CPU 31 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|x86.ActiveCfg = Release|Any CPU 32 | {09199774-3433-4B37-B339-D2568E2F2E3C}.Release|x86.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /Project/Test/Test/MultiDomainTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Codeer.Friendly; 4 | using Codeer.Friendly.Dynamic; 5 | using Codeer.Friendly.Windows; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | 9 | namespace MultiDomainTest 10 | { 11 | [TestClass] 12 | public class MultiDomainTest 13 | { 14 | [TestMethod] 15 | public void Test_MultiDomain_2_32() 16 | { 17 | if (IntPtr.Size != 4) 18 | { 19 | return; 20 | } 21 | TestCore("MultiDomain_2_32.exe"); 22 | } 23 | 24 | [TestMethod] 25 | public void Test_MultiDomain_4_32() 26 | { 27 | if (IntPtr.Size != 4) 28 | { 29 | return; 30 | } 31 | TestCore("MultiDomain_4_32.exe"); 32 | } 33 | 34 | [TestMethod] 35 | public void Test_MultiDomain_4_64() 36 | { 37 | if (IntPtr.Size != 8) 38 | { 39 | return; 40 | } 41 | TestCore("MultiDomain_4_64.exe"); 42 | } 43 | 44 | private static void TestCore(string exePath) 45 | { 46 | Process process = Process.Start(exePath); 47 | using (var app = new WindowsAppFriend(process)) 48 | { 49 | app.Type().System.Windows.Forms.Application.OpenForms[0].StartMultiDomain(); 50 | var apps = app.AttachOtherDomains(); 51 | var names = apps.Select(e => (string)e.Type().CurrentDomain.FriendlyName); 52 | Assert.AreEqual(2, names.Count()); 53 | Assert.IsTrue(names.Any(e => e == "XXX")); 54 | Assert.IsTrue(names.Any(e => e == "YYY")); 55 | } 56 | process.Kill(); 57 | } 58 | 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/ProtocolMessageManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Codeer.Friendly.Windows.Inside 5 | { 6 | /// 7 | /// プロトコルメッセージマネージャ 8 | /// 9 | static class ProtocolMessageManager 10 | { 11 | /// 12 | /// メッセージフィルタ識別子 13 | /// 14 | internal enum ChangeWindowMessageFilterFlags : uint 15 | { 16 | /// 17 | /// 追加 18 | /// 19 | Add = 1, 20 | 21 | /// 22 | /// 削除 23 | /// 24 | Remove = 2 25 | }; 26 | 27 | /// 28 | /// メッセージフィルタ型 29 | /// 30 | /// メッセージ 31 | /// フラグ 32 | /// 成否 33 | internal delegate bool ChangeWindowMessageFilter(uint msg, ChangeWindowMessageFilterFlags flags); 34 | 35 | /// 36 | /// 初期化 37 | /// 38 | internal static void Initialize() 39 | { 40 | IntPtr ptr = NativeMethods.LoadLibrary("user32.dll"); 41 | IntPtr pFunc = NativeMethods.GetProcAddress(ptr, "ChangeWindowMessageFilter"); 42 | if (pFunc == IntPtr.Zero) 43 | { 44 | return; 45 | } 46 | //対象アプリケーションから受信するメッセージがUACに邪魔されないようにする 47 | ChangeWindowMessageFilter filter = (ChangeWindowMessageFilter)Marshal.GetDelegateForFunctionPointer(pFunc, typeof(ChangeWindowMessageFilter)); 48 | filter(SystemStarterInApp.WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE, ChangeWindowMessageFilterFlags.Add); 49 | filter(NativeMethods.WM_COPYDATA, ChangeWindowMessageFilterFlags.Add); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 8 | // アセンブリに関連付けられている情報を変更するには、 9 | // これらの属性値を変更してください。 10 | [assembly: AssemblyTitle("WPFApp")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("HP Inc.")] 14 | [assembly: AssemblyProduct("WPFApp")] 15 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2018")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから 20 | // 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 21 | // その型の ComVisible 属性を true に設定してください。 22 | [assembly: ComVisible(false)] 23 | 24 | //ローカライズ可能なアプリケーションのビルドを開始するには、 25 | //.csproj ファイルの CultureYouAreCodingWith を 26 | // 内部で設定します。たとえば、 27 | //ソース ファイルで英語を使用している場合、 を en-US に設定します。次に、 28 | //下の NeutralResourceLanguage 属性のコメントを解除します。下の行の "en-US" を 29 | //プロジェクト ファイルの UICulture 設定と一致するよう更新します。 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //テーマ固有のリソース ディクショナリが置かれている場所 36 | //(リソースがページ、 37 | //またはアプリケーション リソース ディクショナリに見つからない場合に使用されます) 38 | ResourceDictionaryLocation.SourceAssembly //汎用リソース ディクショナリが置かれている場所 39 | //(リソースがページ、 40 | //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) 41 | )] 42 | 43 | 44 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 45 | // 46 | // メジャー バージョン 47 | // マイナー バージョン 48 | // ビルド番号 49 | // Revision 50 | // 51 | // すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます 52 | // 既定値にすることができます: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /Project/TestTargetx86/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 8 | // アセンブリに関連付けられている情報を変更するには、 9 | // これらの属性値を変更してください。 10 | [assembly: AssemblyTitle("TestTargetx86")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("TestTargetx86")] 15 | [assembly: AssemblyCopyright("Copyright © 2019")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから 20 | // 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、 21 | // その型の ComVisible 属性を true に設定してください。 22 | [assembly: ComVisible(false)] 23 | 24 | //ローカライズ可能なアプリケーションのビルドを開始するには、 25 | //.csproj ファイルの CultureYouAreCodingWith を 26 | // 内部で設定します。たとえば、 27 | //ソース ファイルで英語を使用している場合、 を en-US に設定します。次に、 28 | //下の NeutralResourceLanguage 属性のコメントを解除します。下の行の "en-US" を 29 | //プロジェクト ファイルの UICulture 設定と一致するよう更新します。 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //テーマ固有のリソース ディクショナリが置かれている場所 36 | //(リソースがページ、 37 | // またはアプリケーション リソース ディクショナリに見つからない場合に使用されます) 38 | ResourceDictionaryLocation.SourceAssembly //汎用リソース ディクショナリが置かれている場所 39 | //(リソースがページ、 40 | //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) 41 | )] 42 | 43 | 44 | // アセンブリのバージョン情報は次の 4 つの値で構成されています: 45 | // 46 | // メジャー バージョン 47 | // マイナー バージョン 48 | // ビルド番号 49 | // リビジョン 50 | // 51 | // すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます 52 | // 既定値にすることができます: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindows/CodeerFriendlyWindows.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CodeerFriendlyWindows", "CodeerFriendlyWindows.vcxproj", "{163505AC-BD7B-4327-AF32-D6A03F571F59}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|Mixed Platforms = Debug|Mixed Platforms 12 | Debug|Win32 = Debug|Win32 13 | Debug|x64 = Debug|x64 14 | Release|Any CPU = Release|Any CPU 15 | Release|Mixed Platforms = Release|Mixed Platforms 16 | Release|Win32 = Release|Win32 17 | Release|x64 = Release|x64 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|Any CPU.ActiveCfg = Debug|Win32 21 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 22 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|Mixed Platforms.Build.0 = Debug|Win32 23 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|Win32.ActiveCfg = Debug|Win32 24 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|Win32.Build.0 = Debug|Win32 25 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|x64.ActiveCfg = Debug|x64 26 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Debug|x64.Build.0 = Debug|x64 27 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|Any CPU.ActiveCfg = Release|Win32 28 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|Mixed Platforms.ActiveCfg = Release|Win32 29 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|Mixed Platforms.Build.0 = Release|Win32 30 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|Win32.ActiveCfg = Release|Win32 31 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|Win32.Build.0 = Release|Win32 32 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|x64.ActiveCfg = Release|x64 33 | {163505AC-BD7B-4327-AF32-D6A03F571F59}.Release|x64.Build.0 = Release|x64 34 | EndGlobalSection 35 | GlobalSection(SolutionProperties) = preSolution 36 | HideSolutionNode = FALSE 37 | EndGlobalSection 38 | EndGlobal 39 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/FriendlyConnectorWindowInAppManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Codeer.Friendly.Windows.Inside 5 | { 6 | /// 7 | /// Friendly接続ウィンドウ管理。 8 | /// スレッドセーフである。 9 | /// 10 | class FriendlyConnectorWindowInAppManager 11 | { 12 | Dictionary _handleAndWindow = new Dictionary(); 13 | 14 | /// 15 | /// 追加。 16 | /// ウィンドウの所属するスレッドと実行スレッドが違う可能性があるので、ウィンドウからハンドルを取得しない。 17 | /// 18 | /// ハンドル。 19 | /// ウィンドウ。 20 | internal void Add(IntPtr handle, FriendlyConnectorWindowInApp window) 21 | { 22 | lock (this) 23 | { 24 | _handleAndWindow.Add(handle, window); 25 | } 26 | } 27 | 28 | /// 29 | /// クローンの作成。 30 | /// 31 | /// クローン。 32 | internal Dictionary Clone() 33 | { 34 | lock (this) 35 | { 36 | return new Dictionary(_handleAndWindow); 37 | } 38 | } 39 | 40 | /// 41 | /// ハンドルから検索。 42 | /// 43 | /// ハンドル 44 | /// Friendly接続ウィンドウ 45 | internal FriendlyConnectorWindowInApp FromHandle(IntPtr handle) 46 | { 47 | lock (this) 48 | { 49 | FriendlyConnectorWindowInApp window; 50 | return _handleAndWindow.TryGetValue(handle, out window) ? window : null; 51 | } 52 | } 53 | 54 | /// 55 | /// 削除 56 | /// 57 | /// ハンドル。 58 | internal void Remove(IntPtr handle) 59 | { 60 | lock (this) 61 | { 62 | _handleAndWindow.Remove(handle); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | 110 | packages/ 111 | ReleaseBinary/ 112 | bin/ 113 | Debug/ 114 | Release/ 115 | TestResults/ 116 | .vs 117 | *.nupkg 118 | !Project/AppTest/Codeer.Friendly.Windows/Resources/* -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/AssemblyResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Codeer.Friendly.Windows.Step 6 | { 7 | /// 8 | /// Windowsアプリケーション拡張。 9 | /// 10 | public static class AssemblyResolver 11 | { 12 | static bool connected; 13 | static Dictionary _asmDic = new Dictionary(); 14 | 15 | /// 16 | /// アセンブリのフルネームで読み込めたら、それを採用。 17 | /// 読み込めなければ、指定のファイルパスを使う。 18 | /// 19 | /// 長い形式のアセンブリ名。 20 | /// ファイルパス。 21 | internal static void LoadAssembly(string assemblyString, string filePath) 22 | { 23 | lock (_asmDic) 24 | { 25 | if (_asmDic.ContainsKey(assemblyString)) 26 | { 27 | return; 28 | } 29 | } 30 | Assembly asm = null; 31 | try 32 | { 33 | asm = Assembly.Load(assemblyString); 34 | } 35 | catch { } 36 | if (asm == null) 37 | { 38 | asm = Assembly.LoadFrom(filePath); 39 | } 40 | EntryAssembly(asm); 41 | } 42 | 43 | /// 44 | /// アセンブリ登録。 45 | /// 46 | /// アセンブリ。 47 | internal static void EntryAssembly(Assembly asm) 48 | { 49 | lock (_asmDic) 50 | { 51 | if (_asmDic.ContainsKey(asm.FullName)) 52 | { 53 | return; 54 | } 55 | _asmDic.Add(asm.FullName, asm); 56 | if (!connected) 57 | { 58 | connected = true; 59 | AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) 60 | { 61 | Assembly resolve; 62 | return _asmDic.TryGetValue(args.Name, out resolve) ? resolve : null; 63 | }; 64 | } 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/ICustomSerializer.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using System.Runtime.Serialization.Formatters.Binary; 4 | 5 | namespace Codeer.Friendly.Windows 6 | { 7 | /// 8 | /// ICustomSerializer 9 | /// 10 | public interface ICustomSerializer 11 | { 12 | /// 13 | /// Serialize 14 | /// 15 | /// object 16 | /// binary 17 | byte[] Serialize(object obj); 18 | 19 | /// 20 | /// Deserialize 21 | /// 22 | /// binary 23 | /// object 24 | object Deserialize(byte[] bin); 25 | 26 | /// 27 | /// Assembly required for use. 28 | /// 29 | /// Assemblies 30 | Assembly[] GetRequiredAssemblies(); 31 | } 32 | 33 | /// 34 | /// DefaultSerializer 35 | /// 36 | public class DefaultSerializer : ICustomSerializer 37 | { 38 | /// 39 | /// Serialize 40 | /// 41 | /// object 42 | /// binary 43 | public byte[] Serialize(object obj) 44 | { 45 | var formatter = new BinaryFormatter(); 46 | using (var stream = new MemoryStream()) 47 | { 48 | formatter.Serialize(stream, obj); 49 | return stream.ToArray(); 50 | } 51 | } 52 | 53 | /// 54 | /// Deserialize 55 | /// 56 | /// binary 57 | /// object 58 | public object Deserialize(byte[] bin) 59 | { 60 | var formatter = new BinaryFormatter(); 61 | using (var stream = new MemoryStream(bin)) 62 | { 63 | return formatter.Deserialize(stream); 64 | } 65 | } 66 | 67 | /// 68 | /// Assembly required for use. 69 | /// 70 | /// Assemblies 71 | public Assembly[] GetRequiredAssemblies() => new Assembly[0]; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/TargetWindowExecutor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Runtime.InteropServices; 4 | using System.Threading; 5 | 6 | namespace Codeer.Friendly.Windows.Inside 7 | { 8 | /// 9 | /// 指定のウィンドウで処理を実行させる。 10 | /// 11 | class TargetWindowExecutor 12 | { 13 | /// 14 | /// 実行。 15 | /// 16 | /// 処理を実行させるウィンドウ。 17 | /// 処理。 18 | /// 成否。 19 | internal static bool Execute(IntPtr targetThreadWindowHandle, MethodInvoker action) 20 | { 21 | //現在のウィンドウプロックを取得 22 | IntPtr currentProc = NativeMethods.GetWindowLongPtr(targetThreadWindowHandle, NativeMethods.GWL_WNDPROC); 23 | //InvokeWindowを起動するためのプロックを設定 24 | bool executed = false; 25 | NativeMethods.WndProc proc = delegate(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) 26 | { 27 | switch (msg) 28 | { 29 | case 0: 30 | if (!executed) 31 | { 32 | action(); 33 | executed = true; 34 | } 35 | break; 36 | default: 37 | break; 38 | } 39 | return NativeMethods.CallWindowProc(currentProc, hwnd, msg, wParam, lParam); 40 | }; 41 | NativeMethods.SetWindowLongPtr(targetThreadWindowHandle, NativeMethods.GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(proc)); 42 | 43 | //実行完了待ち 44 | while (!executed) 45 | { 46 | //指定のウィンドウが消えていたら終了 47 | if (!NativeMethods.IsWindow(targetThreadWindowHandle)) 48 | { 49 | return false; 50 | } 51 | NativeMethods.SendMessage(targetThreadWindowHandle, 0, IntPtr.Zero, IntPtr.Zero); 52 | Thread.Sleep(10); 53 | } 54 | GC.KeepAlive(proc); 55 | GC.KeepAlive(action); 56 | 57 | //元に戻す 58 | NativeMethods.SetWindowLongPtr(targetThreadWindowHandle, NativeMethods.GWL_WNDPROC, currentProc); 59 | return true; 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.42000 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WPFApp.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFApp.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 51 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Project/TestTargetx86/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.42000 5 | // 6 | // このファイルへの変更は、正しくない動作の原因になったり、 7 | // コードが再生成されるときに失われたりします。 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TestTargetx86.Properties 12 | { 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスによって ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをリビルドします。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// このクラスで使用されるキャッシュされた ResourceManager インスタンスを返します。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestTargetx86.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// すべてについて、現在のスレッドの CurrentUICulture プロパティをオーバーライドします 56 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.34014 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_2_32.Properties 12 | { 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをリビルドします。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// このクラスに使用される、キャッシュされた ResourceManager のインスタンスを返します。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MultiDomain_2_32.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 56 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.34014 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_4_32.Properties 12 | { 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをリビルドします。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// このクラスに使用される、キャッシュされた ResourceManager のインスタンスを返します。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MultiDomain_4_32.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 56 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // このコードはツールによって生成されました。 4 | // ランタイム バージョン:4.0.30319.34014 5 | // 6 | // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 7 | // コードが再生成されるときに損失したりします 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace MultiDomain_4_64.Properties 12 | { 13 | 14 | 15 | /// 16 | /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 17 | /// 18 | // このクラスは StronglyTypedResourceBuilder クラスが ResGen 19 | // または Visual Studio のようなツールを使用して自動生成されました。 20 | // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に 21 | // ResGen を実行し直すか、または VS プロジェクトをリビルドします。 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// このクラスに使用される、キャッシュされた ResourceManager のインスタンスを返します。 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MultiDomain_4_64.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 56 | /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/Codeer.Friendly.Windows.Step.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {CF2D3C8D-2D2A-41F8-A0DA-D958BDE641F0} 9 | Library 10 | Properties 11 | Codeer.Friendly.Windows.Step 12 | Codeer.Friendly.Windows.Step 13 | v2.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | 36 | 37 | Codeer.Friendly.Windows.Step.snk 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | if $(ConfigurationName) == Release Copy "$(TargetPath)" "../../../Codeer.Friendly.Windows/Resources/$(TargetFileName)" 57 | 58 | 65 | -------------------------------------------------------------------------------- /Project/Attachx86/Attachx86.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748} 8 | Exe 9 | Attachx86 10 | Attachx86 11 | v4.0 12 | 512 13 | true 14 | 15 | 16 | x86 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | x86 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\Codeer.Friendly.Windows\packages\Codeer.Friendly.2.7.0\lib\net40\Codeer.Friendly.dll 37 | 38 | 39 | ..\Codeer.Friendly.Windows\packages\Codeer.Friendly.2.7.0\lib\net40\Codeer.Friendly.Dynamic.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {56a947b0-1df8-4116-8152-ab2d4b6042c3} 56 | Codeer.Friendly.Windows 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Project/UnitTest/TestHandOverResources.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using Codeer.Friendly; 5 | using Codeer.Friendly.Dynamic; 6 | using Codeer.Friendly.Windows; 7 | using Microsoft.VisualStudio.TestTools.UnitTesting; 8 | 9 | namespace UnitTest 10 | { 11 | [TestClass] 12 | public class TestHandOverResources 13 | { 14 | WindowsAppFriend app2; 15 | 16 | [TestInitialize] 17 | public void TestInitialize() 18 | { 19 | //対象プロセス(x86) 20 | var targetExePath = Path.GetFullPath(GetType().Assembly.Location + @"..\..\..\..\..\TestTargetx86\bin\Debug\TestTargetx86.exe"); 21 | var targetApp = Process.Start(targetExePath); 22 | 23 | //アタッチしてその通信情報を引き継ぐためのバイナリを生成 24 | var myProcess = Process.GetCurrentProcess(); 25 | var binPath = Path.GetTempFileName(); 26 | var attachExePath = Path.GetFullPath(GetType().Assembly.Location + @"..\..\..\..\..\Attachx86\bin\Debug\Attachx86.exe"); 27 | Process.Start(attachExePath, $"{targetApp.Id} {myProcess.Id} {binPath}").WaitForExit(); 28 | 29 | //バイナリを元にWindowsAppFriend生成 30 | var bin = File.ReadAllBytes(binPath); 31 | File.Delete(binPath); 32 | app2 = new WindowsAppFriend(targetApp.MainWindowHandle, bin); 33 | } 34 | 35 | [TestCleanup] 36 | public void TestCleanup() => Process.GetProcessById(app2.ProcessId).Kill(); 37 | 38 | [TestMethod] 39 | public void Execute64() 40 | { 41 | //操作確認 42 | app2.Type("System.Windows.Application").Current.MainWindow.Title = "xxx"; 43 | } 44 | 45 | [TestMethod] 46 | public void ConvertToWrapper() 47 | { 48 | WindowWrapper w = app2.Type("System.Windows.Application").Current.MainWindow; 49 | w.Title = "yyy"; 50 | } 51 | 52 | [TestMethod] 53 | public void ConvertNull() 54 | { 55 | app2.LoadAssembly(GetType().Assembly); 56 | WindowWrapper w = app2.Null(); 57 | Assert.IsNull(w); 58 | } 59 | 60 | [TestMethod] 61 | public void SerializeTest() 62 | { 63 | app2.LoadAssembly(GetType().Assembly); 64 | WindowWrapperSerializable data = app2.Type(GetType()).SerializableData; 65 | Assert.AreEqual(100, data.Value); 66 | } 67 | 68 | public class WindowWrapper 69 | { 70 | AppVar _core; 71 | public WindowWrapper(AppVar src) 72 | { 73 | _core = src; 74 | } 75 | 76 | public string Title 77 | { 78 | get => _core.Dynamic().Title; 79 | set => _core.Dynamic().Title = value; 80 | } 81 | } 82 | 83 | public static WindowWrapperSerializable SerializableData = new WindowWrapperSerializable { Value = 100 }; 84 | 85 | [Serializable] 86 | public class WindowWrapperSerializable 87 | { 88 | public int Value { get; set; } 89 | 90 | public WindowWrapperSerializable(AppVar src) { } 91 | 92 | public WindowWrapperSerializable() { } 93 | } 94 | 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CopyDataProtocol/CopyDataProtocolTalker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using System.Runtime.InteropServices; 4 | using Codeer.Friendly; 5 | using Codeer.Friendly.Inside.Protocol; 6 | using Codeer.Friendly.Inside; 7 | 8 | namespace Codeer.Friendly.Windows.Inside.CopyDataProtocol 9 | { 10 | /// 11 | /// Windowメッセージ通信。 12 | /// 13 | static class CopyDataProtocolTalker 14 | { 15 | /// 16 | /// 送受信。 17 | /// 18 | /// 送信対象ウィンドウハンドル。 19 | /// 送信データ。 20 | /// 受信データ。 21 | internal static object SendAndRecieve(IntPtr targetWindowHandle, object data) 22 | { 23 | using(ReceiveAfterSend recieveWindow = new ReceiveAfterSend()) 24 | { 25 | return SendAndRecieve(targetWindowHandle, data, recieveWindow); 26 | } 27 | } 28 | 29 | /// 30 | /// 送受信。 31 | /// 32 | /// 送信対象ウィンドウハンドル。 33 | /// 送信データ。 34 | /// 受信ウィンドウ。 35 | /// 受信データ。 36 | internal static object SendAndRecieve(IntPtr targetWindowHandle, object data, ReceiveAfterSend recieveWindow) 37 | { 38 | //通信番号生成 39 | int communicationNo = 0; 40 | if (!recieveWindow.UniqueNoManager.CreateNo(out communicationNo)) 41 | { 42 | throw new InformationException(ResourcesLocal.Instance.OutOfCommunicationNo); 43 | } 44 | 45 | //使用可能なスレッドであるかチェック 46 | if (!recieveWindow.CanUseThread) 47 | { 48 | throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorInvalidThreadCall); 49 | } 50 | 51 | //送受信 52 | IntPtr globalData = IntPtr.Zero; 53 | try 54 | { 55 | //通信データ作成 56 | CopyDataProtocolInfo communicationData = new CopyDataProtocolInfo(recieveWindow.Handle, data); 57 | 58 | //シリアライズ 59 | byte[] bin = communicationData.Serialize(); 60 | 61 | //WM_COPYDATAでの送信用構造体に移し替え 62 | NativeMethods.COPYDATASTRUCT copyData = new NativeMethods.COPYDATASTRUCT(); 63 | copyData.dwData = IntPtr.Zero; 64 | copyData.cbData = (uint)bin.Length; 65 | copyData.lpData = globalData = Marshal.AllocHGlobal(bin.Length); 66 | Marshal.Copy(bin, 0, copyData.lpData, bin.Length); 67 | 68 | //送信 69 | IntPtr sendRet = NativeMethods.SendMessage(targetWindowHandle, NativeMethods.WM_COPYDATA, new IntPtr(communicationNo), ref copyData); 70 | if (sendRet != ReceiveForm.SendCopyDataSuccess) 71 | { 72 | throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorAppCommunication); 73 | } 74 | 75 | //受信データ取得 76 | object receiveData; 77 | if (!recieveWindow.GetReceiveData(communicationNo, out receiveData)) 78 | { 79 | throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorAppCommunication); 80 | } 81 | return receiveData; 82 | } 83 | finally 84 | { 85 | //グローバルメモリ解放 86 | if (globalData != IntPtr.Zero) 87 | { 88 | Marshal.FreeHGlobal(globalData); 89 | } 90 | recieveWindow.UniqueNoManager.FreeNo(communicationNo); 91 | } 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/WindowsAppExpanderInApp.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace Codeer.Friendly.Windows.Inside 8 | { 9 | /// 10 | /// Windowsアプリケーション拡張。 11 | /// 12 | public static class WindowsAppExpanderInApp 13 | { 14 | static bool connected; 15 | static Dictionary _asmDic = new Dictionary(); 16 | 17 | /// 18 | /// DLLのロード。 19 | /// 20 | /// ファイル名称。 21 | /// モジュールハンドル。 22 | static IntPtr LoadLibrary(string fileName) 23 | { 24 | return NativeMethods.LoadLibrary(fileName); 25 | } 26 | 27 | /// 28 | /// ファイルからアセンブリ読み込み。 29 | /// 30 | /// ファイルパス。 31 | static void LoadFile(string filePath) 32 | { 33 | EntryAssembly(Assembly.LoadFile(filePath)); 34 | } 35 | 36 | /// 37 | /// アセンブリのフルネームで読み込めたら、それを採用。 38 | /// 読み込めなければ、指定のファイルパスを使う。 39 | /// 40 | /// 長い形式のアセンブリ名。 41 | /// ファイルパス。 42 | internal static void LoadAssembly(string assemblyString, string filePath) 43 | { 44 | lock (_asmDic) 45 | { 46 | if (_asmDic.ContainsKey(assemblyString)) 47 | { 48 | return; 49 | } 50 | } 51 | Assembly asm = null; 52 | try 53 | { 54 | asm = Assembly.Load(assemblyString); 55 | } 56 | catch { } 57 | if (asm == null) 58 | { 59 | asm = Assembly.LoadFrom(filePath); 60 | } 61 | EntryAssembly(asm); 62 | } 63 | 64 | /// 65 | /// アセンブリ名称からアセンブリ読み込み。 66 | /// 67 | /// 長い形式のアセンブリ名。 68 | [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "0#")] 69 | static void Load(string assemblyString) 70 | { 71 | EntryAssembly(Assembly.Load(assemblyString)); 72 | } 73 | 74 | /// 75 | /// アセンブリ登録。 76 | /// 77 | /// アセンブリ。 78 | internal static void EntryAssembly(Assembly asm) 79 | { 80 | lock (_asmDic) 81 | { 82 | if (_asmDic.ContainsKey(asm.FullName)) 83 | { 84 | return; 85 | } 86 | _asmDic.Add(asm.FullName, asm); 87 | if (!connected) 88 | { 89 | connected = true; 90 | AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs args) 91 | { 92 | Assembly resolve; 93 | return _asmDic.TryGetValue(args.Name, out resolve) ? resolve : null; 94 | }; 95 | } 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SystemController.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using Codeer.Friendly.Windows.Inside.CopyDataProtocol; 4 | using System.Diagnostics.CodeAnalysis; 5 | 6 | namespace Codeer.Friendly.Windows.Inside 7 | { 8 | /// 9 | /// システム制御。 10 | /// 11 | class SystemController 12 | { 13 | internal IntPtr SystemControlWindowInAppHandle { get; } 14 | IntPtr _friendlyConnectorWindowInAppAsync; 15 | 16 | /// 17 | /// コンストラクタ。 18 | /// 19 | /// システムコントロールウィンドウハンドル。 20 | internal SystemController(IntPtr systemControlWindowInAppHandle) 21 | { 22 | SystemControlWindowInAppHandle = systemControlWindowInAppHandle; 23 | 24 | //コントロールスレッドに非同期通信用を一つ確保する 25 | _friendlyConnectorWindowInAppAsync = (IntPtr)CopyDataProtocolTalker.SendAndRecieve(SystemControlWindowInAppHandle, 26 | new SystemControlInfo(SystemControlType.StartFriendlyConnectorWindowInApp, SystemControlWindowInAppHandle)); 27 | if (_friendlyConnectorWindowInAppAsync == IntPtr.Zero) 28 | { 29 | throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorExecuteThreadWindowHandle); 30 | } 31 | } 32 | 33 | /// 34 | /// FriendlyConnector開始。 35 | /// 36 | /// 実行対象スレッドに属するウィンドウハンドル。 37 | /// FriendlyConnector。 38 | internal FriendlyConnectorCore StartFriendlyConnector(IntPtr executeThreadWindowHandle) 39 | { 40 | //通信用ウィンドウを生成 41 | IntPtr friendlyConnectorWindowInApp = (IntPtr)CopyDataProtocolTalker.SendAndRecieve(SystemControlWindowInAppHandle, 42 | new SystemControlInfo(SystemControlType.StartFriendlyConnectorWindowInApp, executeThreadWindowHandle)); 43 | if (friendlyConnectorWindowInApp == IntPtr.Zero) 44 | { 45 | throw new FriendlyOperationException(ResourcesLocal.Instance.ErrorExecuteThreadWindowHandle); 46 | } 47 | return new FriendlyConnectorCore(_friendlyConnectorWindowInAppAsync, friendlyConnectorWindowInApp); 48 | } 49 | 50 | /// 51 | /// FriendlyConnector終了。 52 | /// 53 | /// アプリケーション内部のFriendlyConnectorWindowのハンドル。 54 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 55 | internal void EndFriendlyConnector(IntPtr friendlyConnectorWindowInApp) 56 | { 57 | //タイミングによっては相手アプリケーションが存在しないことは十分にありうる 58 | try 59 | { 60 | CopyDataProtocolTalker.SendAndRecieve(SystemControlWindowInAppHandle, 61 | new SystemControlInfo(SystemControlType.EndFriendlyConnectorWindowInApp, friendlyConnectorWindowInApp)); 62 | } 63 | catch { } 64 | } 65 | 66 | /// 67 | /// システム終了。 68 | /// 69 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 70 | internal void EndSystem() 71 | { 72 | //フタイミングによっては相手アプリケーションが存在しないことは十分にありうる 73 | try 74 | { 75 | CopyDataProtocolTalker.SendAndRecieve(SystemControlWindowInAppHandle, 76 | new SystemControlInfo(SystemControlType.EndSystem, null)); 77 | } 78 | catch { } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Project/UnitTest/TestCore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Reflection; 6 | using Codeer.Friendly.Dynamic; 7 | using Codeer.Friendly.Windows; 8 | using Microsoft.VisualStudio.TestTools.UnitTesting; 9 | 10 | namespace UnitTest 11 | { 12 | [TestClass] 13 | public class TestCore 14 | { 15 | WindowsAppFriend _app; 16 | 17 | [TestInitialize] 18 | public void TestInitialize() 19 | { 20 | var targetExePath = Path.GetFullPath(GetType().Assembly.Location + @"..\..\..\..\..\TestTargetCore\bin\Debug\netcoreapp3.0\TestTargetCore.exe"); 21 | if (IntPtr.Size == 4) 22 | { 23 | //not tested. 24 | targetExePath = Path.GetFullPath(GetType().Assembly.Location + @"..\..\..\..\..\TestTargetCore\bin\Debug\netcoreapp3.0\TestTargetCore.exe"); 25 | } 26 | 27 | var targetApp = Process.Start(targetExePath); 28 | _app = new WindowsAppFriend(targetApp); 29 | } 30 | 31 | [TestCleanup] 32 | public void TestCleanup() => Process.GetProcessById(_app.ProcessId).Kill(); 33 | 34 | [TestMethod] 35 | public void Execute() 36 | { 37 | var w = _app.Type("System.Windows.Application").Current.MainWindow; 38 | w.Title = "yyy"; 39 | } 40 | 41 | [TestMethod] 42 | public void LoadAssembly() 43 | { 44 | _app.LoadAssembly(GetType().Assembly); 45 | Data value = _app.Type(GetType()).GetIntValue(new Data { Value = 200 }); 46 | Assert.AreEqual(201, value.Value); 47 | } 48 | 49 | public class X { } 50 | public class Y { } 51 | 52 | [TestMethod] 53 | public void TestFinder() 54 | { 55 | var typeFinder = new Codeer.Friendly.DotNetExecutor.TypeFinder(); 56 | var typeFinderCoreType = typeFinder.GetType("Codeer.Friendly.DotNetExecutor.TypeFinder+TypeFinderCore"); 57 | var typeFinderCore = Activator.CreateInstance(typeFinderCoreType); 58 | 59 | Type stringType = typeFinder.GetType("Codeer.Friendly.DotNetExecutor.TypeFinder+StringType"); 60 | MethodInfo methodInfoMakeType = stringType.GetMethod("MakeType", BindingFlags.Instance | BindingFlags.NonPublic); 61 | MethodInfo methodInfoParse = stringType.GetMethod("Parse", BindingFlags.Static | BindingFlags.NonPublic); 62 | 63 | var testTargetType = new[] 64 | { 65 | typeof(int) 66 | , typeof(List) 67 | , typeof(Dictionary) 68 | , typeof(Dictionary>, Dictionary>>) 69 | // 最後の1つは全てキャッシュから変換されるか確認用 70 | , typeof(Dictionary>, Dictionary>>) 71 | }; 72 | 73 | foreach(var type in testTargetType) 74 | { 75 | var typeTmp = methodInfoParse.Invoke(null, new[] { type.FullName }); 76 | var result = methodInfoMakeType.Invoke(typeTmp, new[] { typeFinderCore }); 77 | var fullName = result.GetType().GetProperty("FullName").GetValue(result, null) as string; 78 | Assert.IsTrue(type.FullName == fullName); 79 | } 80 | } 81 | 82 | static Data GetIntValue(Data src) => new Data { Value = src.Value + 1 }; 83 | } 84 | 85 | [Serializable] 86 | public class Data 87 | { 88 | public int Value { get; set; } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows.Step/AppDomainControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Codeer.Friendly.Windows.Step 5 | { 6 | public class AppDomainControl 7 | { 8 | [DllImport("Kernel32", CharSet = CharSet.Unicode, SetLastError = true)] 9 | static extern IntPtr LoadLibrary(string fileName); 10 | 11 | [DllImport("Kernel32", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = false)] 12 | static extern IntPtr GetProcAddress(IntPtr hMod, string funcName); 13 | 14 | delegate int EnumDomainsDelegate( 15 | [MarshalAs(UnmanagedType.LPWStr)]string szVersion, 16 | [MarshalAs(UnmanagedType.LPWStr)]string szStepAssembly, 17 | [MarshalAs(UnmanagedType.LPWStr)]string szGetIDClass, 18 | [MarshalAs(UnmanagedType.LPWStr)]string szGetIDMethod, 19 | [In, Out]int[] ids, 20 | int size); 21 | 22 | [return: MarshalAs(UnmanagedType.Bool)] 23 | delegate bool InitializeAppDomainDelegate( 24 | [MarshalAs(UnmanagedType.LPWStr)]string szVersion, 25 | [MarshalAs(UnmanagedType.LPWStr)]string szStepAssembly, 26 | [MarshalAs(UnmanagedType.LPWStr)]string szGetIDClass, 27 | [MarshalAs(UnmanagedType.LPWStr)]string szGetIDMethod, 28 | [MarshalAs(UnmanagedType.LPWStr)]string szStartClass, 29 | [MarshalAs(UnmanagedType.LPWStr)]string szStartMethod, 30 | int id, 31 | [MarshalAs(UnmanagedType.LPWStr)]string pStartInfo); 32 | 33 | EnumDomainsDelegate _enumDomains; 34 | InitializeAppDomainDelegate _initializeAppDomain; 35 | 36 | public AppDomainControl(string nativeDllPath) 37 | { 38 | IntPtr hDll = LoadLibrary(nativeDllPath); 39 | 40 | IntPtr func = GetProcAddress(hDll, "EnumDomains"); 41 | _enumDomains = (EnumDomainsDelegate)Marshal.GetDelegateForFunctionPointer(func, typeof(EnumDomainsDelegate)); 42 | 43 | func = GetProcAddress(hDll, "InitializeAppDomain"); 44 | _initializeAppDomain = (InitializeAppDomainDelegate)Marshal.GetDelegateForFunctionPointer(func, typeof(InitializeAppDomainDelegate)); 45 | } 46 | 47 | public int[] EnumDomains() 48 | { 49 | int[] getIds = new int[1024]; 50 | int count = 0; 51 | 52 | while (true) 53 | { 54 | count = _enumDomains(RuntimeEnvironment.GetSystemVersion(), 55 | GetType().Assembly.Location, 56 | typeof(AppDomainBridge).FullName, 57 | "GetCurrentDomainId", 58 | getIds, 59 | getIds.Length); 60 | if (count == -1) 61 | { 62 | return null; 63 | } 64 | if (count < getIds.Length) 65 | { 66 | break; 67 | } 68 | getIds = new int[count]; 69 | } 70 | 71 | int[] ids = new int[count]; 72 | for (int i = 0; i < ids.Length; i++) 73 | { 74 | ids[i] = getIds[i]; 75 | } 76 | return ids; 77 | } 78 | 79 | public bool InitializeAppDomain(int id, string args) 80 | { 81 | return _initializeAppDomain( 82 | RuntimeEnvironment.GetSystemVersion(), 83 | GetType().Assembly.Location, 84 | typeof(AppDomainBridge).FullName, 85 | "GetCurrentDomainId", 86 | typeof(StartStepWrap).FullName, 87 | "Start", 88 | id, 89 | args 90 | ); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_2_32/MultiDomain_2_32.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67} 8 | WinExe 9 | Properties 10 | MultiDomain_2_32 11 | MultiDomain_2_32 12 | v2.0 13 | 512 14 | 15 | 16 | x86 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | x86 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Form 45 | 46 | 47 | MainForm.cs 48 | 49 | 50 | 51 | 52 | MainForm.cs 53 | 54 | 55 | ResXFileCodeGenerator 56 | Resources.Designer.cs 57 | Designer 58 | 59 | 60 | True 61 | Resources.resx 62 | 63 | 64 | SettingsSingleFileGenerator 65 | Settings.Designer.cs 66 | 67 | 68 | True 69 | Settings.settings 70 | True 71 | 72 | 73 | 74 | 81 | -------------------------------------------------------------------------------- /Project/TestTargetCore/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Data; 11 | using System.Windows.Documents; 12 | using System.Windows.Input; 13 | using System.Windows.Media; 14 | using System.Windows.Media.Imaging; 15 | using System.Windows.Navigation; 16 | using System.Windows.Shapes; 17 | 18 | namespace TestTargetCore 19 | { 20 | /// 21 | /// Interaction logic for MainWindow.xaml 22 | /// 23 | public partial class MainWindow : Window 24 | { 25 | public MainWindow() 26 | { 27 | InitializeComponent(); 28 | var handle = Kernel32.OpenProcess(Kernel32.ProcessSecurity.ProcessVmRead | Kernel32.ProcessSecurity.ProcessQueryInformation, false, (uint)Process.GetCurrentProcess().Id); 29 | 30 | var w = new Stopwatch(); 31 | w.Start(); 32 | var dlls = string.Join("\r\n", GetModuleFileNames(handle)); 33 | w.Stop(); 34 | var x = w.ElapsedMilliseconds; 35 | _text.Text = string.Join("\r\n", GetModuleFileNames(handle)); 36 | } 37 | 38 | static string[] GetModuleFileNames(IntPtr hProcess) 39 | { 40 | var modules = new IntPtr[2048]; 41 | Psapi.EnumProcessModulesEx(hProcess, modules, IntPtr.Size * 2048, out var cbNeeded, Psapi.ListModules.ListModulesAll); 42 | var moduleNames = new List(); 43 | for (var i = 0; i < cbNeeded / IntPtr.Size; ++i) 44 | { 45 | var sb = new StringBuilder(256); 46 | Psapi.GetModuleFileNameEx(hProcess, modules[i], sb, 256); 47 | moduleNames.Add(sb.ToString()); 48 | } 49 | 50 | return moduleNames.ToArray(); 51 | } 52 | 53 | static bool HasCoreClr(string[] modules) 54 | { 55 | return modules.Any(x => x.ToLower().Contains("coreclr.dll")); 56 | } 57 | } 58 | 59 | 60 | 61 | 62 | static class Kernel32 63 | { 64 | [DllImport("kernel32.dll")] 65 | public static extern IntPtr OpenProcess([MarshalAs(UnmanagedType.I4)] ProcessSecurity dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, 66 | uint dwProcessId); 67 | 68 | [DllImport("kernel32.dll")] 69 | [return: MarshalAs(UnmanagedType.Bool)] 70 | public static extern bool CloseHandle(IntPtr hObject); 71 | 72 | [Flags] 73 | public enum ProcessSecurity : uint 74 | { 75 | ProcessVmRead = 0x0010, 76 | ProcessQueryInformation = 0x0400, 77 | } 78 | } 79 | 80 | static class Psapi 81 | { 82 | [DllImport("psapi.dll")] 83 | [return: MarshalAs(UnmanagedType.Bool)] 84 | public static extern bool EnumProcesses(uint[] lpidProcesses, uint cb, out uint lpcbNeeded); 85 | 86 | [DllImport("psapi.dll")] 87 | public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, StringBuilder lpFilename, 88 | uint nSize); 89 | 90 | [DllImport("psapi.dll")] 91 | [return: MarshalAs(UnmanagedType.Bool)] 92 | public static extern bool EnumProcessModulesEx(IntPtr hProcess, IntPtr[] lphModule, int cb, 93 | out uint lpcbNeeded, [MarshalAs(UnmanagedType.I4)] ListModules dwFilterFlag); 94 | 95 | public enum ListModules : int 96 | { 97 | ListModules32Bit = 0x01, 98 | ListModules64Bit = 0x02, 99 | ListModulesAll = 0x03, 100 | ListModulesDefault = 0x0, 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_32/MultiDomain_4_32.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB} 8 | WinExe 9 | Properties 10 | MultiDomain_4_32 11 | MultiDomain_4_32 12 | v4.0 13 | 512 14 | 15 | 16 | x86 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | x86 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Form 49 | 50 | 51 | MainForm.cs 52 | 53 | 54 | 55 | 56 | MainForm.cs 57 | 58 | 59 | ResXFileCodeGenerator 60 | Resources.Designer.cs 61 | Designer 62 | 63 | 64 | True 65 | Resources.resx 66 | 67 | 68 | SettingsSingleFileGenerator 69 | Settings.Designer.cs 70 | 71 | 72 | True 73 | Settings.settings 74 | True 75 | 76 | 77 | 78 | 85 | -------------------------------------------------------------------------------- /Project/Test/MultiDomain_4_64/MultiDomain_4_64.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01} 8 | WinExe 9 | Properties 10 | MultiDomain_4_64 11 | MultiDomain_4_64 12 | v4.0 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Form 49 | 50 | 51 | MainForm.cs 52 | 53 | 54 | 55 | 56 | MainForm.cs 57 | 58 | 59 | ResXFileCodeGenerator 60 | Resources.Designer.cs 61 | Designer 62 | 63 | 64 | True 65 | Resources.resx 66 | 67 | 68 | SettingsSingleFileGenerator 69 | Settings.Designer.cs 70 | 71 | 72 | True 73 | Settings.settings 74 | True 75 | 76 | 77 | 78 | 85 | -------------------------------------------------------------------------------- /Project/Test/WPFApp/WPFApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {A64CB1F4-6645-465D-8B51-E781079BE6C0} 8 | WinExe 9 | WPFApp 10 | WPFApp 11 | v4.0 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | 17 | 18 | 19 | x86 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | x86 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 4.0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | MSBuild:Compile 55 | Designer 56 | 57 | 58 | MSBuild:Compile 59 | Designer 60 | 61 | 62 | App.xaml 63 | Code 64 | 65 | 66 | MainWindow.xaml 67 | Code 68 | 69 | 70 | 71 | 72 | Code 73 | 74 | 75 | True 76 | True 77 | Resources.resx 78 | 79 | 80 | True 81 | Settings.settings 82 | True 83 | 84 | 85 | ResXFileCodeGenerator 86 | Resources.Designer.cs 87 | 88 | 89 | SettingsSingleFileGenerator 90 | Settings.Designer.cs 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Project/TestTargetx86/TestTargetx86.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92} 8 | WinExe 9 | TestTargetx86 10 | TestTargetx86 11 | v4.7.2 12 | 512 13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | 4 15 | true 16 | true 17 | 18 | 19 | AnyCPU 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | AnyCPU 30 | pdbonly 31 | true 32 | bin\Release\ 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 4.0 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | MSBuild:Compile 56 | Designer 57 | 58 | 59 | MSBuild:Compile 60 | Designer 61 | 62 | 63 | App.xaml 64 | Code 65 | 66 | 67 | MainWindow.xaml 68 | Code 69 | 70 | 71 | 72 | 73 | Code 74 | 75 | 76 | True 77 | True 78 | Resources.resx 79 | 80 | 81 | True 82 | Settings.settings 83 | True 84 | 85 | 86 | ResXFileCodeGenerator 87 | Resources.Designer.cs 88 | 89 | 90 | SettingsSingleFileGenerator 91 | Settings.Designer.cs 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/FriendlyConnectorWindowInApp.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using Codeer.Friendly; 4 | using Codeer.Friendly.Inside.Protocol; 5 | using Codeer.Friendly.DotNetExecutor; 6 | using Codeer.Friendly.Windows.Inside.CopyDataProtocol; 7 | using System.Windows.Forms; 8 | using System.Diagnostics.CodeAnalysis; 9 | 10 | namespace Codeer.Friendly.Windows.Inside 11 | { 12 | /// 13 | /// アプリケーション側フレンドリー操作ウィンドウ。 14 | /// 15 | class FriendlyConnectorWindowInApp : ReceiveForm, IAsyncInvoke 16 | { 17 | FriendlyConnectorWindowInAppManager _manager; 18 | DotNetFriendlyControl _dotNetFriendlyControl; 19 | int _invokeCount; 20 | bool _isCloseMode; 21 | 22 | /// 23 | /// BinOff高速通信用。 24 | /// 25 | internal const int WM_BINOFF = 0x8000; 26 | 27 | /// 28 | /// BinOff成功戻り値。 29 | /// 30 | static readonly IntPtr SuccessBinOff = new IntPtr(1); 31 | 32 | /// 33 | /// コンストラクタ。 34 | /// 35 | /// ウィンドウ管理 36 | /// .Net側処理呼び出しクラス。 37 | internal FriendlyConnectorWindowInApp(FriendlyConnectorWindowInAppManager manager, DotNetFriendlyControl dotNetFriendlyControl) 38 | { 39 | _manager = manager; 40 | _dotNetFriendlyControl = dotNetFriendlyControl; 41 | } 42 | 43 | /// 44 | /// 終了要求。 45 | /// 46 | internal void RequestDispose() 47 | { 48 | _isCloseMode = true; 49 | if (_invokeCount == 0) 50 | { 51 | DisposeCore(); 52 | } 53 | } 54 | 55 | /// 56 | /// 非同期実行。 57 | /// 58 | /// 非同期メソッド。 59 | public void Execute(AsyncMethod method) 60 | { 61 | _invokeCount++; 62 | this.BeginInvoke((MethodInvoker)delegate 63 | { 64 | method(); 65 | _invokeCount--; 66 | if (_isCloseMode && _invokeCount == 0) 67 | { 68 | DisposeCore(); 69 | } 70 | }); 71 | } 72 | 73 | /// 74 | /// データ受信時の処理。 75 | /// 76 | /// 通信番号。 77 | /// 受信データ。 78 | /// 送信元ウィンドウ。 79 | protected override void OnRecieveData(int communicationNo, object recieveData, IntPtr senderWindow) 80 | { 81 | ContextOrderProtocolInfo contextOrder = recieveData as ContextOrderProtocolInfo; 82 | if (contextOrder != null) 83 | { 84 | FriendlyConnectorWindowInApp async = _manager.FromHandle(contextOrder.ExecuteWindowHandle); 85 | SendReturnData(communicationNo, senderWindow, _dotNetFriendlyControl.Execute(async, contextOrder.ProtocolInfo)); 86 | } 87 | else 88 | { 89 | ProtocolInfo protocolInfo = recieveData as ProtocolInfo; 90 | SendReturnData(communicationNo, senderWindow, _dotNetFriendlyControl.Execute(this, protocolInfo)); 91 | } 92 | } 93 | 94 | /// 95 | /// メッセージ処理。 96 | /// 97 | /// メッセージ。 98 | protected override void WndProc(ref Message message) 99 | { 100 | //BinOff高速処理用 101 | if (message.Msg == WM_BINOFF) 102 | { 103 | _dotNetFriendlyControl.Execute(this, new ProtocolInfo(ProtocolType.BinOff, null, new VarAddress(message.WParam.ToInt32()), string.Empty, string.Empty, new string[0])); 104 | message.Result = SuccessBinOff; 105 | return; 106 | } 107 | base.WndProc(ref message); 108 | } 109 | 110 | /// 111 | /// 破棄 112 | /// 113 | private void DisposeCore() 114 | { 115 | Dispose(); 116 | _manager = null; 117 | _dotNetFriendlyControl = null; 118 | GC.Collect(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Codeer.Friendly.Windows.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.11.35222.181 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codeer.Friendly.Windows", "Codeer.Friendly.Windows.csproj", "{56A947B0-1DF8-4116-8152-AB2D4B6042C3}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest", "..\UnitTest\UnitTest.csproj", "{C50464C7-343A-4945-9B44-0C0E6A4C628D}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Attachx86", "..\Attachx86\Attachx86.csproj", "{76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestTargetx86", "..\TestTargetx86\TestTargetx86.csproj", "{8E93CC5B-87D1-453F-96F6-57680DAB7A92}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nuget", "Nuget", "{07819EDF-DAB6-47E6-8976-1F399873ED07}" 15 | ProjectSection(SolutionItems) = preProject 16 | ..\Nuget\Friendly.Windows.nuspec = ..\Nuget\Friendly.Windows.nuspec 17 | EndProjectSection 18 | EndProject 19 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTestCore", "..\UnitTestCore\UnitTestCore.csproj", "{5A5E304F-479D-4E3F-82E3-04550290A043}" 20 | EndProject 21 | Global 22 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 23 | Debug|Any CPU = Debug|Any CPU 24 | Release|Any CPU = Release|Any CPU 25 | Release-Eng|Any CPU = Release-Eng|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release-Eng|Any CPU.ActiveCfg = Release-Eng|Any CPU 33 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release-Eng|Any CPU.Build.0 = Release-Eng|Any CPU 34 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 39 | {C50464C7-343A-4945-9B44-0C0E6A4C628D}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 40 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 45 | {76D53D43-1EC3-4D66-AAAE-0C62B9EEE748}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 46 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 51 | {8E93CC5B-87D1-453F-96F6-57680DAB7A92}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 52 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 57 | {5A5E304F-479D-4E3F-82E3-04550290A043}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 58 | EndGlobalSection 59 | GlobalSection(SolutionProperties) = preSolution 60 | HideSolutionNode = FALSE 61 | EndGlobalSection 62 | GlobalSection(ExtensibilityGlobals) = postSolution 63 | SolutionGuid = {70C68E25-295C-49E0-81CC-9708472FB5CA} 64 | EndGlobalSection 65 | EndGlobal 66 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CopyDataProtocol/ReceiveForm.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.Windows.Forms; 4 | using System.Runtime.InteropServices; 5 | using System.Diagnostics.CodeAnalysis; 6 | using System.Threading; 7 | 8 | namespace Codeer.Friendly.Windows.Inside.CopyDataProtocol 9 | { 10 | /// 11 | /// データ受信ウィンドウ共通処理。 12 | /// 13 | internal abstract class ReceiveForm : CommunicationWindow 14 | { 15 | /// 16 | /// WM_COPYDATA送信成功。 17 | /// 18 | internal static readonly IntPtr SendCopyDataSuccess = new IntPtr(1); 19 | 20 | int _managedThreadId = Thread.CurrentThread.ManagedThreadId; 21 | 22 | /// 23 | /// 使用可能なスレッドであるか 24 | /// 25 | internal bool CanUseThread { get { return _managedThreadId == Thread.CurrentThread.ManagedThreadId; } } 26 | 27 | /// 28 | /// コンストラクタ。 29 | /// 30 | protected ReceiveForm() 31 | { 32 | CreateHandle(); 33 | } 34 | 35 | /// 36 | /// メッセージ処理。 37 | /// 38 | /// メッセージ。 39 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 40 | protected override void WndProc(ref Message message) 41 | { 42 | CopyDataProtocolInfo data; 43 | if (message.HWnd == Handle && ProcessCopyData(ref message, out data)) 44 | { 45 | if (data != null) 46 | { 47 | //対象スレッドで実施されるので、仮に予期せぬ例外が発生しても、無視する。 48 | try 49 | { 50 | OnRecieveData(message.WParam.ToInt32(), data.Data, data.ReturnWindowHandle); 51 | } 52 | catch { } 53 | } 54 | } 55 | else 56 | { 57 | base.WndProc(ref message); 58 | } 59 | } 60 | 61 | /// 62 | /// WM_COPYDATAの処理。 63 | /// 64 | /// メッセージ。 65 | /// 受信データ。 66 | /// true→処理した。 67 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 68 | private static bool ProcessCopyData(ref Message message, out CopyDataProtocolInfo data) 69 | { 70 | data = null; 71 | if (message.Msg == NativeMethods.WM_COPYDATA) 72 | { 73 | //デシリアライズ 74 | //これが失敗するということは通信の状態が正常ではないので、詳細は返さず、ただ、通信に失敗したことだけ通知する 75 | try 76 | { 77 | NativeMethods.COPYDATASTRUCT globalData = (NativeMethods.COPYDATASTRUCT)message.GetLParam(typeof(NativeMethods.COPYDATASTRUCT)); 78 | byte[] bin = new byte[(int)globalData.cbData]; 79 | Marshal.Copy(globalData.lpData, bin, 0, bin.Length); 80 | data = CopyDataProtocolInfo.Deserialize(bin); 81 | message.Result = SendCopyDataSuccess; 82 | } 83 | catch 84 | { 85 | message.Result = IntPtr.Zero; 86 | } 87 | return true; 88 | } 89 | return false; 90 | } 91 | 92 | /// 93 | /// 応答送信。 94 | /// 95 | /// 通信番号。 96 | /// 応答受信ウィンドウ。 97 | /// 送信データ。 98 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 99 | protected static void SendReturnData(int communicationNo, IntPtr receiveWindowHandle, object data) 100 | { 101 | IntPtr globalData = IntPtr.Zero; 102 | try 103 | { 104 | CopyDataProtocolInfo communicatonData = new CopyDataProtocolInfo(IntPtr.Zero, data); 105 | byte[] bin = communicatonData.Serialize(); 106 | NativeMethods.COPYDATASTRUCT copyData = new NativeMethods.COPYDATASTRUCT(); 107 | copyData.dwData = IntPtr.Zero; 108 | copyData.cbData = (uint)bin.Length; 109 | copyData.lpData = globalData = Marshal.AllocHGlobal(bin.Length); 110 | Marshal.Copy(bin, 0, copyData.lpData, bin.Length); 111 | NativeMethods.SendMessage(receiveWindowHandle, NativeMethods.WM_COPYDATA, new IntPtr(communicationNo), ref copyData); 112 | } 113 | catch 114 | { 115 | //対象アプリケーションプロセスでの実行なので例外は投げない。 116 | } 117 | finally 118 | { 119 | if (globalData != IntPtr.Zero) 120 | { 121 | Marshal.FreeHGlobal(globalData); 122 | } 123 | } 124 | } 125 | 126 | /// 127 | /// データ受信時の処理。 128 | /// 129 | /// 通信番号。 130 | /// 受信データ。 131 | /// 送信元ウィンドウ。 132 | protected abstract void OnRecieveData(int communicationNo, object recieveData, IntPtr senderWindow); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Project/Test/Test/Test.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Codeer.Friendly.Windows", "..\..\Codeer.Friendly.Windows\Codeer.Friendly.Windows.csproj", "{56A947B0-1DF8-4116-8152-AB2D4B6042C3}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiDomain_4_32", "..\MultiDomain_4_32\MultiDomain_4_32.csproj", "{00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiDomain_4_64", "..\MultiDomain_4_64\MultiDomain_4_64.csproj", "{DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultiDomain_2_32", "..\MultiDomain_2_32\MultiDomain_2_32.csproj", "{B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test.csproj", "{690F7F4A-D337-475B-9B99-543B05B35520}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFApp", "..\WPFApp\WPFApp.csproj", "{A64CB1F4-6645-465D-8B51-E781079BE6C0}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | Release-Eng|Any CPU = Release-Eng|Any CPU 23 | EndGlobalSection 24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 25 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release-Eng|Any CPU.ActiveCfg = Release-Eng|Any CPU 30 | {56A947B0-1DF8-4116-8152-AB2D4B6042C3}.Release-Eng|Any CPU.Build.0 = Release-Eng|Any CPU 31 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 32 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Debug|Any CPU.Build.0 = Debug|Any CPU 33 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Release|Any CPU.ActiveCfg = Release|Any CPU 34 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Release|Any CPU.Build.0 = Release|Any CPU 35 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 36 | {00F73E5A-48EF-4E48-9703-2DBF0C7F64BB}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 37 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 42 | {DC8E03E7-DCD1-45E8-8D3A-48919F6D5E01}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 43 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 44 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Debug|Any CPU.Build.0 = Debug|Any CPU 45 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Release|Any CPU.ActiveCfg = Release|Any CPU 46 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Release|Any CPU.Build.0 = Release|Any CPU 47 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 48 | {B7A4499C-CFCA-4083-9DFA-0E8E07A6ED67}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 49 | {690F7F4A-D337-475B-9B99-543B05B35520}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 50 | {690F7F4A-D337-475B-9B99-543B05B35520}.Debug|Any CPU.Build.0 = Debug|Any CPU 51 | {690F7F4A-D337-475B-9B99-543B05B35520}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {690F7F4A-D337-475B-9B99-543B05B35520}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {690F7F4A-D337-475B-9B99-543B05B35520}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 54 | {690F7F4A-D337-475B-9B99-543B05B35520}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 55 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 56 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU 57 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU 58 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Release|Any CPU.Build.0 = Release|Any CPU 59 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Release-Eng|Any CPU.ActiveCfg = Release|Any CPU 60 | {A64CB1F4-6645-465D-8B51-E781079BE6C0}.Release-Eng|Any CPU.Build.0 = Release|Any CPU 61 | EndGlobalSection 62 | GlobalSection(SolutionProperties) = preSolution 63 | HideSolutionNode = FALSE 64 | EndGlobalSection 65 | GlobalSection(ExtensibilityGlobals) = postSolution 66 | SolutionGuid = {2A11F9F3-99B1-461E-870E-DE49E08355E1} 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /Project/CodeerFriendlyWindowsCore/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "mscoree.h" 8 | 9 | namespace { 10 | static WNDPROC s_srcProc = NULL; 11 | static void* s_pStartInfo = NULL; 12 | static bool s_bExecutiong = FALSE; 13 | CRITICAL_SECTION s_csConnection; 14 | 15 | const int ERR_UNPREDICATABLE_CLR_VERSION = 1; 16 | const int WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE = 0x8100; 17 | 18 | void SplitArguments(const std::wstring& s, wchar_t delim, std::vector& elems) { 19 | std::wstringstream ss(s); 20 | std::wstring item; 21 | while (std::getline(ss, item, delim)) { 22 | elems.push_back(item); 23 | } 24 | } 25 | 26 | //マネージドメソッド呼び出し。 27 | BOOL ExecuteInDefaultAppDomain( 28 | LPCWSTR szCoreclrPath, 29 | LPCWSTR szAssembly, 30 | LPCWSTR szTypeFullName, 31 | LPCWSTR szMethod, 32 | LPCWSTR szArgs, 33 | int& errNo) 34 | { 35 | HMODULE coreClr = LoadLibraryExW(szCoreclrPath, nullptr, 0); 36 | if (coreClr == nullptr) { 37 | return FALSE; 38 | } 39 | 40 | FnGetCLRRuntimeHost pfnGetCLRRuntimeHost = (FnGetCLRRuntimeHost)::GetProcAddress(coreClr, "GetCLRRuntimeHost"); 41 | if (pfnGetCLRRuntimeHost == nullptr) { 42 | return FALSE; 43 | } 44 | 45 | ICLRRuntimeHost4* runtimeHost; 46 | HRESULT hr = pfnGetCLRRuntimeHost(IID_ICLRRuntimeHost4, (IUnknown * *)& runtimeHost); 47 | if (FAILED(hr)) { 48 | return FALSE; 49 | } 50 | 51 | hr = runtimeHost->Start(); 52 | if (FAILED(hr)) { 53 | return FALSE; 54 | } 55 | 56 | DWORD dwResult; 57 | hr = runtimeHost->ExecuteInDefaultAppDomain( 58 | szAssembly, 59 | szTypeFullName, 60 | szMethod, 61 | szArgs, 62 | &dwResult); 63 | return !FAILED(hr); 64 | } 65 | 66 | 67 | /** 68 | @brief 初期化 69 | @param pStartInfo 開始情報 70 | @return 結果 71 | */ 72 | void InitializeFriendlyCore(void* pStartInfo) 73 | { 74 | //引数パース 75 | std::vector vec; 76 | SplitArguments((LPCWSTR)pStartInfo, '\t', vec); 77 | if (vec.size() != 7) { 78 | return; 79 | } 80 | 81 | //処理実行 82 | int errNo = 0; 83 | if (!ExecuteInDefaultAppDomain(vec[2].c_str(), vec[3].c_str(), vec[4].c_str(), vec[5].c_str(), vec[6].c_str(), errNo)) { 84 | //失敗通知 85 | wchar_t* p = NULL; 86 | HWND hReturn = (HWND)std::wcstoull(vec[1].c_str(), &p, 10); 87 | ::SendMessage(hReturn, WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE, 0, errNo); 88 | } 89 | } 90 | 91 | //SetWindowLongの最適呼び出し 92 | LONG_PTR SetWindowLongPtrEx(HWND hwnd, int index, LONG_PTR ptr) 93 | { 94 | return (::IsWindowUnicode(hwnd)) ? SetWindowLongPtrW(hwnd, index, ptr) : SetWindowLongPtrA(hwnd, index, ptr); 95 | } 96 | 97 | //CallWindowProcの最適呼び出し 98 | LRESULT CallWindowProcEx(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 99 | { 100 | return (::IsWindowUnicode(hWnd)) ? CallWindowProcW(lpPrevWndFunc, hWnd, Msg, wParam, lParam) : CallWindowProcA(lpPrevWndFunc, hWnd, Msg, wParam, lParam); 101 | } 102 | 103 | LRESULT CALLBACK ExecuteConnectionProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 104 | { 105 | if (s_bExecutiong && msg == WM_NULL && wParam == 0 && lParam == 0) { 106 | InitializeFriendlyCore(s_pStartInfo); 107 | s_bExecutiong = FALSE; 108 | } 109 | return CallWindowProcEx(s_srcProc, hWnd, msg, wParam, lParam); 110 | } 111 | } 112 | 113 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 114 | { 115 | switch (ul_reason_for_call) 116 | { 117 | case DLL_PROCESS_ATTACH: 118 | ::InitializeCriticalSection(&s_csConnection); 119 | case DLL_THREAD_ATTACH: 120 | case DLL_THREAD_DETACH: 121 | case DLL_PROCESS_DETACH: 122 | break; 123 | } 124 | return TRUE; 125 | } 126 | 127 | /** 128 | @brief 初期化 129 | @param pStartInfo 開始情報 130 | @return 結果 131 | */ 132 | DWORD __stdcall InitializeFriendly(void* pStartInfo) 133 | { 134 | struct Scop { 135 | Scop() { ::EnterCriticalSection(&s_csConnection); } 136 | ~Scop() { ::LeaveCriticalSection(&s_csConnection); } 137 | }scope; 138 | 139 | //引数パース 140 | std::vector vec; 141 | SplitArguments((LPCWSTR)pStartInfo, '\t', vec); 142 | if (vec.size() != 7) { 143 | return 0; 144 | } 145 | 146 | //対象ウィンドウのスレッドに処理を実行させる 147 | wchar_t* p = NULL; 148 | HWND hTargetWindow = (HWND)std::wcstoull(vec[0].c_str(), &p, 10); 149 | s_pStartInfo = pStartInfo; 150 | s_bExecutiong = TRUE; 151 | s_srcProc = (WNDPROC)SetWindowLongPtrEx(hTargetWindow, GWLP_WNDPROC, (LONG_PTR)ExecuteConnectionProc); 152 | while (s_bExecutiong && IsWindow(hTargetWindow)) { 153 | ::SendMessage(hTargetWindow, WM_NULL, 0, 0); 154 | Sleep(1); 155 | } 156 | 157 | SetWindowLongPtrEx(hTargetWindow, GWLP_WNDPROC, (LONG_PTR)s_srcProc); 158 | if (s_bExecutiong) { 159 | wchar_t* p = NULL; 160 | HWND hReturn = (HWND)std::wcstoull(vec[1].c_str(), &p, 10); 161 | ::SendMessage(hReturn, WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE, 0, 0); 162 | } 163 | return 0; 164 | } -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/CommunicationWindowManager.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.InteropServices; 5 | using System.Windows.Forms; 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | namespace Codeer.Friendly.Windows.Inside 9 | { 10 | /// 11 | /// 通信ウィンドウ管理 12 | /// 13 | abstract class CommunicationWindowManager 14 | { 15 | const string WindowClassNameBase = "Codeer.Friendly.Windows.Inside.CommunicationWindow_"; 16 | [SuppressMessage("Microsoft.Performance", "CA1802:UseLiteralsWhereAppropriate")] 17 | internal static readonly string WindowClassName; 18 | static readonly NativeMethods.WndProc MyWindowProc; 19 | static Dictionary _handleAndWindow = new Dictionary(); 20 | 21 | /// 22 | /// staticコンストラクタ 23 | /// 24 | [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")] 25 | static CommunicationWindowManager() 26 | { 27 | string windowClassName = string.Empty; 28 | for (int i = 0; true; i++) 29 | { 30 | windowClassName = WindowClassNameBase + i; 31 | 32 | //ウィンドウプロックをGCの対象から外すためにstaticメンバにする 33 | MyWindowProc = new NativeMethods.WndProc(WndProc); 34 | 35 | //ウィンドウクラス登録 36 | NativeMethods.WNDCLASSEX wc = new NativeMethods.WNDCLASSEX(); 37 | wc.cbSize = (uint)Marshal.SizeOf(wc); 38 | wc.style = 0; 39 | wc.lpfnWndProc = Marshal.GetFunctionPointerForDelegate(MyWindowProc); 40 | wc.cbClsExtra = 0; 41 | wc.cbWndExtra = 0; 42 | wc.hInstance = NativeMethods.GetModuleHandle(null); 43 | wc.hIcon = IntPtr.Zero; 44 | wc.hCursor = IntPtr.Zero; 45 | wc.hbrBackground = IntPtr.Zero; 46 | wc.lpszMenuName = string.Empty; 47 | wc.lpszClassName = windowClassName; 48 | wc.hIconSm = IntPtr.Zero; 49 | if (NativeMethods.RegisterClassEx(ref wc) != 0) 50 | { 51 | break; 52 | } 53 | } 54 | WindowClassName = windowClassName; 55 | } 56 | 57 | /// 58 | /// ウィンドウプロック 59 | /// 60 | /// ウィンドウハンドル 61 | /// メッセージ 62 | /// WParam 63 | /// LParam 64 | /// 結果 65 | static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam) 66 | { 67 | CommunicationWindow w; 68 | lock (_handleAndWindow) 69 | { 70 | if (!_handleAndWindow.TryGetValue(hwnd, out w)) 71 | { 72 | return NativeMethods.DefWindowProc(hwnd, msg, wParam, lParam); 73 | } 74 | } 75 | Message m = new Message(); 76 | m.HWnd = hwnd; 77 | m.Msg = msg; 78 | m.WParam = wParam; 79 | m.LParam = lParam; 80 | w.CallWndProc(ref m); 81 | GC.KeepAlive(w); 82 | return m.Result; 83 | } 84 | 85 | /// 86 | /// 生成 87 | /// 88 | /// ウィンドウ 89 | /// 生成結果 90 | internal static IntPtr Create(CommunicationWindow window) 91 | { 92 | //ウィンドウ生成 93 | IntPtr handle = NativeMethods.CreateWindowEx(0, WindowClassName, string.Empty, 0, 0, 0, 1, 1, 94 | NativeMethods.HWND_MESSAGE, IntPtr.Zero, NativeMethods.GetModuleHandle(null), IntPtr.Zero); 95 | 96 | //ウィンドウ登録 97 | lock (_handleAndWindow) 98 | { 99 | _handleAndWindow.Add(handle, window); 100 | } 101 | 102 | //念のため、MyWindowProcが破棄されないように 103 | GC.KeepAlive(MyWindowProc); 104 | return handle; 105 | } 106 | 107 | /// 108 | /// ウィンドウの破棄 109 | /// 110 | /// ハンドル 111 | internal static void DestroyWindow(IntPtr handle) 112 | { 113 | NativeMethods.DestroyWindow(handle); 114 | lock (_handleAndWindow) 115 | { 116 | CommunicationWindow window; 117 | if (_handleAndWindow.TryGetValue(handle, out window)) 118 | { 119 | GC.KeepAlive(_handleAndWindow); 120 | } 121 | _handleAndWindow.Remove(handle); 122 | } 123 | 124 | //念のため、MyWindowProcが破棄されないように 125 | GC.KeepAlive(MyWindowProc); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/ExecuteContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Codeer.Friendly.Windows.Inside; 3 | using Codeer.Friendly.Windows.Inside.CopyDataProtocol; 4 | using Codeer.Friendly.Inside.Protocol; 5 | using System.Windows.Forms; 6 | 7 | namespace Codeer.Friendly.Windows 8 | { 9 | #if ENG 10 | /// 11 | /// Used for changing the executing process thread in the target application. 12 | /// 13 | #else 14 | /// 15 | /// 実行コンテキスト。 16 | /// テスト対象アプリケーションでの処理実行スレッドを変更するのに使用します。 17 | /// 18 | #endif 19 | public class ExecuteContext : IDisposable 20 | { 21 | readonly FriendlyConnectorCore _friendlyConnector; 22 | SystemController _systemController; 23 | 24 | /// 25 | /// 接続者。 26 | /// 27 | internal FriendlyConnectorCore FriendlyConnector { get { return _friendlyConnector; } } 28 | 29 | #if ENG 30 | 31 | /// 32 | /// Constructor. 33 | /// 34 | /// Application manipulation object. 35 | /// Window handle in the thread where test operations will be carried out. 36 | #else 37 | 38 | /// 39 | /// コンストラクタ。 40 | /// 41 | /// アプリケーション操作クラス。 42 | /// 処理を実行させるスレッドで動作するウィンドウのハンドルです。 43 | #endif 44 | public ExecuteContext(WindowsAppFriend app, IntPtr executeThreadWindowHandle) 45 | { 46 | if (app == null) 47 | { 48 | throw new ArgumentNullException("app"); 49 | } 50 | _systemController = app.SystemController; 51 | _friendlyConnector = _systemController.StartFriendlyConnector(executeThreadWindowHandle); 52 | } 53 | 54 | #if ENG 55 | /// 56 | /// Constructor. 57 | /// 58 | /// Application manipulation object. 59 | /// AppVar for a .Net window object in the thread where test operations will be carried out. 60 | #else 61 | /// 62 | /// コンストラクタ。 63 | /// 64 | /// アプリケーション操作クラス。 65 | /// 処理を実行させるスレッドで動作するウィンドウの.Netオブジェクトの入ったアプリケーション内変数です。 66 | #endif 67 | public ExecuteContext(WindowsAppFriend app, AppVar executeThreadWindowControl) 68 | { 69 | if (app == null) 70 | { 71 | throw new ArgumentNullException("app"); 72 | } 73 | _systemController = app.SystemController; 74 | IntPtr handle = (IntPtr)app[typeof(ExecuteContext), "GetHandleThreadSafe"](executeThreadWindowControl).Core; 75 | _friendlyConnector = _systemController.StartFriendlyConnector(handle); 76 | } 77 | 78 | /// 79 | /// コンストラクタ。 80 | /// 81 | /// 接続者。 82 | internal ExecuteContext(FriendlyConnectorCore friendlyConnector) 83 | { 84 | _friendlyConnector = friendlyConnector; 85 | } 86 | 87 | /// 88 | /// ファイナライザ。 89 | /// 90 | ~ExecuteContext() 91 | { 92 | Dispose(false); 93 | } 94 | 95 | #if ENG 96 | /// 97 | /// Disposes this object. 98 | /// This context cannot be used after this method is called. 99 | /// 100 | #else 101 | /// 102 | /// 破棄します。 103 | /// このメソッドが呼び出されると、このコンテキストを使用して処理を実行させることができなくなります。 104 | /// 105 | #endif 106 | public void Dispose() 107 | { 108 | Dispose(true); 109 | GC.SuppressFinalize(this); 110 | } 111 | 112 | #if ENG 113 | /// 114 | /// Dispose. 115 | /// 116 | /// flag. 117 | #else 118 | /// 119 | /// 破棄。 120 | /// 121 | /// 破棄フラグ。 122 | #endif 123 | protected virtual void Dispose(bool disposing) 124 | { 125 | if (_systemController == null) 126 | { 127 | return; 128 | } 129 | _systemController.EndFriendlyConnector(_friendlyConnector.FriendlyConnectorWindowInAppHandle); 130 | _systemController = null; 131 | GC.Collect(); 132 | } 133 | 134 | /// 135 | /// ハンドルの取得 136 | /// App内部から使用される 137 | /// 138 | /// 取得対象コントロール 139 | /// ハンドル 140 | static IntPtr GetHandleThreadSafe(Control control) 141 | { 142 | if (control == null) 143 | { 144 | return IntPtr.Zero; 145 | } 146 | IntPtr ptr = IntPtr.Zero; 147 | control.Invoke((MethodInvoker)delegate 148 | { 149 | ptr = control.Handle; 150 | }); 151 | return ptr; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/VarPool.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Codeer.Friendly.Inside.Protocol; 3 | using Codeer.Friendly.Inside; 4 | using System; 5 | using Codeer.Friendly.Windows.Inside; 6 | 7 | namespace Codeer.Friendly.DotNetExecutor 8 | { 9 | /// 10 | /// .Netの変数管理。 11 | /// このクラスで定義されているメソッドに関してはスレッドセーフで扱うことができる。 12 | /// 13 | class VarPool 14 | { 15 | UniqueNoManager _varAddressManager = new UniqueNoManager(); 16 | Dictionary _handleAndObject = new Dictionary(); 17 | Dictionary _keepAlive = new Dictionary(); 18 | 19 | /// 20 | /// 存命登録。 21 | /// 22 | /// 変数アドレス。 23 | internal void KeepAlive(VarAddress varAddress) 24 | { 25 | lock (this) 26 | { 27 | int count = 0; 28 | if (!_keepAlive.TryGetValue(varAddress.Core, out count)) 29 | { 30 | count = 0; 31 | } 32 | count++; 33 | _keepAlive.Remove(varAddress.Core); 34 | _keepAlive.Add(varAddress.Core, count); 35 | } 36 | } 37 | 38 | /// 39 | /// 存命解除。 40 | /// 41 | /// 変数アドレス。 42 | internal void FreeKeepAlive(VarAddress varAddress) 43 | { 44 | lock (this) 45 | { 46 | int count = 0; 47 | if (!_keepAlive.TryGetValue(varAddress.Core, out count)) 48 | { 49 | return; 50 | } 51 | count--; 52 | if (count <= 0) 53 | { 54 | _keepAlive.Remove(varAddress.Core); 55 | if (!_handleAndObject.ContainsKey(varAddress.Core)) 56 | { 57 | //すでに変数プールから削除されているなら番号解放 58 | _varAddressManager.FreeNo(varAddress.Core); 59 | } 60 | } 61 | else 62 | { 63 | _keepAlive[varAddress.Core] = count; 64 | } 65 | } 66 | } 67 | 68 | /// 69 | /// 追加。 70 | /// 71 | /// オブジェクト。 72 | /// 変数アドレス。 73 | internal VarAddress Add(object obj) 74 | { 75 | lock (this) 76 | { 77 | int no; 78 | if (!_varAddressManager.CreateNo(out no)) 79 | { 80 | throw new InformationException(ResourcesLocal.Instance.OutOfMemory); 81 | } 82 | _handleAndObject.Add(no, new VarAndType(obj)); 83 | return new VarAddress(no); 84 | } 85 | } 86 | 87 | /// 88 | /// 削除。 89 | /// 90 | /// 変数アドレス。 91 | /// 成否。 92 | internal bool Remove(VarAddress varAddress) 93 | { 94 | lock (this) 95 | { 96 | if (!_handleAndObject.ContainsKey(varAddress.Core)) 97 | { 98 | return false; 99 | } 100 | _handleAndObject.Remove(varAddress.Core); 101 | if (!_keepAlive.ContainsKey(varAddress.Core)) 102 | { 103 | //存命中でなければ番号解放 104 | _varAddressManager.FreeNo(varAddress.Core); 105 | } 106 | return true; 107 | } 108 | } 109 | 110 | /// 111 | /// 変数取得。 112 | /// 113 | /// 変数アドレス。 114 | /// 変数。 115 | internal VarAndType GetVarAndType(VarAddress varAddress) 116 | { 117 | lock (this) 118 | { 119 | VarAndType varAndType; 120 | if (_handleAndObject.TryGetValue(varAddress.Core, out varAndType)) 121 | { 122 | return new VarAndType(varAndType.Core, varAndType.Type); 123 | } 124 | throw new InternalException(); 125 | } 126 | } 127 | 128 | /// 129 | /// オブジェクトの設定。 130 | /// 131 | /// 変数アドレス。 132 | /// オブジェクト。 133 | internal void SetObject(VarAddress varAddress, object obj) 134 | { 135 | lock (this) 136 | { 137 | //非同期実行時には、値を設定に来ても、受け取る変数自体が削除されていることがありうる 138 | if (_handleAndObject.ContainsKey(varAddress.Core)) 139 | { 140 | _handleAndObject[varAddress.Core] = new VarAndType(obj); 141 | } 142 | } 143 | } 144 | 145 | /// 146 | /// 指定の変数アドレスが存在しない、またはnullであるか。 147 | /// このメソッドはスレッドセーフである。 148 | /// 149 | /// 変数アドレス。 150 | /// 指定の変数アドレスが存在しない、またはnullであるか。 151 | internal bool IsEmptyVar(VarAddress varAddress) 152 | { 153 | lock (this) 154 | { 155 | VarAndType varAndType; 156 | if (_handleAndObject.TryGetValue(varAddress.Core, out varAndType)) 157 | { 158 | return object.ReferenceEquals(varAndType.Core, null); 159 | } 160 | return true; 161 | } 162 | } 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/DotNetExecutor/TypeFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Codeer.Friendly.DotNetExecutor 6 | { 7 | /// 8 | /// 型に関するユーティリティー。 9 | /// 10 | public class TypeFinder 11 | { 12 | TypeFinderCore _core = new TypeFinderCore(); 13 | 14 | /// 15 | /// 型を取得 16 | /// 17 | /// 型文字列 18 | /// 19 | public Type GetType(string typeFullName) 20 | { 21 | var type = _core.GetType(typeFullName); 22 | if (type != null) return type; 23 | 24 | var stringType = StringType.Parse(typeFullName); 25 | if (stringType == null) return null; 26 | type = stringType.MakeType(_core); 27 | if (type != null) 28 | { 29 | _core.AddCache(typeFullName, type); 30 | } 31 | return type; 32 | } 33 | 34 | /// 35 | /// 型に関するユーティリティー。 36 | /// 37 | class TypeFinderCore 38 | { 39 | Dictionary _fullNameAndType = new Dictionary(); 40 | 41 | /// 42 | /// タイプフルネームから型を取得する。 43 | /// 44 | /// タイプフルネーム。 45 | /// 取得した型。 46 | internal Type GetType(string typeFullName) 47 | { 48 | lock (_fullNameAndType) 49 | { 50 | //キャッシュを見る 51 | Type type = null; 52 | if (_fullNameAndType.TryGetValue(typeFullName, out type)) 53 | { 54 | return type; 55 | } 56 | 57 | //各アセンブリに問い合わせる 58 | Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 59 | List assemblyTypes = new List(); 60 | foreach (Assembly assembly in assemblies) 61 | { 62 | type = assembly.GetType(typeFullName); 63 | if (type != null) 64 | { 65 | break; 66 | } 67 | } 68 | if (type != null) 69 | { 70 | _fullNameAndType.Add(typeFullName, type); 71 | } 72 | return type; 73 | } 74 | } 75 | 76 | /// 77 | /// キャッシュを更新する 78 | /// 79 | /// タイプフルネーム 80 | /// 型 81 | internal void AddCache(string typeFullName, Type type) 82 | { 83 | lock (_fullNameAndType) 84 | { 85 | if (type == null) 86 | { 87 | return; 88 | } 89 | _fullNameAndType[typeFullName] = type; 90 | } 91 | } 92 | } 93 | 94 | /// 95 | /// 解析後の型情報クラス 96 | /// 97 | class StringType 98 | { 99 | /// 100 | /// 変換前の元の型名 101 | /// 102 | internal string FullNameBack { get; set; } 103 | 104 | /// 105 | /// 型名 106 | /// 107 | internal string FullName { get; set; } 108 | 109 | /// 110 | /// 型パラメーター情報 111 | /// 112 | internal List GenericTypes { get; set; } = new List(); 113 | 114 | /// 115 | /// 型を生成 116 | /// 117 | /// 変換処理 118 | /// 119 | internal Type MakeType(TypeFinderCore core) 120 | { 121 | var type = core.GetType(FullName); 122 | if (type == null) return null; 123 | if (GenericTypes.Count <= 0) return type; 124 | var genericTypes = new List(); 125 | foreach (var typeTmp in GenericTypes) 126 | { 127 | genericTypes.Add(typeTmp.MakeType(core)); 128 | } 129 | 130 | try 131 | { 132 | return type.MakeGenericType(genericTypes.ToArray()); 133 | } 134 | catch { } 135 | 136 | return null; 137 | } 138 | 139 | /// 140 | /// 型名の付加情報を削除してから変換する為に解析する 141 | /// 142 | /// 型名 143 | /// 解析後の型情報 144 | internal static StringType Parse(string typeFullName) 145 | { 146 | var genelicCountIndex = typeFullName.IndexOf('`'); 147 | // 普通のタイプ 148 | if (genelicCountIndex == -1) 149 | { 150 | return new StringType { FullNameBack = typeFullName, FullName = typeFullName.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0] }; 151 | } 152 | // ジェネリック 153 | var genericTypeStart = typeFullName.IndexOf('['); 154 | var genericType = new StringType { FullNameBack = typeFullName, FullName = typeFullName.Substring(0, genericTypeStart) }; 155 | var genericCount = int.Parse(typeFullName.Substring(genelicCountIndex + 1, genericTypeStart - genelicCountIndex - 1)); 156 | var scope = 0; 157 | // 下記例の「System.Int32」の開始位置 158 | // System.Collections.Generic.List`1[[System.Int32, System.Private.CoreLib, Version = 5.0.0.0, Culture = neutral, PublicKeyToken = 7cec85d7bea7798e]] 159 | var typeInfoStartIndex = -1; 160 | for (int i = genericTypeStart + 1; i < typeFullName.Length; i++) 161 | { 162 | if (typeFullName[i] == '[') 163 | { 164 | if (typeInfoStartIndex == -1) typeInfoStartIndex = i; 165 | scope++; 166 | } 167 | else if (typeFullName[i] == ']') 168 | { 169 | scope--; 170 | } 171 | else 172 | { 173 | continue; 174 | } 175 | if (scope == 0) 176 | { 177 | genericType.GenericTypes.Add(Parse(typeFullName.Substring(typeInfoStartIndex + 1, i - typeInfoStartIndex - 1))); 178 | if (genericType.GenericTypes.Count == genericCount) break; 179 | typeInfoStartIndex = -1; 180 | } 181 | } 182 | return genericType; 183 | } 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SystemStartResponseReciever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.Windows.Forms; 4 | using System.Threading; 5 | 6 | namespace Codeer.Friendly.Windows.Inside 7 | { 8 | /// 9 | /// システム開始レスポンス受信。 10 | /// 11 | class SystemStartResponseReciever 12 | { 13 | Thread _recieveThread; 14 | IntPtr _systemControlWindowInAppHandle; 15 | long _errNo; 16 | 17 | /// 18 | /// 開始。 19 | /// 20 | /// 対象プロセスID。 21 | /// レスポンス受信用ウィンドウハンドル。 22 | internal IntPtr Start(int targetProcessId) 23 | { 24 | IntPtr recieveWindowHandle = IntPtr.Zero; 25 | object sync = new object(); 26 | _recieveThread = new Thread((ThreadStart)delegate 27 | { 28 | using (RecieveWindow window = new RecieveWindow()) 29 | { 30 | lock (sync) 31 | { 32 | recieveWindowHandle = window.Handle; 33 | } 34 | 35 | //受信待ち 36 | while (!window.IsError) 37 | { 38 | NativeMethods.MSG msg = new NativeMethods.MSG(); 39 | if (NativeMethods.PeekMessage(ref msg, window.Handle, 0, 0, NativeMethods.PeekMsgOption.PM_REMOVE)) 40 | { 41 | NativeMethods.TranslateMessage(ref msg); 42 | NativeMethods.DispatchMessage(ref msg); 43 | } 44 | if (window.SystemControlWindowHandle != IntPtr.Zero) 45 | { 46 | lock (sync) 47 | { 48 | _systemControlWindowInAppHandle = window.SystemControlWindowHandle; 49 | } 50 | break; 51 | } 52 | Thread.Sleep(10); 53 | 54 | //通信プロセスが消えたら終わり 55 | try 56 | { 57 | if (Process.GetProcessById(targetProcessId) == null) 58 | { 59 | break; 60 | } 61 | } 62 | catch 63 | { 64 | break; 65 | } 66 | } 67 | lock (sync) 68 | { 69 | _errNo = window.ErrNo; 70 | } 71 | } 72 | }); 73 | _recieveThread.Start(); 74 | 75 | //受信ウィンドウ生成待ち。 76 | while (true) 77 | { 78 | lock (sync) 79 | { 80 | if (recieveWindowHandle != IntPtr.Zero) 81 | { 82 | break; 83 | } 84 | } 85 | } 86 | return recieveWindowHandle; 87 | } 88 | 89 | /// 90 | /// 受信スレッドの終了待ち(返信待ち)。 91 | /// 92 | /// エラー番号。 93 | /// 対象プロセス内のコントロール用ウィンドウのハンドル。 94 | internal IntPtr WaitForCompletion(ref long errNo) 95 | { 96 | while (_recieveThread.IsAlive) 97 | { 98 | Thread.Sleep(10); 99 | } 100 | errNo = _errNo; 101 | return _systemControlWindowInAppHandle; 102 | } 103 | 104 | /// 105 | /// システムコントロールウィンドウハンドル受信。 106 | /// 107 | class RecieveWindow : CommunicationWindow 108 | { 109 | IntPtr _systemControlWindowHandle; 110 | bool _isError; 111 | long _errNo; 112 | 113 | /// 114 | /// システムコントロールウィンドウハンドル。 115 | /// 116 | internal IntPtr SystemControlWindowHandle { get { return _systemControlWindowHandle; } } 117 | 118 | /// 119 | /// エラー終了したか。 120 | /// 121 | internal bool IsError { get { return _isError; } } 122 | 123 | /// 124 | /// エラー番号。 125 | /// 126 | internal long ErrNo { get { return _errNo; } } 127 | 128 | /// 129 | /// コンストラクタ。 130 | /// 131 | internal RecieveWindow() 132 | { 133 | CreateHandle(); 134 | } 135 | 136 | /// 137 | /// ウィンドウプロック。 138 | /// 139 | /// メッセージ。 140 | protected override void WndProc(ref Message m) 141 | { 142 | if (m.Msg == SystemStarterInApp.WM_NOTIFY_SYSTEM_CONTROL_WINDOW_HANDLE) 143 | { 144 | _systemControlWindowHandle = m.WParam; 145 | if (_systemControlWindowHandle == IntPtr.Zero) 146 | { 147 | _isError = true; 148 | _errNo = m.LParam.ToInt64(); 149 | } 150 | return; 151 | } 152 | base.WndProc(ref m); 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Project/Codeer.Friendly.Windows/Inside/SystemControlWindowInApp.cs: -------------------------------------------------------------------------------- 1 | #define CODE_ANALYSIS 2 | using System; 3 | using System.Windows.Forms; 4 | using System.Collections.Generic; 5 | using Codeer.Friendly.Inside.Protocol; 6 | using Codeer.Friendly.DotNetExecutor; 7 | using Codeer.Friendly.Windows.Inside.CopyDataProtocol; 8 | using System.Threading; 9 | using System.Runtime.InteropServices; 10 | using System.Diagnostics.CodeAnalysis; 11 | 12 | namespace Codeer.Friendly.Windows.Inside 13 | { 14 | /// 15 | /// アプリケーション側システムコントロールウィンドウ。 16 | /// 17 | class SystemControlWindowInApp : ReceiveForm 18 | { 19 | FriendlyConnectorWindowInAppManager _handleAndWindow = new FriendlyConnectorWindowInAppManager(); 20 | DotNetFriendlyControl _dotNetFriendlyControl = new DotNetFriendlyControl(); 21 | 22 | /// 23 | /// データ受信時の処理。 24 | /// 25 | /// 通信番号。 26 | /// 受信データ。 27 | /// 送信元ウィンドウ。 28 | protected override void OnRecieveData(int communicationNo, object recieveData, IntPtr senderWindow) 29 | { 30 | SystemControlInfo controlInfo = (SystemControlInfo)recieveData; 31 | object ret = null; 32 | switch (controlInfo.SystemControlType) 33 | { 34 | case SystemControlType.StartFriendlyConnectorWindowInApp: 35 | ret = StartFriendlyConnectorWindowInApp(controlInfo); 36 | break; 37 | case SystemControlType.EndFriendlyConnectorWindowInApp: 38 | EndFriendlyConnectorWindowInApp(controlInfo); 39 | break; 40 | case SystemControlType.EndSystem: 41 | EndSystem(); 42 | break; 43 | } 44 | SendReturnData(communicationNo, senderWindow, ret); 45 | } 46 | 47 | /// 48 | /// フレンドリー操作ウィンドウ開始。 49 | /// 50 | /// コントロール情報。 51 | /// FriendlyConnectorWindowInAppのハンドル。 52 | IntPtr StartFriendlyConnectorWindowInApp(SystemControlInfo controlInfo) 53 | { 54 | IntPtr targetThreadWindowHandle = (IntPtr)controlInfo.Data; 55 | FriendlyConnectorWindowInApp window = null; 56 | IntPtr executeWindowHandle = IntPtr.Zero; 57 | if (!TargetWindowExecutor.Execute(targetThreadWindowHandle, delegate 58 | { 59 | window = new FriendlyConnectorWindowInApp(_handleAndWindow, _dotNetFriendlyControl); 60 | executeWindowHandle = window.Handle; 61 | })) 62 | { 63 | return IntPtr.Zero; 64 | } 65 | 66 | //登録 67 | _handleAndWindow.Add(executeWindowHandle, window); 68 | return executeWindowHandle; 69 | } 70 | 71 | /// 72 | /// フレンドリー操作ウィンドウ終了。 73 | /// 74 | /// コントロール情報。 75 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 76 | void EndFriendlyConnectorWindowInApp(SystemControlInfo controlInfo) 77 | { 78 | IntPtr handle = (IntPtr)controlInfo.Data; 79 | FriendlyConnectorWindowInApp invokeWindow = _handleAndWindow.FromHandle(handle); 80 | _handleAndWindow.Remove(handle); 81 | 82 | //スレッドが異なるので、Invokeによって終了処理を実施する。 83 | if (invokeWindow != null) 84 | { 85 | try 86 | { 87 | invokeWindow.Invoke((MethodInvoker)delegate 88 | { 89 | try 90 | { 91 | invokeWindow.RequestDispose(); 92 | } 93 | catch { } 94 | }); 95 | } 96 | catch { } 97 | } 98 | } 99 | 100 | /// 101 | /// システム終了 102 | /// 103 | void EndSystem() 104 | { 105 | //自身のスレッドを終了させる 106 | NativeMethods.PostMessage(Handle, NativeMethods.WM_QUIT, IntPtr.Zero, IntPtr.Zero); 107 | } 108 | 109 | /// 110 | /// 破棄 111 | /// 112 | /// Disposeメソッドから呼び出されたか 113 | [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")] 114 | protected override void Dispose(bool disposing) 115 | { 116 | try 117 | { 118 | if (_handleAndWindow != null) 119 | { 120 | //ウィンドウ全終了 121 | foreach (KeyValuePair element in _handleAndWindow.Clone()) 122 | { 123 | //何らかの都合で終了に失敗するものが出ても消せるだけ消しておく 124 | //スレッドが異なるので、Invokeによって終了処理を実施する 125 | try 126 | { 127 | element.Value.Invoke((MethodInvoker)delegate 128 | { 129 | try 130 | { 131 | element.Value.RequestDispose(); 132 | } 133 | catch { } 134 | }); 135 | } 136 | catch { } 137 | } 138 | _handleAndWindow = null; 139 | } 140 | _dotNetFriendlyControl = null; 141 | } 142 | catch { } 143 | base.Dispose(disposing); 144 | } 145 | } 146 | } 147 | --------------------------------------------------------------------------------