- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
经过数周有关此主题的研究,我终于决定开始我自己的话题,希望有经验的人可以为您提供帮助。我搜寻了互联网,试图了解其中的各种编码示例,但是我试图将一个可行的解决方案整合在一起。让我从一些背景开始-
背景:
我有一个vb.net应用程序,该应用程序将使用CA IT客户端管理器(ITCM)交付给我组织中的Windows服务器和PC。与Microsoft SCCM一样,CA ITCM在每台PC上都具有作为SYSTEM运行的代理服务。因此,当我的应用程序在目标PC上交付并执行时,它正在“ NT Authority \ SYSTEM”上下文中运行。
问题:
在应用程序的初始阶段,在每个需要停止的登录用户的上下文中都有一个正在运行的进程。在我的应用程序执行结束时,我需要为每个登录用户重新启动此过程,以防止他们必须注销并重新启动。我要停止的进程实际上是一个系统托盘进程,用户可以在其桌面上与之交互。
追逐VB.NET解决方案:
不断地在Internet上进行研究,似乎没有针对每个问题的本机.NET解决方案,而没有每个登录用户的密码或提示用户输入一些凭据。由于这不是我的选择,因此我需要找到一种启动过程的方式,而不必知道或要求登录用户的凭据。
经过研究,我找到了Windows API函数CreateProcessAsUser。据我了解,我可以按照以下方式做一些事情(见下文)
笔记:
这是我第一次在VB.NET中使用非托管代码调用Windows API。当我将各种文章中的代码拼凑在一起时,关于常量,枚举和函数声明有很多歧义。如果您发现这些声明中的任何错误,请告诉我。关于何时需要将数据类型“封送”为其他类型,我有很多问题。请仔细阅读!!
由于有来自类似帖子的无数示例,因此我尝试遵循CreateProcessAsUser页面上的MSDN示例:
MSDN链接:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682429(v=vs.85).aspx
范例连结:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa379608(v=vs.85).aspx
除了查看每个Windows API调用的有效性之外,请查看操作的总体顺序,并让我知道我是否过于复杂或什至可能缺少某些内容。我没有从Microsoft示例中实现的唯一代码是允许每个SID完全访问交互式Windows工作站,然后允许SID完全访问交互式桌面。也许我错了,但我认为每个用户都应该已经可以访问其交互式桌面!
Public Class WindowsAPI
Private Const SE_CREATE_TOKEN_NAME As String = "SeCreateTokenPrivilege"
Private Const SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege"
Private Const SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege"
Private Const SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege"
Private Const SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege"
Private Const SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege"
Private Const SE_TCB_NAME = "SeTcbPrivilege"
Private Const SE_SECURITY_NAME = "SeSecurityPrivilege"
Private Const SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
Private Const SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege"
Private Const SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege"
Private Const SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege"
Private Const SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege"
Private Const SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege"
Private Const SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege"
Private Const SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege"
Private Const SE_BACKUP_NAME = "SeBackupPrivilege"
Private Const SE_RESTORE_NAME = "SeRestorePrivilege"
Private Const SE_SHUTDOWN_NAME = "SeShutdownPrivilege"
Private Const SE_DEBUG_NAME = "SeDebugPrivilege"
Private Const SE_AUDIT_NAME = "SeAuditPrivilege"
Private Const SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege"
Private Const SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
Private Const SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege"
Private Const SE_UNDOCK_NAME = "SeUndockPrivilege"
Private Const SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege"
Private Const SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege"
Private Const SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege"
Private Const SE_IMPERSONATE_NAME = "SeImpersonatePrivilege"
Private Const SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege"
Private Const SE_PRIVILEGE_ENABLED As Integer = &H2
Private Enum WindowShowStyle As UInteger
Hide = 0
ShowNormal = 1
ShowMinimized = 2
ShowMaximized = 3
Maximize = 3
ShowNormalNoActivate = 4
Show = 5
Minimize = 6
ShowMinNoActivate = 7
ShowNoActivate = 8
Restore = 9
ShowDefault = 10
ForceMinimized = 11
End Enum
Private Enum STARTF As Integer
STARTF_USESHOWWINDOW = &H1
STARTF_USESIZE = &H2
STARTF_USEPOSITION = &H4
STARTF_USECOUNTCHARS = &H8
STARTF_USEFILLATTRIBUTE = &H10
STARTF_RUNFULLSCREEN = &H20
STARTF_FORCEONFEEDBACK = &H40
STARTF_FORCEOFFFEEDBACK = &H80
STARTF_USESTDHANDLES = &H100
STARTF_USEHOTKEY = &H200
End Enum
Private Enum CreateProcessFlags
DEBUG_PROCESS = &H1
DEBUG_ONLY_THIS_PROCESS = &H2
CREATE_SUSPENDED = &H4
DETACHED_PROCESS = &H8
CREATE_NEW_CONSOLE = &H10
NORMAL_PRIORITY_CLASS = &H20
IDLE_PRIORITY_CLASS = &H40
HIGH_PRIORITY_CLASS = &H80
REALTIME_PRIORITY_CLASS = &H100
CREATE_NEW_PROCESS_GROUP = &H200
CREATE_UNICODE_ENVIRONMENT = &H400
CREATE_SEPARATE_WOW_VDM = &H800
CREATE_SHARED_WOW_VDM = &H1000
CREATE_FORCEDOS = &H2000
BELOW_NORMAL_PRIORITY_CLASS = &H4000
ABOVE_NORMAL_PRIORITY_CLASS = &H8000
INHERIT_PARENT_AFFINITY = &H10000
INHERIT_CALLER_PRIORITY = &H20000
CREATE_PROTECTED_PROCESS = &H40000
EXTENDED_STARTUPINFO_PRESENT = &H80000
PROCESS_MODE_BACKGROUND_BEGIN = &H100000
PROCESS_MODE_BACKGROUND_END = &H200000
CREATE_BREAKAWAY_FROM_JOB = &H1000000
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = &H2000000
CREATE_DEFAULT_ERROR_MODE = &H4000000
CREATE_NO_WINDOW = &H8000000
PROFILE_USER = &H10000000
PROFILE_KERNEL = &H20000000
PROFILE_SERVER = &H40000000
CREATE_IGNORE_SYSTEM_DEFAULT = &H80000000
End Enum
Private Enum ACCESS_MASK
DELETE = &H10000
READ_CONTROL = &H20000
WRITE_DAC = &H40000
WRITE_OWNER = &H80000
SYNCHRONIZE = &H100000
STANDARD_RIGHTS_REQUIRED = &HF0000
STANDARD_RIGHTS_READ = &H20000
STANDARD_RIGHTS_WRITE = &H20000
STANDARD_RIGHTS_EXECUTE = &H20000
STANDARD_RIGHTS_ALL = &H1F0000
SPECIFIC_RIGHTS_ALL = &HFFFF
ACCESS_SYSTEM_SECURITY = &H1000000
MAXIMUM_ALLOWED = &H2000000
GENERIC_READ = &H80000000
GENERIC_WRITE = &H40000000
GENERIC_EXECUTE = &H20000000
GENERIC_ALL = &H10000000
DESKTOP_READOBJECTS = &H1
DESKTOP_CREATEWINDOW = &H2
DESKTOP_CREATEMENU = &H4
DESKTOP_HOOKCONTROL = &H8
DESKTOP_JOURNALRECORD = &H10
DESKTOP_JOURNALPLAYBACK = &H20
DESKTOP_ENUMERATE = &H40
DESKTOP_WRITEOBJECTS = &H80
DESKTOP_SWITCHDESKTOP = &H100
WINSTA_ENUMDESKTOPS = &H1
WINSTA_READATTRIBUTES = &H2
WINSTA_ACCESSCLIPBOARD = &H4
WINSTA_CREATEDESKTOP = &H8
WINSTA_WRITEATTRIBUTES = &H10
WINSTA_ACCESSGLOBALATOMS = &H20
WINSTA_EXITWINDOWS = &H40
WINSTA_ENUMERATE = &H100
WINSTA_READSCREEN = &H200
WINSTA_ALL_ACCESS = &H37F
End Enum
<StructLayout(LayoutKind.Sequential)>
Private Structure PROCESS_INFORMATION
Public hProcess As IntPtr
Public hThread As IntPtr
Public dwProcessId As System.UInt32
Public dwThreadId As System.UInt32
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Structure SECURITY_ATTRIBUTES
Public nLength As System.UInt32
Public lpSecurityDescriptor As IntPtr
Public bInheritHandle As Boolean
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Structure STARTUPINFO
Public cb As System.UInt32
Public lpReserved As String
Public lpDesktop As String
Public lpTitle As String
Public dwX As System.UInt32
Public dwY As System.UInt32
Public dwXSize As System.UInt32
Public dwYSize As System.UInt32
Public dwXCountChars As System.UInt32
Public dwYCountChars As System.UInt32
Public dwFillAttribute As System.UInt32
Public dwFlags As System.UInt32
Public wShowWindow As Short
Public cbReserved2 As Short
Public lpReserved2 As IntPtr
Public hStdInput As IntPtr
Public hStdOutput As IntPtr
Public hStdError As IntPtr
End Structure
Private Enum SECURITY_IMPERSONATION_LEVEL
SecurityAnonymous = 0
SecurityIdentification = 1
SecurityImpersonation = 2
SecurityDelegation = 3
End Enum
Private Enum TOKEN_TYPE
TokenPrimary = 1
TokenImpersonation = 2
End Enum
Structure LUID
Public LowPart As UInt32
Public HighPart As Integer
End Structure
Structure TOKEN_PRIVILEGES
Public PrivilegeCount As Integer
Public TheLuid As LUID
Public Attributes As Integer
End Structure
Enum TOKEN_INFORMATION_CLASS
TokenUser = 1
TokenGroups
TokenPrivileges
TokenOwner
TokenPrimaryGroup
TokenDefaultDacl
TokenSource
TokenType
TokenImpersonationLevel
TokenStatistics
TokenRestrictedSids
TokenSessionId
TokenGroupsAndPrivileges
TokenSessionReference
TokenSandBoxInert
TokenAuditPolicy
TokenOrigin
TokenElevationType
TokenLinkedToken
TokenElevation
TokenHasRestrictions
TokenAccessInformation
TokenVirtualizationAllowed
TokenVirtualizationEnabled
TokenIntegrityLevel
TokenUIAccess
TokenMandatoryPolicy
TokenLogonSid
MaxTokenInfoClass
End Enum
<StructLayoutAttribute(LayoutKind.Sequential)>
Public Structure SECURITY_DESCRIPTOR
Public revision As Byte
Public size As Byte
Public control As Short
Public owner As IntPtr
Public group As IntPtr
Public sacl As IntPtr
Public dacl As IntPtr
End Structure
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function AdjustTokenPrivileges(ByVal TokenHandle As IntPtr,
ByVal DisableAllPrivileges As Boolean,
ByRef NewState As TOKEN_PRIVILEGES,
ByVal BufferLengthInBytes As UInt32,
ByRef PreviousState As TOKEN_PRIVILEGES,
ByRef ReturnLengthInBytes As UInt32) As Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function CreateProcessAsUser(ByVal hToken As IntPtr,
ByVal lpApplicationName As String,
ByVal lpCommandLine As String,
ByRef lpProcessAttributes As SECURITY_ATTRIBUTES,
ByRef lpThreadAttributes As SECURITY_ATTRIBUTES,
ByVal bInheritHandles As Boolean,
ByVal dwCreationFlags As UInteger,
ByVal lpEnvironment As IntPtr,
ByVal lpCurrentDirectory As String,
ByRef lpStartupInfo As STARTUPINFO,
ByRef lpProcessInformation As PROCESS_INFORMATION) As Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function DuplicateTokenEx(ByVal hExistingToken As IntPtr,
ByVal dwDesiredAccess As UInteger,
ByRef lpTokenAttributes As SECURITY_ATTRIBUTES,
ByVal ImpersonationLevel As SECURITY_IMPERSONATION_LEVEL,
ByVal TokenType As TOKEN_TYPE,
ByRef phNewToken As IntPtr) As Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function ImpersonateLoggedOnUser(ByVal hToken As IntPtr) As Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function OpenProcessToken(ByVal ProcessHandle As IntPtr,
ByVal DesiredAccess As Integer,
ByRef TokenHandle As IntPtr) As Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function RevertToSelf() As Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function CloseHandle(ByVal hObject As IntPtr) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function GetProcessWindowStation() As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function OpenDesktop(ByVal lpszDesktop As String,
ByVal dwFlags As Integer,
ByVal fInderit As Boolean,
ByVal dwDesiredAccess As Integer) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function OpenWindowStation(ByVal lpszWinSta As String,
ByVal fInherit As Boolean,
ByVal dwDesiredAccess As ACCESS_MASK) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function SetProcessWindowStation(ByVal hWinSta As IntPtr) As Boolean
End Function
Public Shared Function LaunchProcess(ByVal CmdLine As String) As Boolean
' Declare and initialize variables
Dim ExplorerProcesses As Process()
Dim UserTokenHandle As IntPtr
Dim PrimaryTokenHandle As IntPtr
Dim CurrentWinStationHandle As IntPtr
Dim InteractiveWinStationHandle As IntPtr
Dim InteractiveDesktopHandle As IntPtr
Dim StartupInfo As STARTUPINFO
Dim ProcessInfo As PROCESS_INFORMATION
' Get all explorer.exe IDs
ExplorerProcesses = Process.GetProcessesByName("explorer")
' Verify explorers were found
If ExplorerProcesses.Length = 0 Then
' Return
Return True
End If
' Iterate each explorer.exe process
For Each ExplorerProcess As Process In ExplorerProcesses
' Get the user token handle address (Query access level)
If OpenProcessToken(ExplorerProcess.Handle, TokenAccessLevels.MaximumAllowed, UserTokenHandle) = False Then
' Do some error handling
' Iterate the next process
Continue For
End If
' Get a primary token
If DuplicateTokenEx(UserTokenHandle,
TokenAccessLevels.MaximumAllowed,
Nothing,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenPrimary,
PrimaryTokenHandle) = False Then
' Do some error handling
' Iterate the next process
Continue For
End If
' Save a handle to the current window station
CurrentWinStationHandle = GetProcessWindowStation()
' Check for valid handle to the windows station
If CurrentWinStationHandle = IntPtr.Zero Then
' Do some error handling
' Iterate the next process
Continue For
End If
' Get a handle to the interactive window station
InteractiveWinStationHandle = OpenWindowStation("winsta0", False, ACCESS_MASK.READ_CONTROL Or ACCESS_MASK.WRITE_DAC)
' Check for a valid handle
If InteractiveWinStationHandle = Nothing Then
' Do some error handling
' Iterate the next user
Continue For
End If
' To get the correct default desktop, set the caller's window station to the interactive window station
If SetProcessWindowStation(InteractiveWinStationHandle) = False Then
' Do some error handling
' Iterate the next user
Continue For
End If
' Get handle to interactive desktop
InteractiveDesktopHandle = OpenDesktop("default",
0,
False,
ACCESS_MASK.READ_CONTROL Or
ACCESS_MASK.WRITE_DAC Or
ACCESS_MASK.DESKTOP_WRITEOBJECTS Or
ACCESS_MASK.DESKTOP_READOBJECTS)
' Restore the caller's window station
If SetProcessWindowStation(CurrentWinStationHandle) = False Then
' Do some error handling
' Iterate the next user
Continue For
End If
' Check for a valid handle
If InteractiveDesktopHandle = IntPtr.Zero Then
' Do some error handling
' Iterate the next user
Continue For
End If
' Initialize process and startup info
ProcessInfo = New PROCESS_INFORMATION
StartupInfo = New STARTUPINFO
StartupInfo.cb = Marshal.SizeOf(StartupInfo)
StartupInfo.lpDesktop = "winsta0\default"
' Impersonate client to ensure access to executable file
If ImpersonateLoggedOnUser(PrimaryTokenHandle) = False Then
' Do some error handling
' Iterate the next user
Continue For
End If
' Launch the process in the client's logon session
If CreateProcessAsUser(PrimaryTokenHandle,
Nothing,
CmdLine,
Nothing,
Nothing,
False,
CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT Or
CreateProcessFlags.NORMAL_PRIORITY_CLASS Or,
Nothing,
Nothing,
StartupInfo,
ProcessInfo) = False Then
' Do some error handling
' Iterate the next user
Continue For
End If
' End impersonation of client
If RevertToSelf() = False Then
' Do some error handling
' Iterate the next user
Continue For
End If
Next
' Check for open handle
If Not PrimaryTokenHandle = IntPtr.Zero Then
' Close the handle
CloseHandle(PrimaryTokenHandle)
End If
' Return
Return True
End Function
End Class
最佳答案
解决方案:
在发布完整的代码解决方案之前,我想分享如何找到答案。在重温有关CreateProcessAsUser API函数的MSDN文章之后,我意识到我需要验证我的进程是否真正拥有该文章提到的必需特权:
SE_INCREASE_QUOTA_NAME
SE_ASSIGNPRIMARYTOKEN_NAME
另外,本文未提及,但对于查找和调整令牌特权以启用上述特权的其他一些相关Windows API调用来说,可能至关重要的是:
SE_TCB_NAME
回想一下,我的应用程序是使用CA的IT客户端管理器(ITCM)软件交付的,以Windows Server和PC为目标。核心CA ITCM代理服务以“本地系统”身份登录,但其插件执行所有脏工作,并以SYSTEM帐户运行。显然,SYSTEM帐户和“本地系统”帐户之间存在巨大差异。
使用SysInternal的Process Explorer工具,我能够检查我的应用程序,发现它没有拥有所有必需的特权。自运行测试以来已经有一段时间了,所以我忘记了实际上没有持有哪个特权。
我最初犯的错误是编写非托管的Windows API函数调用以尝试启用丢失的特权,但不幸的是,这种方式不起作用。要么您的进程拥有特权,要么没有特权。如果它拥有特权,那么您唯一的责任就是确保启用特权。
为了克服这个问题,我不得不使用另一种方法。为了获得所需的特权,我的应用程序需要作为服务安装并执行,因此可以作为“本地系统”帐户运行。但是,仅将整个应用程序重新设计为可安装的服务,以满足这一简单要求是没有意义的。
相反,我创建了第二个VB.NET项目,这是我要发布的代码。第二个项目是一个简单的Windows服务,它带有启动参数。第一个启动参数是您要为每个登录用户启动的应用程序。在启动切换到您指定的应用程序时,将传递所有剩余的启动参数:-)
有了现在拥有适当特权并可以动态接收启动参数的服务,该服务可以为每个登录用户确切指定要启动的内容,我将生成的可执行文件嵌入了我的第一个项目。
我的第一个项目以SYSTEM帐户身份运行,它具有安装新系统服务的权利/许可/特权。它还有权启动该系统服务,并为系统中的每个登录用户传递启动启动托盘服务所需的参数。问题解决了!
这是我的Windows服务的代码-
LaunchService.vb:
'****************************** Class Header *******************************\
' Project Name: LaunchService
' Class Name: LaunchService
' File Name: LaunchService.vb
' Author: fonbr01
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
' IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
' OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
' ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
' OTHER DEALINGS IN THE SOFTWARE.
'***************************************************************************/
Public Class LaunchService
Protected Overrides Sub OnStart(ByVal args() As String)
' Local Variables
Dim AppName As String
' Get the application name
AppName = args(0)
args(0) = " "
' Check for additional arguments
If args.Length > 1 Then
' Shift the arguments
For i As Integer = 1 To args.Length - 1
' Swap the args
args(i - 1) = args(i)
Next
' Remove the last argument
args(args.Length - 1) = ""
End If
' Launch the App for all users
WindowsAPI.LaunchProcess(AppName, args)
End Sub
Protected Overrides Sub OnStop()
End Sub
End Class
'****************************** Class Header *******************************\
' Project Name: LaunchService
' Class Name: WindowsAPI
' File Name: WindowsAPI.vb
' Author: fonbr01
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
' IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
' OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
' ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
' OTHER DEALINGS IN THE SOFTWARE.
'***************************************************************************/
' Imports
Imports Microsoft.Win32.SafeHandles
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Diagnostics
' Windows API Class
Public Class WindowsAPI
' *************************
' * Windows API Functions
' *************************
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function AdjustTokenPrivileges(
<[In]()> ByVal TokenHandle As SafeTokenHandle,
<[In](), MarshalAs(UnmanagedType.Bool)> ByVal DisableAllPrivileges As Boolean,
<[In]()> ByRef NewState As TOKEN_PRIVILEGES,
<[In]()> ByVal BufferLengthInBytes As UInt32,
<Out()> ByRef PreviousState As TOKEN_PRIVILEGES,
<Out()> ByRef ReturnLengthInBytes As UInt32) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function CreateProcessAsUser(
<[In]()> ByVal hToken As SafeTokenHandle,
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpApplicationName As String,
<[In](), Out(), MarshalAs(UnmanagedType.LPWStr)> ByVal lpCommandLine As String,
<[In]()> ByRef lpProcessAttributes As SECURITY_ATTRIBUTES,
<[In]()> ByRef lpThreadAttributes As SECURITY_ATTRIBUTES,
<[In](), MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean,
<[In]()> ByVal dwCreationFlags As UInteger,
<[In]()> ByVal lpEnvironment As IntPtr,
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpCurrentDirectory As String,
<[In]()> ByRef lpStartupInfo As STARTUPINFO,
<Out()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function DuplicateToken(
<[In]()> ByVal ExistingTokenHandle As SafeTokenHandle,
<[In]()> ByVal ImpersonationLevel As SECURITY_IMPERSONATION_LEVEL,
<Out()> ByRef DuplicateTokenHandle As SafeTokenHandle) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function DuplicateTokenEx(
<[In]()> ByVal hExistingToken As IntPtr,
<[In]()> ByVal dwDesiredAccess As UInteger,
<[In]()> ByRef lpTokenAttributes As SECURITY_ATTRIBUTES,
<[In]()> ByVal ImpersonationLevel As SECURITY_IMPERSONATION_LEVEL,
<[In]()> ByVal TokenType As TOKEN_TYPE,
<Out()> ByRef phNewToken As SafeTokenHandle) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Private Shared Function LookupPrivilegeValue(
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpSystemName As String,
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpName As String,
<Out()> ByRef lpLuid As LUID) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function OpenProcessToken(
<[In]()> ByVal hProcess As IntPtr,
<[In]()> ByVal desiredAccess As UInt32,
<Out()> ByRef hToken As SafeTokenHandle) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' *************************
' * Structures
' *************************
<StructLayout(LayoutKind.Sequential)>
Private Structure PROCESS_INFORMATION
Public hProcess As IntPtr
Public hThread As IntPtr
Public dwProcessId As System.UInt32
Public dwThreadId As System.UInt32
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Structure SECURITY_ATTRIBUTES
Public nLength As System.UInt32
Public lpSecurityDescriptor As IntPtr
Public bInheritHandle As Boolean
End Structure
<StructLayout(LayoutKind.Sequential)>
Private Structure STARTUPINFO
Public cb As System.UInt32
Public lpReserved As String
Public lpDesktop As String
Public lpTitle As String
Public dwX As System.UInt32
Public dwY As System.UInt32
Public dwXSize As System.UInt32
Public dwYSize As System.UInt32
Public dwXCountChars As System.UInt32
Public dwYCountChars As System.UInt32
Public dwFillAttribute As System.UInt32
Public dwFlags As System.UInt32
Public wShowWindow As Short
Public cbReserved2 As Short
Public lpReserved2 As IntPtr
Public hStdInput As IntPtr
Public hStdOutput As IntPtr
Public hStdError As IntPtr
End Structure
Private Structure LUID
Public LowPart As UInt32
Public HighPart As Integer
End Structure
Private Structure LUID_AND_ATTRIBUTES
Public Luid As LUID
Public Attributes As Integer
End Structure
Private Structure TOKEN_PRIVILEGES
Public PrivilegeCount As UInt32
<MarshalAs(UnmanagedType.ByValArray)> Public Privileges() As LUID_AND_ATTRIBUTES
End Structure
' ******************************
' * Enumerations
' ******************************
Private Enum CreateProcessFlags
DEBUG_PROCESS = &H1
DEBUG_ONLY_THIS_PROCESS = &H2
CREATE_SUSPENDED = &H4
DETACHED_PROCESS = &H8
CREATE_NEW_CONSOLE = &H10
NORMAL_PRIORITY_CLASS = &H20
IDLE_PRIORITY_CLASS = &H40
HIGH_PRIORITY_CLASS = &H80
REALTIME_PRIORITY_CLASS = &H100
CREATE_NEW_PROCESS_GROUP = &H200
CREATE_UNICODE_ENVIRONMENT = &H400
CREATE_SEPARATE_WOW_VDM = &H800
CREATE_SHARED_WOW_VDM = &H1000
CREATE_FORCEDOS = &H2000
BELOW_NORMAL_PRIORITY_CLASS = &H4000
ABOVE_NORMAL_PRIORITY_CLASS = &H8000
INHERIT_PARENT_AFFINITY = &H10000
INHERIT_CALLER_PRIORITY = &H20000
CREATE_PROTECTED_PROCESS = &H40000
EXTENDED_STARTUPINFO_PRESENT = &H80000
PROCESS_MODE_BACKGROUND_BEGIN = &H100000
PROCESS_MODE_BACKGROUND_END = &H200000
CREATE_BREAKAWAY_FROM_JOB = &H1000000
CREATE_PRESERVE_CODE_AUTHZ_LEVEL = &H2000000
CREATE_DEFAULT_ERROR_MODE = &H4000000
CREATE_NO_WINDOW = &H8000000
PROFILE_USER = &H10000000
PROFILE_KERNEL = &H20000000
PROFILE_SERVER = &H40000000
CREATE_IGNORE_SYSTEM_DEFAULT = &H80000000
End Enum
Private Enum SECURITY_IMPERSONATION_LEVEL
SecurityAnonymous = 0
SecurityIdentification
SecurityImpersonation
SecurityDelegation
End Enum
Private Enum TOKEN_TYPE
TokenPrimary = 1
TokenImpersonation = 2
End Enum
' ******************************
' * Constants
' ******************************
Private Const SE_ASSIGNPRIMARYTOKEN_NAME As String = "SeAssignPrimaryTokenPrivilege"
Private Const SE_INCREASE_QUOTA_NAME As String = "SeIncreaseQuotaPrivilege"
Private Const SE_TCB_NAME As String = "SeTcbPrivilege"
Private Const SE_PRIVILEGE_ENABLED As UInt32 = &H2
' ******************************
' * Safe Token Handle Class
' ******************************
Private Class SafeTokenHandle
Inherits SafeHandleZeroOrMinusOneIsInvalid
Private Sub New()
MyBase.New(True)
End Sub
Friend Sub New(ByVal handle As IntPtr)
MyBase.New(True)
MyBase.SetHandle(handle)
End Sub
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
Friend Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean
End Function
Protected Overrides Function ReleaseHandle() As Boolean
Return SafeTokenHandle.CloseHandle(MyBase.handle)
End Function
End Class
' ******************************
' * Increase Privileges Function
' ******************************
Public Shared Function IncreasePrivileges() As Boolean
' Local variables
Dim hToken As SafeTokenHandle = Nothing
Dim luid As LUID
Dim NewState As TOKEN_PRIVILEGES
NewState.PrivilegeCount = 1
ReDim NewState.Privileges(0)
' Get current process token
If OpenProcessToken(Diagnostics.Process.GetCurrentProcess.Handle, TokenAccessLevels.MaximumAllowed, hToken) = False Then
' Write debug
WriteEvent("Error: Windows API OpenProcessToken function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Lookup SeIncreaseQuotaPrivilege
If Not LookupPrivilegeValue(Nothing, SE_INCREASE_QUOTA_NAME, luid) Then
' Write debug
WriteEvent("Error: Windows API LookupPrivilegeValue function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Enable SeIncreaseQuotaPrivilege
NewState.Privileges(0).Luid = luid
NewState.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
' Adjust the token privileges
If Not AdjustTokenPrivileges(hToken, False, NewState, Marshal.SizeOf(NewState), Nothing, Nothing) Then
' Write debug
WriteEvent("Error: Windows API AdjustTokenPrivileges function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Lookup SeAssignPrimaryTokenPrivilege
If Not LookupPrivilegeValue(Nothing, SE_ASSIGNPRIMARYTOKEN_NAME, luid) Then
' Write debug
WriteEvent("Error: Windows API LookupPrivilegeValue function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Enable SeAssignPrimaryTokenPrivilege
NewState.Privileges(0).Luid = luid
NewState.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
' Adjust the token privileges
If Not AdjustTokenPrivileges(hToken, False, NewState, Marshal.SizeOf(NewState), Nothing, Nothing) Then
' Write debug
WriteEvent("Error: Windows API AdjustTokenPrivileges function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Lookup SeTcbPrivilege
If Not LookupPrivilegeValue(Nothing, SE_TCB_NAME, luid) Then
' Write debug
WriteEvent("Error: Windows API LookupPrivilegeValue function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Enable SeTcbPrivilege
NewState.Privileges(0).Luid = luid
NewState.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED
' Adjust the token privileges
If Not AdjustTokenPrivileges(hToken, False, NewState, Marshal.SizeOf(NewState), Nothing, Nothing) Then
' Write debug
WriteEvent("Error: Windows API AdjustTokenPrivileges function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Return
Return False
End If
' Return
Return True
End Function
' ******************************
' * Launch Process Sub
' ******************************
Public Shared Sub LaunchProcess(ByVal CmdLine As String, ByVal args As String())
' Local variables
Dim Arguments As String = ""
Dim ExplorerProcesses As Process()
Dim hToken As SafeTokenHandle = Nothing
Dim principle As WindowsIdentity
Dim phNewToken As SafeTokenHandle = Nothing
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
' Process arguments
For Each arg As String In args
' Build argument string
Arguments += " " + arg
Next
' Increase Privileges
If IncreasePrivileges() = False Then
' Write debug
WriteEvent("Warning: Failed to increase current process privileges.", EventLogEntryType.Warning)
End If
' Get all explorer.exe IDs
ExplorerProcesses = Process.GetProcessesByName("explorer")
' Verify explorers were found
If ExplorerProcesses.Length = 0 Then
' Write debug
WriteEvent("Warning: No explorer.exe processes found.", EventLogEntryType.Warning)
' Return
Exit Sub
End If
' Iterate each explorer.exe process
For Each hProcess As Process In ExplorerProcesses
' Get the user token handle
If OpenProcessToken(hProcess.Handle, TokenAccessLevels.MaximumAllowed, hToken) = False Then
' Write debug
WriteEvent("Error: Windows API OpenProcessToken function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Iterate the next process
Continue For
End If
' Get the windows identity
principle = New WindowsIdentity(hToken.DangerousGetHandle)
' Get a primary token
If Not DuplicateTokenEx(hToken.DangerousGetHandle,
TokenAccessLevels.MaximumAllowed,
Nothing,
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
TOKEN_TYPE.TokenPrimary,
phNewToken) Then
' Write debug
WriteEvent("Error: Windows API DuplicateTokenEx function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
' Iterate the next process
Continue For
End If
' Initialize process and startup info
pi = New PROCESS_INFORMATION
si = New STARTUPINFO
si.cb = Marshal.SizeOf(si)
si.lpDesktop = Nothing
' Launch the process in the client's logon session
If Not CreateProcessAsUser(phNewToken,
Nothing,
CmdLine + Arguments,
Nothing,
Nothing,
False,
CreateProcessFlags.CREATE_UNICODE_ENVIRONMENT,
Nothing,
Nothing,
si,
pi) Then
' Write debug
WriteEvent("Error: Windows API CreateProcessAsUser function returns an error." + Environment.NewLine +
"Windows API error code: " + Marshal.GetLastWin32Error.ToString, EventLogEntryType.Error)
Else
' Write debug
WriteEvent("Created new user process: " + Environment.NewLine +
"User: " + principle.Name + Environment.NewLine +
"Process: " + CmdLine + Arguments + Environment.NewLine +
"PID: " + pi.dwProcessId.ToString, EventLogEntryType.Information)
End If
' Free resources
hToken.Close()
hToken = Nothing
phNewToken.Close()
phNewToken = Nothing
principle = Nothing
pi = Nothing
si = Nothing
Next
End Sub
' ******************************
' * Write Event Log Sub
' ******************************
Public Shared Sub WriteEvent(EventMessage As String, EntryType As EventLogEntryType)
' Check if event source exists
If Not EventLog.SourceExists("WinOffline Launch Service") Then
' Create the event source
EventLog.CreateEventSource("WinOffline Launch Service", "System")
End If
' Write the message
EventLog.WriteEntry("WinOffline Launch Service", EventMessage, EntryType)
End Sub
End Class
sc create <ServiceName> binpath= <Full Path to Service Executable> start= demand
sc start <ServiceName> <Full Path to App to Launch for all Users> <Parameters>
sc stop <ServiceName>
sc delete <ServiceName>
关于vb.net - 使用以SYSTEM身份运行的vb.net应用程序,如何为每个登录用户启动分离的进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14188988/
我在尝试使用 jpa2.0 将包含持久实体和分离实体(新创建的实体)的实体列表更新到我的数据库中时遇到错误。 我的实体包含在合并数据时出现错误(在标题中提到)的内部实体: Class supercla
我在分层 Pane 中有一组面板。我需要一个分隔符来将 sideBar 与 topBar 和 tabbedPanel 分开。我留了一个 10 像素的缓冲区来放置它。不幸的是,可能由于它是 JLayer
在我从数据库中读取的代码中,我还使用自定义适配器打印出每一行,该行中有一个 texttview、2 个按钮和一个 edittext。这一切都很好,但是当按下按钮时,edittext 会递增或递减,有没
我有一个由 Hibernate 4.3.4 管理的实体,它有一个其他实体的一对多集合。 在我的处理过程中,我必须分离父实体(将分离级联到子列表)。但是,当我向列表中添加一个尚未持久化的新项目并执行分离
我想追加一行,该行应该是表格的最后一行。在我的代码中,它似乎在第一次动态添加行时起作用。但是当添加其他行时它不会成为最后一行。 我总是希望“subtot”行成为最后一行,但是当我追加其他行时,它不
我试图用它们之间的空格分隔这 2 个 div(请参见图 1)。问题是当我添加边距或填充时会发生这种情况(请参见图 2)。 这是我的代码,请注意我没有使用 Bootstrap: .row { mar
我的服务器包含一些 ServerActor。该 actor 接收 RegisterClient 消息并将 ActorRefs 添加到已注册客户端列表中。 我还有多个客户端,每个客户端都包含 Clien
假设我有一个需要两个参数的函数,并且参数的顺序会影响结果。 是否可以将第一个参数传递给 partial 或 comp 函数,然后将另一个参数传递给它,如下所示: (defn bar [arg1 arg
如何搜索和分离多个后代键。 例子: (def d {:foo 123 :bar { :baz 456 :bam { :w
我正在尝试为 Slick 表创建一个类型安全的动态 DSL,但不确定如何实现这一点。 用户可以通过以 form/json 格式发送过滤器来将过滤器发布到服务器,我需要使用所有这些来构建一个 Slick
我是新来的,我发现看到充满大量函数和变量初始化以及 UI 的组件时眼睛很痛。是否可以将它们分开? 而不是默认设置,如下所示。如何将业务逻辑分离到另一个文件中? function MyComponent
我试图通过将参数粘贴在一起来使用分离。这应该是一件容易的工作,但不适合我。当我想到使用 eval(parse()) 时,我知道是时候寻求帮助了 通常,如果我加载一个包,我可以按如下方式分离它: det
(dissoc :a m)允许我解除给定的键。但是,有没有办法使用谓词函数来分离 pred 为真的任何键? (dissoc-with-pred pred? m) 所以给了一张 map - {:a 2
我编写了一个使用 devtools 来包含内部数据的包: devtools::use_data(.data, internal = T, overwrite = T) 我最近更改了该数据并重建了包。我
所以我有一个脚本,我想在我的服务器上运行它而不会打扰我。所以我想我会在 tmux 窗口中运行服务器,然后 detach这样我就可以简单地 attach如果我想查看进度(此脚本需要数天才能运行)。 但是
ThreeJS中动画数据和模型数据是否可以解耦? 这样就可以交换模型并保留动画?我认为这可能非常强大 我知道如何在 ThreeJS 中做到这一点的方法是将每个动画一个接一个地打包在一个模型中,这似乎是
我有一堆(Ruby)脚本存储在服务器上。到目前为止,我的团队通过打开一个启动脚本名称列表的访问器应用程序来使用它们,然后他们在工作文件夹中的文件上选择要在该实例中运行的脚本。脚本直接从服务器运行,因此
我想知道 javascript 如何包含在 jsp 中 - 我们是否可以在 .js 文件中放置 jsp 能够识别的任何代码,而不仅仅是 javascript 代码? 我有一些常见的 JavaScrip
您是否可以在 Dockerfile 中指定一个选项,默认使用它构建的容器以分离方式运行。 这将导致与 -d 相同的结果: docker run -d 这样 docker run 默认情况下会分离运
我正在为现有的 Java 程序开发 Java 插件。现有程序使用特定版本的 eclipse.uml2.*,我的插件也是如此。不幸的是,我的插件需要更新版本。 为了运行该插件,我需要将其导出到 Jar
我是一名优秀的程序员,十分优秀!