From 1a1c8e71fcd14858f595029f089b2d4a00202b32 Mon Sep 17 00:00:00 2001
From: ogi <Administrator@S-OGI-PC>
Date: Fri, 05 Dec 2025 09:24:16 +0900
Subject: [PATCH] プロジェクトファイルを追加。
---
HotelPms.Share/Util/ServiceCore.cs | 434 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 434 insertions(+), 0 deletions(-)
diff --git a/HotelPms.Share/Util/ServiceCore.cs b/HotelPms.Share/Util/ServiceCore.cs
new file mode 100644
index 0000000..51cdf06
--- /dev/null
+++ b/HotelPms.Share/Util/ServiceCore.cs
@@ -0,0 +1,434 @@
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace HotelPms.Share.Util
+{
+ public class ServiceCore
+ {
+ #region DLLImport
+
+ [DllImport("advapi32.dll")]
+ public static extern IntPtr OpenSCManager(string lpMachineName, string lpSCDB, int scParameter);
+ [DllImport("Advapi32.dll")]
+ public static extern IntPtr CreateService(IntPtr SC_HANDLE, string lpSvcName, string lpDisplayName,
+ int dwDesiredAccess, int dwServiceType, int dwStartType, int dwErrorControl, string lpPathName,
+ string lpLoadOrderGroup, int lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword);
+ [DllImport("advapi32.dll")]
+ public static extern void CloseServiceHandle(IntPtr SCHANDLE);
+ [DllImport("advapi32.dll")]
+ public static extern int StartService(IntPtr SVHANDLE, int dwNumServiceArgs, string lpServiceArgVectors);
+ [DllImport("advapi32.dll", SetLastError = true)]
+ public static extern IntPtr OpenService(IntPtr SCHANDLE, string lpSvcName, int dwNumServiceArgs);
+ [DllImport("advapi32.dll")]
+ public static extern int DeleteService(IntPtr SVHANDLE);
+ [DllImport("kernel32.dll")]
+ public static extern int GetLastError();
+
+ const int SERVICE_CONFIG_DESCRIPTION = 0x01;
+
+ [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ public static extern bool ChangeServiceConfig2(IntPtr hService, int dwInfoLevel, [MarshalAs(UnmanagedType.Struct)] ref SERVICE_DESCRIPTION lpInfo);
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct SERVICE_DESCRIPTION
+ {
+ public string lpDescription;
+ }
+
+ #endregion DLLImport
+
+ #region Constants declaration.
+
+ private const int SC_MANAGER_CREATE_SERVICE = 0x0002;
+ private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
+ //int SERVICE_DEMAND_START = 0x00000003;
+ private const int SERVICE_ERROR_NORMAL = 0x00000001;
+ private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
+ private const int SERVICE_QUERY_CONFIG = 0x0001;
+ private const int SERVICE_CHANGE_CONFIG = 0x0002;
+ private const int SERVICE_QUERY_STATUS = 0x0004;
+ private const int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
+ private const int SERVICE_START = 0x0010;
+ private const int SERVICE_STOP = 0x0020;
+ private const int SERVICE_PAUSE_CONTINUE = 0x0040;
+ private const int SERVICE_INTERROGATE = 0x0080;
+ private const int SERVICE_USER_DEFINED_CONTROL = 0x0100;
+ private const int SERVICE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
+ SERVICE_QUERY_CONFIG |
+ SERVICE_CHANGE_CONFIG |
+ SERVICE_QUERY_STATUS |
+ SERVICE_ENUMERATE_DEPENDENTS |
+ SERVICE_START |
+ SERVICE_STOP |
+ SERVICE_PAUSE_CONTINUE |
+ SERVICE_INTERROGATE |
+ SERVICE_USER_DEFINED_CONTROL);
+ private const int SERVICE_AUTO_START = 0x00000002;
+
+ #endregion Constants declaration.
+
+ /// <summary>
+ /// 安装和运行
+ /// </summary>
+ /// <param name="svcPath">程序路径.</param>
+ /// <param name="svcName">服务名</param>
+ /// <param name="svcDispName">服务显示名称.</param>
+ /// <returns>服务安装是否成功.</returns>
+ public static bool Install(string svcPath, string svcName, string svcDispName, string description)
+ {
+ try
+ {
+ IntPtr sc_handle = OpenSCManager(null, null, SC_MANAGER_CREATE_SERVICE);
+ if (sc_handle != IntPtr.Zero)
+ {
+ IntPtr sv_handle = CreateService(sc_handle, svcName, svcDispName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, svcPath, null, 0, null, null, null);
+ if (sv_handle == IntPtr.Zero)
+ {
+ CloseServiceHandle(sc_handle);
+ return false;
+ }
+ else
+ {
+ var pinfo = new SERVICE_DESCRIPTION
+ {
+ lpDescription = description
+ };
+ ChangeServiceConfig2(sv_handle, SERVICE_CONFIG_DESCRIPTION, ref pinfo);
+ //试尝启动服务
+ int i = StartService(sv_handle, 0, null);
+ if (i == 0)
+ {
+ return false;
+ }
+ CloseServiceHandle(sc_handle);
+ return true;
+ }
+ }
+ else
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+ /// <summary>
+ /// 反安装服务.
+ /// </summary>
+ /// <param name="svcName">服务名.</param>
+ public static bool UnInstall(string svcName)
+ {
+ IntPtr sc_hndl = IntPtr.Zero;
+ int GENERIC_WRITE = 0x40000000;
+
+ try
+ {
+ sc_hndl = OpenSCManager(null, null, GENERIC_WRITE);
+ if (sc_hndl != IntPtr.Zero)
+ {
+ int DELETE = 0x10000;
+ IntPtr svc_hndl = OpenService(sc_hndl, svcName, DELETE);
+ if (svc_hndl != IntPtr.Zero)
+ {
+ return DeleteService(svc_hndl) != 0;
+ }
+ else
+ return false;
+ }
+ else
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ finally
+ {
+ if (sc_hndl != IntPtr.Zero) { CloseServiceHandle(sc_hndl); }
+ }
+ }
+
+
+ #region Structures
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct SECURITY_ATTRIBUTES
+ {
+ public int Length;
+ public IntPtr lpSecurityDescriptor;
+ public bool bInheritHandle;
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct STARTUPINFO
+ {
+ public int 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 short wShowWindow;
+ public short cbReserved2;
+ public IntPtr lpReserved2;
+ public IntPtr hStdInput;
+ public IntPtr hStdOutput;
+ public IntPtr hStdError;
+ }
+
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PROCESS_INFORMATION
+ {
+ public IntPtr hProcess;
+ public IntPtr hThread;
+ public uint dwProcessId;
+ public uint dwThreadId;
+ }
+
+
+ #endregion
+
+
+ #region Enumerations
+
+
+ enum TOKEN_TYPE : int
+ {
+ TokenPrimary = 1,
+ TokenImpersonation = 2
+ }
+
+
+ enum SECURITY_IMPERSONATION_LEVEL : int
+ {
+ SecurityAnonymous = 0,
+ SecurityIdentification = 1,
+ SecurityImpersonation = 2,
+ SecurityDelegation = 3,
+ }
+
+
+ enum WTSInfoClass
+ {
+ InitialProgram,
+ ApplicationName,
+ WorkingDirectory,
+ OEMId,
+ SessionId,
+ UserName,
+ WinStationName,
+ DomainName,
+ ConnectState,
+ ClientBuildNumber,
+ ClientName,
+ ClientDirectory,
+ ClientProductId,
+ ClientHardwareId,
+ ClientAddress,
+ ClientDisplay,
+ ClientProtocolType
+ }
+
+
+ #endregion
+
+
+ #region Constants
+
+
+ public const int TOKEN_DUPLICATE = 0x0002;
+ public const uint MAXIMUM_ALLOWED = 0x2000000;
+ public const int CREATE_NEW_CONSOLE = 0x00000010;
+
+
+ public const int IDLE_PRIORITY_CLASS = 0x40;
+ public const int NORMAL_PRIORITY_CLASS = 0x20;
+ public const int HIGH_PRIORITY_CLASS = 0x80;
+ public const int REALTIME_PRIORITY_CLASS = 0x100;
+
+
+ #endregion
+
+
+ #region Win32 API Imports
+
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool CloseHandle(IntPtr hSnapshot);
+
+
+ [DllImport("kernel32.dll")]
+ static extern uint WTSGetActiveConsoleSessionId();
+
+
+ [DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
+ static extern bool WTSQuerySessionInformation(System.IntPtr hServer, int sessionId, WTSInfoClass wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);
+
+
+ [DllImport("advapi32.dll", EntryPoint = "CreateProcessAsUser", SetLastError = true, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
+ public extern static bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, String lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
+ ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandle, int dwCreationFlags, IntPtr lpEnvironment,
+ String lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation);
+
+
+ [DllImport("kernel32.dll")]
+ static extern bool ProcessIdToSessionId(uint dwProcessId, ref uint pSessionId);
+
+
+ [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
+ public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess,
+ ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType,
+ int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);
+
+
+ [DllImport("kernel32.dll")]
+ static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
+
+
+ [DllImport("advapi32", SetLastError = true), SuppressUnmanagedCodeSecurityAttribute]
+ static extern bool OpenProcessToken(IntPtr ProcessHandle, int DesiredAccess, ref IntPtr TokenHandle);
+
+
+ #endregion
+
+
+ public static string GetCurrentActiveUser()
+ {
+ IntPtr hServer = IntPtr.Zero, state = IntPtr.Zero;
+ uint bCount = 0;
+
+
+ // obtain the currently active session id; every logged on user in the system has a unique session id
+ uint dwSessionId = WTSGetActiveConsoleSessionId();
+ string domain = string.Empty, userName = string.Empty;
+
+
+ if (WTSQuerySessionInformation(hServer, (int)dwSessionId, WTSInfoClass.DomainName, out state, out bCount))
+ {
+ domain = Marshal.PtrToStringAuto(state);
+ }
+
+
+ if (WTSQuerySessionInformation(hServer, (int)dwSessionId, WTSInfoClass.UserName, out state, out bCount))
+ {
+ userName = Marshal.PtrToStringAuto(state);
+ }
+
+
+ return string.Format("{0}\\{1}", domain, userName);
+ }
+
+ public static bool StartProcessAndBypassUAC(String applicationName)
+ {
+ PROCESS_INFORMATION procInfo;
+ return StartProcessAndBypassUAC(applicationName, string.Empty, out procInfo);
+ }
+
+ /// <summary>
+ /// Launches the given application with full admin rights, and in addition bypasses the Vista UAC prompt
+ /// </summary>
+ /// <param name="applicationName">The name of the application to launch</param>
+ /// <param name="procInfo">Process information regarding the launched application that gets returned to the caller</param>
+ /// <returns></returns>
+ public static bool StartProcessAndBypassUAC(String applicationName, String command, out PROCESS_INFORMATION procInfo)
+ {
+ uint winlogonPid = 0;
+ IntPtr hUserTokenDup = IntPtr.Zero, hPToken = IntPtr.Zero, hProcess = IntPtr.Zero;
+ procInfo = new PROCESS_INFORMATION();
+
+
+ // obtain the currently active session id; every logged on user in the system has a unique session id
+ uint dwSessionId = WTSGetActiveConsoleSessionId();
+
+
+ // obtain the process id of the winlogon process that is running within the currently active session
+ Process[] processes = Process.GetProcessesByName("winlogon");
+ foreach (Process p in processes)
+ {
+ if ((uint)p.SessionId == dwSessionId)
+ {
+ winlogonPid = (uint)p.Id;
+ }
+ }
+
+
+ // obtain a handle to the winlogon process
+ hProcess = OpenProcess(MAXIMUM_ALLOWED, false, winlogonPid);
+
+
+ // obtain a handle to the access token of the winlogon process
+ if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE, ref hPToken))
+ {
+ CloseHandle(hProcess);
+ return false;
+ }
+
+
+ // Security attibute structure used in DuplicateTokenEx and CreateProcessAsUser
+ // I would prefer to not have to use a security attribute variable and to just
+ // simply pass null and inherit (by default) the security attributes
+ // of the existing token. However, in C# structures are value types and therefore
+ // cannot be assigned the null value.
+ SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
+ sa.Length = Marshal.SizeOf(sa);
+
+
+ // copy the access token of the winlogon process; the newly created token will be a primary token
+ if (!DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, ref sa, (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, (int)TOKEN_TYPE.TokenPrimary, ref hUserTokenDup))
+ {
+ CloseHandle(hProcess);
+ CloseHandle(hPToken);
+ return false;
+ }
+
+
+ // By default CreateProcessAsUser creates a process on a non-interactive window station, meaning
+ // the window station has a desktop that is invisible and the process is incapable of receiving
+ // user input. To remedy this we set the lpDesktop parameter to indicate we want to enable user
+ // interaction with the new process.
+ STARTUPINFO si = new STARTUPINFO();
+ si.cb = (int)Marshal.SizeOf(si);
+ si.lpDesktop = @"winsta0\default"; // interactive window station parameter; basically this indicates that the process created can display a GUI on the desktop
+
+
+ // flags that specify the priority and creation method of the process
+ int dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
+
+
+ // create a new process in the current user's logon session
+ bool result = CreateProcessAsUser(hUserTokenDup, // client's access token
+ applicationName, // file to execute
+ command, // command line
+ ref sa, // pointer to process SECURITY_ATTRIBUTES
+ ref sa, // pointer to thread SECURITY_ATTRIBUTES
+ false, // handles are not inheritable
+ dwCreationFlags, // creation flags
+ IntPtr.Zero, // pointer to new environment block
+ null, // name of current directory
+ ref si, // pointer to STARTUPINFO structure
+ out procInfo // receives information about new process
+ );
+
+
+ // invalidate the handles
+ CloseHandle(hProcess);
+ CloseHandle(hPToken);
+ CloseHandle(hUserTokenDup);
+
+
+ return result; // return the result
+ }
+ }
+}
--
Gitblit v1.10.0