关于部分WIN32 API 在WIN 7下失效的问题

   今天下午在回复longware的反馈问题时,发现的FindWindow 、FindWindowEX、SendMessage等部分WIN32 API在WIN 7下某些情况下会失效的问题。

   发现过程是:longware网友反馈我《屏幕录像功能技术探索及分享 》里的实验程序在WIN 7下无法正常结束屏幕录像进程。经过我调试测试后,发现程序里调用的FindWindow无法获取到camstudio_cl.exe进程的句柄(返回0)。

      表面原因:录制视频方法里,

  //不创建进程窗口
  p.StartInfo.CreateNoWindow = true;
  在VISTA/WIN 7下 FindWindow或FindWindowEX无法获取到窗体句柄,所以无法发消息来结束进程。

      理论原因:

  Impact of Session 0 Isolation on Services and Drivers in Windows

    来源http://www.microsoft.com/whdc/system/sysinternals/Session0Changes.mspx

       Updated: December 10, 2009

  In Windows XP, Windows Server 2003, and earlier versions of Windows, all services run in Session 0 along with applications. This situation   poses a security risk. In Windows Vista, Windows Server 2008, and later versions of Windows, the operating system isolates services in Session 0 and runs applications in other sessions, so services are protected from attacks that originate in application code.

This paper describes changes to the way in which services are run. It provides guidelines for developers to modify application services and driver services to run in Windows Vista, Windows Server 2008, and later versions of Windows.

This information applies to the following operating systems:
Windows 7
Windows Server 2008 R2
Windows Server 2008
Windows Vista

        理论上原因大意为:在VISTA之前的操作系统中(如XP/ WIN SERVER 2003等),所有的服务线程和应用程序都在Session 0里运行,这种方式具有安全风险,Vista/win7之后的操作系统隔离了服务和应用程序,这样服务就可以免于潜在的来自这应用程序代码的攻击。

        我理解时,在WIN 7里当不创建窗体的程序进程,会被认为是服务,从而运行于Session 0里。所以,应用程序调用FindWindow方法也就无法获取进程的窗体句柄啦。

     解决方法:
  经过我试验,

      1) “ [DllImport("kernel32.dll",SetLastError = true, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr GetConsoleWindow();”  是无法解决问题的,同样无法获取句柄。

      2) FindWindowEX代替FindWindow同样无法解决问题

      3)只能在WIN 7下允许录制视频时创建窗体的情况下,p.StartInfo.CreateNoWindow = false;才能获取进程窗体句柄,进而结束录制进程。目前没找到更好的方法。

 另外知识点:向外部程序中发送键盘按键值

1.首先启动进程, Process.Start("mspaint.exe","C:\\1.jpg");
2.然后激活画图程序
3.然后向改进程发送CTRL+S按键:SendKeys.Send("^S");

ExpandedBlockStart.gif 代码
没有把画图程序关掉,而是把主程序关掉了 
[DllImport(
" user32.dll " , CharSet  =  CharSet.Auto)] 
        
public   static   extern  IntPtr FindWindow( string  className,  string  windowName); 
        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto, ExactSpelling  =   true )] 
        
public   static   extern   bool  SetForegroundWindow(IntPtr hWnd); 
       [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto, ExactSpelling  =   true )] 
        
public   static   extern   bool  IsIconic(IntPtr hWnd); 
        [DllImport(
" user32.dll " , CharSet  =  CharSet.Auto, ExactSpelling  =   true )] 
        
public   static   extern   bool  OpenIcon(IntPtr hWnd);       
        
private   void  button1_Click( object  sender, EventArgs e) 
        {            
            Process.Start(
" mspaint.exe " ); 
            IntPtr handle 
=  FindWindow( null " 未命名 - 画图 " ); 
            
if  (handle  !=  IntPtr.Zero) 
            { 
                
if  (IsIconic(handle)) 
                { 
                    OpenIcon(handle); 
                } 
                
else  
                { 
                    SetForegroundWindow(handle);                    
                } 
            } 
            SendKeys.Send(
" %{F4} " );           
        } 
--------- 回复 --------------
保证可用
~ 接分...先打开最小化,然后active,然后置顶!!! 
C# code
[DllImport(
" user32.dll " )]  static   extern  IntPtr SetActiveWindow(IntPtr hWnd); [DllImport( " user32.dll " )] [ return : MarshalAs(UnmanagedType.Bool)]  static   extern   bool  OpenIcon(IntPtr hWnd); [DllImport( " user32.dll " )] [ return : MarshalAs(UnmanagedType.Bool)]  static   extern   bool  SetForegroundWindow(IntPtr hWnd);  public   static   void  GetMainWindow( string  proName) { Process[] pros  =  Process.GetProcessesByName(proName.Trim());  if  (pros.Length  !=   0 ) { IntPtr pGame  =  pros[ 0 ].MainWindowHandle; OpenIcon(pGame); SetActiveWindow(pGame); SetForegroundWindow(pGame); Thread.Sleep( 2000 ); }  else  { Console.WriteLine( " Can't get the Main Window. " ); } } 

 

 

参考:

与我遇到相似的问题http://stackoverflow.com/questions/340122/findwindow-fails-from-service-application

http://www.experts-exchange.com/Programming/Programming_Languages/C_Sharp/Q_21590318.html

http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/ea8b0fd5-a660-46f9-9dcb-d525cc22dcbd/

http://www.khgl.cn/html/82/n-895082.html

 

 

 本博客声明:本人的技术探索过程中,得到了国信司南公司方面物质和精神支持。今后,本人博客里的所有技术探索成果将归“无痕客”、“国信司南”和“博客园”三方共同所有,原创作品如需转载,请注明本博客声明。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值