手机版

asp.net中穿透会话0隔离(二)

时间:2021-10-07 来源:互联网 编辑:宝哥软件园 浏览:

对于简单的交互,服务可以通过WTSSendMessage函数,在用户会议上显示消息窗口。对于一些复杂的用户界面交互,必须调用CreateProcessAsUser或其他方法(WCF .网远程处理等)进行跨会议通信,在桌面用户上创建一个应用程序界面WTSSendMessage。函数如果服务只是简单的向桌面用户会议发送消息窗口,则可以使用WTSSendMessage函数实现。首先,在上一篇下载的代码中加入一个Interop.cs类,并在类中加入如下代码:复制代码代码如下:公共静态IntPtr WTS _ CURRENT _ SERVER _ HANDLE=IntPtr .零;公共静态void ShowMessageBox(字符串消息,字符串标题){ int resp=0;WTSSendMessage(WTS _ CURRENT _ SERVER _ HANDLE,WTSGetActiveConsoleSessionId(),标题,标题.长度,信息,信息。长度,0,0,out resp,false);} [DllImport('kernel32.dll ',SetLastError=true)]公共静态extern int wtsgetaactiveconsolessionid();[DllImport('wtsapi32.dll ',SetLastError=true)]公共静态外部bool WTSSendMessage(int ptr hServer,int SessionId,String pTitle,int TitleLength,String pMessage,int MessageLength,int Style,int Timeout,out int pResponse,bool bWait);在显示消息框函数中调用了WTSSendMessage来发送信息窗口,这样我们就可以在服务的OnStart函数中使用,打开Service1.cs加入下面代码:复制代码代码如下:受保护的覆盖无效OnStart(字符串[]参数){ Interop .显示消息框(这是警报服务的消息)、"警报服务消息");} 编译程序后在服务管理器中重新启动警报服务服务,从下图中可以看到消息窗口是在当前用户桌面显示的,而不是会话0中

createprocesssuser函数如果想通过服务为桌面用户Session创建一个复杂的UI程序界面,则需要使用createprocesssuser函数为用户创建一个新的进程来运行相应的程序。

打开互操作类继续添加下面代码:复制代码代码如下:公共静态void CreateProcess(字符串app,字符串路径){ bool resultIntPtr hToken=WindowsIdentity .GetCurrent().代币;IntPtr hDupedToken=IntPtr .零;PROCESS _ INFORMATION pi=new PROCESS _ INFORMATION();SECURITy _ ATTRIBUTS sa=new SECURITy _ ATTRIBUTS();sa .长度=元帅SizeOf(sa);STARTUPINFO si=new STARTUPINFO();si.cb=元帅SizeOf(si);int dwsession id=wtsgetaactiveconsolessionid();result=WTSQueryUserToken(dwSessionID,out hToken);if(!结果){ ShowMessageBox(' wtsqueryusettken失败、“警报服务消息”);} result=replicatetokenex(HToken,GENERIC_ALL_ACCESS,ref sa,(int)SECURITy _ ASPENSION _ LEVEL .SecurityIdentification,(int)TOKEN_TYPE .TokenPrimary,ref hDupedToken);if(!结果){ ShowMessageBox(' replicatetokenex失败、“警报服务消息”);} IntPtr lpEnvironment=IntPtr .零;结果=CreateEnvironmentBlock(out lpEnvironment,hDupedToken,false);if(!结果){ ShowMessageBox(' CreateEnvironmentBlock失败、“警报服务消息”);}结果=createprocesssuser(HDupedToken,app,String .空,参考sa,参考sa,假,0,IntPtr .零点、路径、参考si、参考pi);if(!结果){ int error=Marshal .getlastwin 32错误();字符串消息=字符串。格式(“createprocesssuser错误: { 0 }”,错误);显示消息框(消息,"警报服务消息");} if(pi。hpprocess!=IntPtr .零)CloseHandle(pi。HP process);if (pi.hThread!=IntPtr .零)CloseHandle(pi。hth read);if (hDupedToken!=IntPtr .零)CloseHandle(hDupedToken);}[结构布局(布局种类.顺序的)]公共结构STARTUPINFO { public Int32 cb公共字符串lpReserved公共字符串lpDesktop公共字符串lptitle public int 32 dwxppublic int 32 dwyppublic int 32 dwXSizepublic int 32 dwxcountcharsppublic int 32 dwycountcharsppublic int 32 dwfilattributepublic int 32 dwFlagspublic int 16 wshowindowpublic int 16 cbreserved 2 public int ptr lpreserved 2 public int ptr hStdInputpublic int ptr hStdError }[结构布局(布局种类.顺序)]公共结构PRocESS _ INFORMATION { public int ptr HP PRocESS;public IntPtr hThreadpublic Int32 dwprocessidppublic Int32 dwThreadID }[结构布局(布局种类.顺序)]公共结构SECURITy _ ATTRIBUTES { public int 32 Length;public int ptr lpSecurityDescriptor;公共bool bInheritHandle } public enum SECURITy _ IMPERSONATION _ LEVEL { SECURITy onymous,SecurityIdentification,SecurityImpersonation,SECURITy委派} public enum TOKEN _ TYPE { TOKEN primary=1,TOKEN IMPERSONATION } public const int GENERIC _ ALL _ ACCESS=0x 1000000;[DllImport('kernel32.dll ',SetLastError=true,CharSet=CharSet .自动,调用conventi on=调用conventi on .StdCall)])公共静态外部bool CloseHandle(IntPtr句柄);[DllImport('advapi32.dll ',SetLastError=true,CharSet=CharSet .Ansi,调用conventi on=调用conventi on .StdCall)])公共静态外部bool createprocesssuser(int ptr hToken,string lpApplicationName,string lpCommandLine,ref SECURITy _ ATTRIBUTES lpProcessAttributes,ref SECURITy _ ATTRIBUTES lpThreadAttributes,bool bInheritHandle,Int32 dwCreationFlags,IntPtr lpEnvrionment,string lpCurrentDirectory,ref STARTUPINFO lpStartupInfo,ref PROCESS _ INFORMATION lpprocessing INFORMATION);[DllImport('advapi32.dll ',SetLastError=true)]公共静态extern bool replicatetokenex(int ptr hExistingToken,Int32 dwDesiredAccess,ref SECURITY _ ATTRIBUTES lpThreadAttributes,Int32 ImpersonationLevel,Int32 dwTokenType,ref IntPtr phNewToken);[DllImport('wtsapi32.dll ',SetLastError=true)]公共静态外部bool wtsqueryusetoken(int 32会话id,out int ptr Token);[DllImport('userenv.dll ',SetLastError=true)]静态外部bool CreateEnvironmentBlock(out IntPtr lpEnvironment,IntPtr hToken,bool bInherit);在CreateProcess函数中同时也涉及到DuplicateTokenEx、WTSQueryUserToken、CreateEnvironmentBlock函数的使用,有兴趣的朋友可通过MSDN进行学习。

CreateProcess函数创建后,您可以通过它真正调用应用程序。回到Service1.cs,修改OnStart,我们会打开一个CMD窗口。代码如下:复制代码如下:受保护覆盖void onstart(string[]args){ interop . create process(' cmd . exe ',@ ' c : \ windows \ system32 \ ');}重新编译程序并启动AlertService服务,看到如下界面。此时,我们可以通过一些简单的方法来解决会话0隔离的问题。还可以通过WCF等技术完成一些比较复杂的跨会话通信方式,在Windows 7和Vista系统中实现服务与桌面用户的交互操作。

参考资料1.WTSSendMessage Function http://msdn。微软。com/en-us/library/aa 383842(vs . 85)。aspx 2。createprocessouser函数http://msdn。微软。com/en-us/library/ms 682429(v=vs . 85)。aspx 3。WTSSendMessage(wtsapi32)http://www .平沃克。净/默认。aspx/wtsapi32/WTSSendMessage。html 4。WTSSendMessage代码下载AlertService2_jb51.rar作者:李敬然(国民总收入)出处:{ Gnietech }(http://www . cn blogs.com/gni elee/)

版权声明:asp.net中穿透会话0隔离(二)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。