mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-07 07:02:50 +08:00
Merge pull request #51 from Lightczx/master
Use Microsoft.Windows.CsWin32 to replace manual PInvoke
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0-windows7</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
@@ -21,8 +21,12 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.21.6" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.22.0" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.188-beta">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -31,6 +35,10 @@
|
||||
<LastGenOutput>App.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<None Remove="res\Updater.exe" />
|
||||
<None Remove="src\NativeMethods.json" />
|
||||
<None Remove="src\NativeMethods.txt" />
|
||||
<AdditionalFiles Include="src\NativeMethods.json" />
|
||||
<AdditionalFiles Include="src\NativeMethods.txt" />
|
||||
<EmbeddedResource Include="res\Updater.exe">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using Microsoft.Win32;
|
||||
using YaeAchievement.Win32;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.Graphics.Gdi;
|
||||
//using YaeAchievement.Win32;
|
||||
|
||||
namespace YaeAchievement.AppCenterSDK;
|
||||
|
||||
@@ -21,9 +24,9 @@ public static class DeviceHelper {
|
||||
}
|
||||
|
||||
public static string GetScreenSize() {
|
||||
var desktop = Native.GetDC(IntPtr.Zero);
|
||||
var size = $"{Native.GetDeviceCaps(desktop, 118)}x{Native.GetDeviceCaps(desktop, 117)}";
|
||||
Native.ReleaseDC(IntPtr.Zero, desktop);
|
||||
var desktop = Native.GetDC(HWND.Null);
|
||||
var size = $"{Native.GetDeviceCaps(desktop, GET_DEVICE_CAPS_INDEX.DESKTOPHORZRES)}x{Native.GetDeviceCaps(desktop, GET_DEVICE_CAPS_INDEX.DESKTOPVERTRES)}";
|
||||
Native.ReleaseDC(HWND.Null, desktop);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@@ -1,52 +1,77 @@
|
||||
using System.ComponentModel;
|
||||
using Microsoft.Win32.SafeHandles;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.System.Memory;
|
||||
using Windows.Win32.System.Threading;
|
||||
using YaeAchievement.Win32;
|
||||
using static YaeAchievement.Win32.Native;
|
||||
|
||||
namespace YaeAchievement;
|
||||
namespace YaeAchievement;
|
||||
|
||||
public static class Injector {
|
||||
|
||||
public static unsafe bool CreateProcess(string path, out IntPtr hProc, out IntPtr hThread, out uint pid) {
|
||||
var si = new StartupInfo();
|
||||
SecurityAttributes* attr = null;
|
||||
public static unsafe bool CreateProcess(string path, out HANDLE hProc, out HANDLE hThread, out uint pid) {
|
||||
Span<char> cmdLines = stackalloc char[1]; // "\0"
|
||||
var si = new STARTUPINFOW() { cb = unchecked((uint)sizeof(STARTUPINFOW)) };
|
||||
var dir = Path.GetDirectoryName(path)!;
|
||||
var result = Native.CreateProcess(
|
||||
path, null, ref *attr, ref *attr, false,
|
||||
CreationFlags.CreateSuspended, IntPtr.Zero, dir, ref si, out var pi
|
||||
path, ref cmdLines, default, default, false,
|
||||
PROCESS_CREATION_FLAGS.CREATE_SUSPENDED, default, dir, in si, out var pi
|
||||
);
|
||||
pid = pi.dwProcessID;
|
||||
pid = pi.dwProcessId;
|
||||
hProc = pi.hProcess;
|
||||
hThread = pi.hThread;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// todo: refactor
|
||||
public static int LoadLibraryAndInject(IntPtr hProc, string libPath) {
|
||||
var hKernel = GetModuleHandle("kernel32.dll");
|
||||
if (hKernel == IntPtr.Zero) {
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail");
|
||||
public static unsafe int LoadLibraryAndInject(HANDLE hProc, ReadOnlySpan<byte> libPath)
|
||||
{
|
||||
fixed (char* lpModelName = "kernel32.dll")
|
||||
{
|
||||
HINSTANCE hKernel = Native.GetModuleHandle(lpModelName);
|
||||
|
||||
if (hKernel.IsNull)
|
||||
{
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("GetModuleHandle fail");
|
||||
}
|
||||
|
||||
fixed(byte* lpProcName = "LoadLibraryA"u8)
|
||||
{
|
||||
var pLoadLibrary = Native.GetProcAddress(hKernel, (PCSTR)lpProcName);
|
||||
if (pLoadLibrary.IsNull)
|
||||
{
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail");
|
||||
}
|
||||
var pBase = Native.VirtualAllocEx(hProc, default, unchecked((uint)libPath.Length + 1), VIRTUAL_ALLOCATION_TYPE.MEM_RESERVE | VIRTUAL_ALLOCATION_TYPE.MEM_COMMIT, PAGE_PROTECTION_FLAGS.PAGE_READWRITE);
|
||||
if ((nint)pBase == 0)
|
||||
{
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail");
|
||||
}
|
||||
fixed (void* lpBuffer = libPath)
|
||||
{
|
||||
if (!Native.WriteProcessMemory(hProc, pBase, lpBuffer, unchecked((uint)libPath.Length), default))
|
||||
{
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail");
|
||||
}
|
||||
}
|
||||
|
||||
var lpStartAddress = pLoadLibrary.CreateDelegate<LPTHREAD_START_ROUTINE>();
|
||||
var hThread = Native.CreateRemoteThread(hProc, default, 0, lpStartAddress, pBase, 0, default);
|
||||
|
||||
if (hThread.IsNull)
|
||||
{
|
||||
var e = new Win32Exception();
|
||||
Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE);
|
||||
return e.PrintMsgAndReturnErrCode("CreateRemoteThread fail");
|
||||
}
|
||||
if (Native.WaitForSingleObject(hThread, 2000) == 0)
|
||||
{
|
||||
Native.VirtualFreeEx(hProc, pBase, 0, VIRTUAL_FREE_TYPE.MEM_RELEASE);
|
||||
}
|
||||
return !Native.CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0;
|
||||
}
|
||||
}
|
||||
var pLoadLibrary = GetProcAddress(hKernel, "LoadLibraryA");
|
||||
if (pLoadLibrary == IntPtr.Zero) {
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("GetProcAddress fail");
|
||||
}
|
||||
var pBase = VirtualAllocEx(hProc, IntPtr.Zero, libPath.Length + 1, AllocationType.Reserve | AllocationType.Commit, MemoryProtection.ReadWrite);
|
||||
if (pBase == IntPtr.Zero) {
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("VirtualAllocEx fail");
|
||||
}
|
||||
if (!WriteProcessMemory(hProc, pBase, libPath.ToCharArray(), libPath.Length, out _)) {
|
||||
return new Win32Exception().PrintMsgAndReturnErrCode("WriteProcessMemory fail");
|
||||
}
|
||||
var hThread = CreateRemoteThread(hProc, IntPtr.Zero, 0, pLoadLibrary, pBase, 0, out _);
|
||||
if (hThread == IntPtr.Zero) {
|
||||
var e = new Win32Exception();
|
||||
VirtualFreeEx(hProc, pBase, 0, AllocationType.Release);
|
||||
return e.PrintMsgAndReturnErrCode("CreateRemoteThread fail");
|
||||
}
|
||||
if (WaitForSingleObject(hThread, 2000) == 0) {
|
||||
VirtualFreeEx(hProc, pBase, 0, AllocationType.Release);
|
||||
}
|
||||
return !CloseHandle(hThread) ? new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail") : 0;
|
||||
}
|
||||
|
||||
}
|
||||
6
src/NativeMethods.json
Normal file
6
src/NativeMethods.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://aka.ms/CsWin32.schema.json",
|
||||
"className": "Native",
|
||||
"allowMarshaling": true,
|
||||
"public": true
|
||||
}
|
||||
21
src/NativeMethods.txt
Normal file
21
src/NativeMethods.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
CreateProcess
|
||||
GetModuleHandle
|
||||
GetProcAddress
|
||||
VirtualAllocEx
|
||||
WriteProcessMemory
|
||||
CreateRemoteThread
|
||||
VirtualFreeEx
|
||||
WaitForSingleObject
|
||||
OpenClipboard
|
||||
EmptyClipboard
|
||||
GlobalLock
|
||||
SetClipboardData
|
||||
GlobalUnlock
|
||||
CloseClipboard
|
||||
GetStdHandle
|
||||
GetConsoleMode
|
||||
SetConsoleMode
|
||||
TerminateProcess
|
||||
ResumeThread
|
||||
GetDeviceCaps
|
||||
GetDC
|
||||
51
src/Utils.cs
51
src/Utils.cs
@@ -1,11 +1,15 @@
|
||||
using System.ComponentModel;
|
||||
using Microsoft.Win32;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipes;
|
||||
using System.Net;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Win32;
|
||||
using System.Text;
|
||||
using Windows.Win32;
|
||||
using Windows.Win32.Foundation;
|
||||
using Windows.Win32.System.Console;
|
||||
using YaeAchievement.AppCenterSDK;
|
||||
using YaeAchievement.res;
|
||||
using YaeAchievement.Win32;
|
||||
@@ -64,18 +68,21 @@ public static class Utils {
|
||||
public static bool ToBooleanOrFalse(string? value) {
|
||||
return value != null && bool.TryParse(value, out var result) && result;
|
||||
}
|
||||
|
||||
public static void CopyToClipboard(string text) {
|
||||
if (Native.OpenClipboard(IntPtr.Zero)) {
|
||||
|
||||
public static unsafe void CopyToClipboard(string text) {
|
||||
if (Native.OpenClipboard(HWND.Null))
|
||||
{
|
||||
Native.EmptyClipboard();
|
||||
var hGlobal = Marshal.AllocHGlobal((text.Length + 1) * 2);
|
||||
var hPtr = Native.GlobalLock(hGlobal);
|
||||
HANDLE hGlobal = (HANDLE)Marshal.AllocHGlobal((text.Length + 1) * 2);
|
||||
IntPtr hPtr = (IntPtr)Native.GlobalLock(hGlobal);
|
||||
Marshal.Copy(text.ToCharArray(), 0, hPtr, text.Length);
|
||||
Native.GlobalUnlock(hPtr);
|
||||
Native.SetClipboardData(13, hGlobal);
|
||||
Marshal.FreeHGlobal(hGlobal);
|
||||
Native.CloseClipboard();
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Win32Exception();
|
||||
}
|
||||
}
|
||||
@@ -144,9 +151,10 @@ public static class Utils {
|
||||
}
|
||||
|
||||
// ReSharper disable once UnusedMethodReturnValue.Global
|
||||
public static bool TryDisableQuickEdit() {
|
||||
var handle = Native.GetStdHandle();
|
||||
return Native.GetConsoleMode(handle, out var mode) && Native.SetConsoleMode(handle, mode&~64);
|
||||
public static unsafe bool TryDisableQuickEdit() {
|
||||
var handle = Native.GetStdHandle(STD_HANDLE.STD_INPUT_HANDLE);
|
||||
CONSOLE_MODE mode = default;
|
||||
return Native.GetConsoleMode(handle, &mode) && Native.SetConsoleMode(handle, mode & ~CONSOLE_MODE.ENABLE_QUICK_EDIT_MODE);
|
||||
}
|
||||
|
||||
public static void CheckGenshinIsRunning() {
|
||||
@@ -208,7 +216,7 @@ public static class Utils {
|
||||
return File.Exists(path) && (hash == _updateInfo.CurrentCNGameHash || hash == _updateInfo.CurrentOSGameHash);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ReSharper disable once UnusedMethodReturnValue.Global
|
||||
public static Thread StartAndWaitResult(string exePath, Func<string, bool> onReceive) {
|
||||
if (!CheckGenshinIsLatestVersion(exePath)) {
|
||||
@@ -223,8 +231,10 @@ public static class Utils {
|
||||
if (!Injector.CreateProcess(exePath, out var hProcess, out var hThread, out var pid)) {
|
||||
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("ICreateProcess fail"));
|
||||
}
|
||||
if (Injector.LoadLibraryAndInject(hProcess, GlobalVars.LibFilePath) != 0) {
|
||||
if (!Native.TerminateProcess(hProcess, 0)) {
|
||||
if (Injector.LoadLibraryAndInject(hProcess,Encoding.UTF8.GetBytes(GlobalVars.LibFilePath)) != 0)
|
||||
{
|
||||
if (!Native.TerminateProcess(hProcess, 0))
|
||||
{
|
||||
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("TerminateProcess fail"));
|
||||
}
|
||||
}
|
||||
@@ -232,22 +242,27 @@ public static class Utils {
|
||||
proc = Process.GetProcessById(Convert.ToInt32(pid));
|
||||
proc.EnableRaisingEvents = true;
|
||||
proc.Exited += (_, _) => {
|
||||
if (GlobalVars.UnexpectedExit) {
|
||||
if (GlobalVars.UnexpectedExit)
|
||||
{
|
||||
proc = null;
|
||||
Console.WriteLine(App.GameProcessExit);
|
||||
Environment.Exit(114514);
|
||||
}
|
||||
};
|
||||
if (Native.ResumeThread(hThread) == 0xFFFFFFFF) {
|
||||
if (Native.ResumeThread(hThread) == 0xFFFFFFFF)
|
||||
{
|
||||
var e = new Win32Exception();
|
||||
if (!Native.TerminateProcess(hProcess, 0)) {
|
||||
if (!Native.TerminateProcess(hProcess, 0))
|
||||
{
|
||||
new Win32Exception().PrintMsgAndReturnErrCode("TerminateProcess fail");
|
||||
}
|
||||
Environment.Exit(e.PrintMsgAndReturnErrCode("ResumeThread fail"));
|
||||
}
|
||||
if (!Native.CloseHandle(hProcess)) {
|
||||
if (!Native.CloseHandle(hProcess))
|
||||
{
|
||||
Environment.Exit(new Win32Exception().PrintMsgAndReturnErrCode("CloseHandle fail"));
|
||||
}
|
||||
|
||||
var ts = new ThreadStart(() => {
|
||||
var server = new NamedPipeServerStream(GlobalVars.PipeName);
|
||||
server.WaitForConnection();
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[Flags]
|
||||
public enum AllocationType : uint {
|
||||
Commit = 0x00001000,
|
||||
Reserve = 0x00002000,
|
||||
Reset = 0x00080000,
|
||||
TopDown = 0x00100000,
|
||||
WriteWatch = 0x00200000,
|
||||
Physical = 0x00400000,
|
||||
Rotate = 0x00800000,
|
||||
ResetUndo = 0x01000000,
|
||||
LargePages = 0x20000000,
|
||||
Decommit = 0x00004000,
|
||||
Release = 0x00008000
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[Flags]
|
||||
public enum CreationFlags : uint {
|
||||
CreateSuspended = 0x00000004,
|
||||
DetachedProcess = 0x00000008,
|
||||
CreateNoWindow = 0x08000000,
|
||||
ExtendedStartupInfoPresent = 0x00080000
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[Flags]
|
||||
public enum MemoryProtection : uint {
|
||||
Execute = 0x10,
|
||||
ExecuteRead = 0x20,
|
||||
ExecuteReadWrite = 0x40,
|
||||
ExecuteWriteCopy = 0x80,
|
||||
NoAccess = 0x01,
|
||||
ReadOnly = 0x02,
|
||||
ReadWrite = 0x04,
|
||||
WriteCopy = 0x08,
|
||||
GuardModifierFlag = 0x100,
|
||||
NoCacheModifierFlag = 0x200,
|
||||
WriteCombineModifierFlag = 0x400
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
#pragma warning disable CA1401, CA2101
|
||||
public static class Native {
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
|
||||
public static extern bool CreateProcess(
|
||||
string lpApplicationName,
|
||||
string? lpCommandLine,
|
||||
ref SecurityAttributes lpProcessAttributes,
|
||||
ref SecurityAttributes lpThreadAttributes,
|
||||
bool bInheritHandles,
|
||||
CreationFlags dwCreationFlags,
|
||||
IntPtr lpEnvironment,
|
||||
string? lpCurrentDirectory,
|
||||
[In] ref StartupInfo lpStartupInfo,
|
||||
out ProcessInformation lpProcessInformation
|
||||
);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern bool WriteProcessMemory(
|
||||
IntPtr hProcess,
|
||||
IntPtr lpBaseAddress,
|
||||
char[] lpBuffer,
|
||||
int nSize,
|
||||
out IntPtr lpNumberOfBytesWritten
|
||||
);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
|
||||
public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
public static extern IntPtr VirtualAllocEx(
|
||||
IntPtr hProcess,
|
||||
IntPtr lpAddress,
|
||||
int dwSize,
|
||||
AllocationType flAllocationType,
|
||||
MemoryProtection flProtect
|
||||
);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress, int dwSize, AllocationType dwFreeType);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern uint ResumeThread(IntPtr hThread);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool CloseHandle(IntPtr hObject);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern IntPtr CreateRemoteThread(
|
||||
IntPtr hProcess,
|
||||
IntPtr lpThreadAttributes,
|
||||
int dwStackSize,
|
||||
IntPtr lpStartAddress,
|
||||
IntPtr lpParameter,
|
||||
uint dwCreationFlags,
|
||||
out IntPtr lpThreadId
|
||||
);
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private const int STD_INPUT_HANDLE = -10;
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetStdHandle(int nStdHandle = STD_INPUT_HANDLE);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool GetConsoleMode(IntPtr handle, out int lpMode);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool SetConsoleMode(IntPtr handle, int ioMode);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GlobalLock(IntPtr mem);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern bool GlobalUnlock(IntPtr mem);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool OpenClipboard(IntPtr owner);
|
||||
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool CloseClipboard();
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr SetClipboardData(uint uFormat, IntPtr data);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool EmptyClipboard();
|
||||
|
||||
[DllImport("gdi32.dll", SetLastError = true)]
|
||||
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr GetDC(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hdc);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
public static extern uint WaitForSingleObject(IntPtr handle, ulong dwMilliseconds);
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ProcessInformation {
|
||||
public IntPtr hProcess;
|
||||
public IntPtr hThread;
|
||||
public uint dwProcessID;
|
||||
public uint dwThreadID;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SecurityAttributes {
|
||||
public int nLength;
|
||||
public IntPtr lpSecurityDescriptor;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable FieldCanBeMadeReadOnly.Global
|
||||
|
||||
namespace YaeAchievement.Win32;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||
public struct StartupInfo {
|
||||
public uint cb;
|
||||
public string lpReserved;
|
||||
public string lpDesktop;
|
||||
public string lpTitle;
|
||||
public uint dwX;
|
||||
public uint dwY;
|
||||
public uint dwXSize;
|
||||
public uint dwYSize;
|
||||
public uint dwXCountChars;
|
||||
public uint dwYCountChars;
|
||||
public uint dwFillAttribute;
|
||||
public uint dwFlags;
|
||||
public ushort wShowWindow;
|
||||
public ushort cbReserved2;
|
||||
public IntPtr lpReserved2;
|
||||
public IntPtr hStdInput;
|
||||
public IntPtr hStdOutput;
|
||||
public IntPtr hStdError;
|
||||
}
|
||||
Reference in New Issue
Block a user