gpt4 book ai didi

.net - 如何从 Windows 服务锁定工作站?

转载 作者:行者123 更新时间:2023-12-03 15:53:25 28 4
gpt4 key购买 nike

我需要从用 VB.Net 编写的 Windows 服务中锁定工作站。我正在 Windows 7 上编写应用程序,但它也需要在 Vista 和 XP 下工作。

User32 API LockWorkStation 不起作用,因为它需要交互式桌面,我得到的返回值为 0。

我尝试从 Process 和 Shell 调用 %windir%\System32\rundll32.exe user32.dll,LockWorkStation,但仍然没有任何 react 。

将服务设置为与桌面交互是行不通的,因为我在管理员帐户下运行该服务,因此它可以执行一些需要管理员权限的其他操作 - 例如禁用网络,并且您只能选择与桌面交互选项如果在本地系统帐户下运行。

那将是次要问题-如何从在本地系统帐户下运行的服务运行具有管理员权限的另一个应用程序,而不会打扰用户。

我正在编写一个应用程序来控制我的 child 的计算机/互联网访问(我计划在完成后开源),所以我需要一切都尽可能悄悄地发生。

我有一个 UI 可以处理任务栏中的设置和状态通知,但这很容易杀死并因此破坏锁定。我可以制作另一个隐藏的 Windows 窗体应用程序来处理锁定,但这似乎是一个相当不雅的解决方案。

有更好的想法吗?

最佳答案

我一直在与这个问题作斗争一个多星期,在阅读了很多关于这个问题的信息之后,终于找到了解决方案......

您必须像这样使用 CreateProcessAsUser 函数:

  Private Shared Sub Executer(ByVal content As String)
Dim objProcess As System.Diagnostics.Process

Dim filename As String
filename = "e:\lock.bat"
'create a bat file with ''rundll32.exe user32.dll,LockWorkStation'' inside

Dim UserTokenHandle As IntPtr = IntPtr.Zero
WindowsApi.WTSQueryUserToken(WindowsApi.WTSGetActiveConsoleSessionId, UserTokenHandle)

Dim ProcInfo As New WindowsApi.PROCESS_INFORMATION
Dim StartInfo As New WindowsApi.STARTUPINFOW
StartInfo.cb = CUInt(Marshal.SizeOf(StartInfo))

WindowsApi.CreateProcessAsUser(UserTokenHandle, filename, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)
If Not UserTokenHandle = IntPtr.Zero Then
WindowsApi.CloseHandle(UserTokenHandle)
End If

End Sub

大部分代码来自 here您还可以在哪里找到与此功能一起使用的 WindowsApi。
我仍在尝试寻找是否可以避免使用 bat 文件,但至少是一个非常不错的解决方案。

编辑:
为避免使用外部 *.bat 文件来执行代码,只需编辑 WindowsApi 类并将 CreateProcessAsUser 和 advapi32.dll 导入部分替换为:
    <DllImport("Advapi32.dll", EntryPoint:="CreateProcessAsUser", ExactSpelling:=False,      SetLastError:=True, CharSet:=CharSet.Unicode)> _
Public Shared Function CreateProcessAsUser( _
ByVal hToken As IntPtr, _
ByVal lpApplicationName As String, _
<[In](), Out(), [Optional]()> ByVal lpCommandLine As StringBuilder, _
ByVal lpProcessAttributes As IntPtr, _
ByVal lpThreadAttributes As IntPtr, _
<MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean, _
ByVal dwCreationFlags As Integer, _
ByVal lpEnvironment As IntPtr, _
ByVal lpCurrentDirectory As String, _
<[In]()> ByRef lpStartupInfo As STARTUPINFOW, _
<Out()> ByRef lpProcessInformation As PROCESS_INFORMATION) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

现在您可以使用字符串构建器作为 CreateProcessAsUser 函数的第三个参数(命令行),并将第二个(应用程序名称)设置为“Nothing”,如下所示:
Dim cmdline As New StringBuilder
cmdline.Append("rundll32.exe user32.dll,LockWorkStation")
WindowsApi.CreateProcessAsUser(UserTokenHandle, Nothing, cmdline, IntPtr.Zero, IntPtr.Zero, False, 0, IntPtr.Zero, Nothing, StartInfo, ProcInfo)

它会起作用的!!!!

问候,
美联社

关于.net - 如何从 Windows 服务锁定工作站?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2466606/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com