以编程方式确定锁定工作站的持续时间?如何在代码中确定机器何时被锁定?欢迎使用C#之外的其他想法。我喜欢Windows服务的想法(并接受了它),因为它简单干净,但不幸的是,我认为在这种特殊情况下它对我不起作用。我想在我的工作站上运行它而不是在家里(或者我想除了在家里),但它受到mod的严格控制。事实上,这就是我自己动手的部分原因。无论如何我都会写下来看看它是否有效。谢谢大家!我以前没有发现这个,但是从任何应用程序都可以连接SessionSwitchEventHandler。显然你的应用程序需要运行,但只要它是:Microsoft.Win32.SystemEvents.SessionSwitch+=newMicrosoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);voidSystemEvents_SessionSwitch(objectsender,Microsoft.Win32.SessionSwitchEventArgse){if(e.Reason==SessionSwitchReason.SessionLock){//我离开了办公桌}elseif(e.Reason==SessionSwitchReason.SessionUnlock){//我回来了到我的办公桌}}我将创建一个处理OnSessionChange事件(visualstudio2005项目类型)的Windows服务,如下所示:我离开了我的办公桌}elseif(changeDescription.Reason==SessionChangeReason.SessionUnlock){//我回到了我的办公桌}}此时您记录什么以及如何记录活动由您决定,但Windows服务提供了快速轻松的访问权限Windows事件,例如启动、关闭、登录/注销以及锁定和解锁事件。下面的解决方案使用Win32API。工作站锁定时调用OnSessionLock,解锁时调用OnSessionUnlock。[DllImport("wtsapi32.dll")]privatestaticexternboolWTSRegisterSessionNotification(IntPtrhWnd,intdwFlags);[DllImport("wtsapi32.dll")]privatestaticexternboolWTSUnRegisterSessionNotification(IntPtrhWnd);私人常量intNotifyForThisSession=0;//这个会话只有privateconstintSessionChangeMes??sage=0x02B1;私有常量intSessionLockParam=0x7;私有常量intSessionUnlockParam=0x8;protectedoverridevoidWndProc(refMessagem){//检查会话更改通知if(m.Msg==SessionChangeMes??sage){if(m.WParam.ToInt32()==SessionLockParam)OnSessionLock();//锁定时做一些事情elseif(m.WParam.ToInt32()==SessionUnlockParam)OnSessionUnlock();//解锁时做一些事情}base.WndProc(refm);返回;}voidOnSessionLock(){Debug.WriteLine("Locked...");}voidOnSessionUnlock(){Debug.WriteLine("Unlocked...");}privatevoidForm1Load(objectsender,EventArgse){WTSRegisterSessionNotifica化(this.Handle,NotifyForThisSession);}//然后当我们完成后,我们应该注销通知//WTSUnRegisterSessionNotification(this.Handle);我知道这是一个老问题,但我找到了一种方法来获得我在这里找到的答案,但它是在C++中,所以我尽可能多地翻译成C#以获得锁定状态。所以这里是:staticclassSessionInfo{privateconstInt32FALSE=0;privatestaticreadonlyIntPtrWTS_CURRENT_SERVER=IntPtr.Zero;私人常量Int32WTS_SESSIONSTATE_LOCK=0;私人常量Int32WTS_SESSIONSTATE_UNLOCK=1;私有静态布尔_is_win7=false;静态SessionInfo(){varos_version=Environment.OSVersion;_is_win7=(os_version.Platform==PlatformID.Win32NT&&os_version.Version.Major==6&&os_version.Version.Minor==1);}[DllImport("wtsapi32.dll")]privatestaticexternInt32WTSQuerySessionInformation(IntPtrhServer,[MarshalAs(UnmanagedType.U4)]UInt32SessionId,[MarshalAs(UnmanagedType.U4)]WTS_INFO_CLASSWTSInfoClass,出IntPtrppBuffer,[MarshalAs(UnmanagedType).U4)]输出UInt32pBytesReturned);[DllImport("wtsapi32.dll")]privatestaticexternvoidWTSFreeMemoryEx(WTS_TYPE_CLASSWTSTypeClass,IntPtrpMemory,UInt32NumberOfEntries);私人枚举WTS_INFO_CLASS{WTSInitialProgram=0,WTSApplicationName=1,WTSWorkingDirectory=2,WTSOEMId=3,WTSSessionId=4,WTSUserName=5,WTSWinStationName=6,WTSDomainName=7,WTSConnectState=8,WTSClientBuildNumber=9,WTSClientName=10,WTSClientDirectory=11,WTSClientProductId=12,WTSClientHardwareId=13、WTSClientAddress=14、WTSClientDisplay=15、WTSClientProtocolType=16、WTSIdleTime=17、WTSLogonTime=18、WTSIncomingBytes=19、WTSOutgoingBytes=20、WTSIncomingFrames=21、WTSOutgoingFrames=22、WTSClientInfo=23、WTSSession2、ExtInfo=23、WTSSession2、ExtInfo=23WTSConfigInfo=26,WTSValidationInfo=27,WTSSessionAddressV4=28,WTSIsRemoteSession=29}privateenumWTS_TYPE_CLASS{WTSTypeProcessInfoLevel0,WTSTypeProcessInfoLevel1,WTSTypeSessionInfoLevel1}publicenumWTS_CONNECTSTATE_CLASS{WTSActive,WTSConnected,WTSConnectQuery,WTSShadow,WTSDisconnected,WTSIdle,WTSListen,WTSReset,WTSDown,WTSInit}publicenumLockState{Unknown,Locked,Unlocked}[StructLayout(LayoutKind.Sequential)]privatestructWTSINFOEX{publicUInt32Level;公共UInt32保留;/*我观察到数据字段被向下推了4个字节,所以我添加了这个字段作为填充。*/publicWTSINFOEX_LEVEL数据;}[StructLayout(LayoutKind.Sequential)]privatestructWTSINFOEX_LEVEL{publicWTSINFOEX_LEVEL1WTSInfoExLevel1;}[StructLayout(LayoutKind.Sequential)]privatestructWTSINFOEX_LEVEL1{publicUInt32SessionId;公共WTS_CONNECTSTATE_CLASS会话状态;公共Int32会话标志;/*我不知道该结构的其余部分应该是什么样子,但因为我不需要SessionFlags以外的任何东西,所以我不会去。*/}publicstaticLockStateGetSessionLockState(UInt32session_id){IntPtrppBuffer;UInt32pBytesReturned;Int32结果=WTSQuerySessionInformation(WTS_CURRENT_SERVER,session_id,WTS_INFO_CLASS.WTSSessionInfoEx,outppBuffer,outpBytesReturned);如果(结果==FALSE)返回LockState.Unknown;瓦瑟ssion_info_ex=Marshal.PtrToStructure(ppBuffer);如果(session_info_ex.Level!=1)返回LockState.Unknown;varlock_state=session_info_ex.Data.WTSInfoExLevel1.SessionFlags;WTSFreeMemoryEx(WTS_TYPE_CLASS.WTSTypeSessionInfoLevel1,ppBuffer,pBytesReturned);if(_is_win7){/*Ref:https://msdn.microsoft.com/en-us/library/windows/desktop/ee621019(v=vs.85).aspx*WindowsServer2008R2和Windows7:由于代码缺陷,WTS_SESSIONSTATE_LOCK*和WTS_SESSIONSTATE_UNLOCK标志的用法被颠倒了。即WTS_SESSIONSTATE_LOCK表示会话解锁,WTS_SESSIONSTATE_UNLOCK表示会话锁定。**/switch(lock_state){caseWTS_SESSIONSTATE_LOCK:returnLockState.Unlocked;案例WTS_SESSIONSTATE_UNLOCK:返回LockState.Locked;默认值:返回LockState.Unknown;}}else{switch(lock_state){caseWTS_SESSIONSTATE_LOCK:returnLockState.Locked;案例WTS_SESSIONSTATE_UNLOCK:返回LockState.Unlocked;默认值:返回LockState.Unknown;注意:上面的代码是从一个更大的项目中提取的,很抱歉,如果我漏掉了一点,我没有时间测试上面的代码,但计划在一两个星期内回来做检查一切。我现在才发布它,因为我不想忘记这样做。注意:这不是答案,而是对TimothyCarter的回答(贡献),因为到目前为止我的声誉不允许我发表评论。以防万一有人尝试使用TimothyCarter的答案中的代码并且没有立即在Windows服务中使用它,需要在服务的构造函数中将一个属性设置为true。只需在构造函数中添加这一行:CanHandleSessionChangeEvent=true;并确保在服务启动后不要设置此属性,否则将抛出InvalidOperationException。如果您有兴趣编写一个Windows服务来“查找”这些事件,topshelf(使编写Windows服务更容易的库/框架)有一个钩子。公共接口IMyServiceContract{voidStart();无效停止();voidSessionChanged(Topshelf.SessionChangedArgumentsargs);}publicclassMyService:IMyServiceContract{publicvoidStart(){}publicvoidStop(){}publicvoidSessionChanged(SessionChangedArguments){Console.WriteLine(e.ReasonCode);现在是时候将topshelf服务连接到上面的接口/特定代码下面的所有内容都是“典型的”topshelf设置....除了我标记的2行/*Thisisthemagicline*/这些是东西获取SessionChanged方法。我用Windows10x64测试了这个。我锁定并解锁了我的机器,我得到了想要的结果。IMyServiceContractmyServiceObject=newMyService();/*容器.Resolve();*/HostFactory.Run(x=>{x.Service(s=>{s.ConstructUsing(name=>myServiceObject);s.WhenStarted(sw=>sw.Start());s.WhenStopped(sw=>sw.Stop());s.WhenSessionChanged((csm,hc,chg)=>csm.SessionChanged(chg));/*这是魔法线*/});x.EnableSessionChanged();/*这是魔法线*//*为下面注释掉的属性使用命令行变量*//*x.RunAsLocalService();x.SetDescription("MyDescription");x.SetDisplayName("MyDisplayName");x.SetServiceName("MyServiceName");x.SetInstanceName("MyInstance");*/x.StartManually();//手动启动服务。这允许在服务实际启动之前调整身份/*下面映射到控制面板中Windows服务属性的“恢复”选项卡*/x.EnableServiceRecovery(r=>{r.OnCrashOnly();r.RestartService(1);////首先r.RestartService(1);////第二个r.Re启动服务(1);////后续r.SetResetPeriod(0);});x.DependsOnEventLog();//Windows事件日志x.UseLog4Net();x.EnableShutdown();x.OnException(ex=>{/*记录异常*//*没看到,我这里有一个log4net记录器*/});});我的packages.config给出了关于版本的提示:下面是找到PC的100%工作代码在使用前被锁定,使用命名空间System.Runtime.InteropServices。以上就是C#学习教程:编程确定工作站被锁定的持续时间?分享的所有内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注——[DllImport("user32",EntryPoint="OpenDesktopA",CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]privatestaticexternInt32OpenDesktop(stringlpszDesktop,Int32dwFlags,boolfInherit,Int32dwDesiredAccess);[DllImport("user32",CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]privatestaticDesktopInt32Close(Int32hDesktop);[DllImport("user32",CharSet=CharSet.Ansi,SetLastError=true,ExactSpelling=true)]privatestaticexternInt32SwitchDesktop(Int32hDesktop);publicstaticboolIsWorkstationLocked(){constintDESKTOP_SWITCHDESKTOP=25inthwnd=-1;intrtn=-1;hwnd=OpenDesktop("默认",0,false,DESKTOP_SWITCHDESKTOP);如果(hwnd!=0){rtn=SwitchDesktop(hwnd);if(rtn==0){//锁定CloseDesktop(hwnd);返回真;}else{//未锁定CloseDesktop(hwnd);}}else{//错误:“无法访问essthedesktop..."}returnfalse;}本文采集自网络,不代表立场,如涉及侵权,请点击右下角联系管理员删除,如有转载请告知注明出处:
