当然是在远程机器上了,jhonguy你没用过PCANYWHERE是吧?

解决方案 »

  1.   

    就是普通的用CTRL+ALT+DEL锁定的,要在程序中实现解锁,它应该是向系统发消息来实现的,但问题是发的什么消息呢?具体怎么实现的呢?
      

  2.   

    我们在操作时是在控制端点击一个按钮,然后远程机器就响应了CTRL+ALT+DEL的操作。
    从这个操作流程看,实现应该是:
    1.按钮事件中处理一个信息传递,远程机器接收后再模拟CTRL+ALT+DEL的操作
    2.消息的传递我想跟设置中的选项有关,一般是设置为tcp/ip,也就是消息是使用tcp/ip协议出去的
    3.模拟CTRL+ALT+DEL操作向系统传递消息属于windows编程的内容,应该可以在很多地方找到
      

  3.   

    我就是想找到模拟向系统传递CTRL+ALT+DEL的啊,哪儿可以找到?我找了好久了,都没有找到啊
      

  4.   

    PCANYWHERE需要客户端和服务器端两部分吗?
      

  5.   

    主控端与被控端是否都要装pcanywhere? 
      

  6.   

    反正用keybd_event能够产生有关按键的消息。可以模拟按键。
      

  7.   

    我已经试过,使用Keybd_Event函数不可能实现。。请各位另外想办法吧.!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      

  8.   

    // 这是我以前写的一段代码,在NT/Win2k下可以工作
    // 算你好运。
    // 主要的trick是WindowsStation/Desktop和那句PostMessageconst
      DEF_ACT_WS: PChar = 'WinSta0';        // current user window station
      LOGON_DT: PChar = 'WinLogon';         // winlogon desktop
      DEFAULT_DT: PChar = 'Default';        // default desktopconst
      FLAG_OPEN_WS =
          WINSTA_ENUMDESKTOPS or WINSTA_READATTRIBUTES or
          WINSTA_ACCESSCLIPBOARD or WINSTA_CREATEDESKTOP or
          WINSTA_WRITEATTRIBUTES or WINSTA_ACCESSGLOBALATOMS or
          WINSTA_EXITWINDOWS or WINSTA_ENUMERATE or WINSTA_READSCREEN;
      FLAG_OPEN_DT =
          DESKTOP_READOBJECTS or DESKTOP_CREATEWINDOW or
          DESKTOP_CREATEMENU or DESKTOP_HOOKCONTROL or
          DESKTOP_JOURNALRECORD or DESKTOP_JOURNALPLAYBACK or
          DESKTOP_ENUMERATE or DESKTOP_WRITEOBJECTS or DESKTOP_SWITCHDESKTOP;function OpenWSDT (pszWS, pszDT: PChar; var hOldWS: HWINSTA;
      var hOldDT: HDESK): Boolean;
    var
      hNewWS: HWINSTA;
      hNewDT: HDESK;
    begin
      Result := FALSE;
      hOldWS := GetProcessWindowStation;
      hOldDT := GetThreadDesktop (GetCurrentThreadID);  hNewWS := 0;
      if pszWS<>nil then
      begin
        hNewWS := OpenWindowStation(pszWS,FALSE,FLAG_OPEN_WS);
        if hNewWS<>0 then
        begin
          if not SetProcessWindowStation(hNewWS) then
          begin
            CloseWindowStation(hNewWS);
            Exit;
          end;
        end else Exit;
      end;  if pszDT=nil then
      hNewDT := OpenInputDesktop(0,FALSE,FLAG_OPEN_DT) else
      hNewDT := OpenDesktop (pszDT,0,FALSE,FLAG_OPEN_DT);
      if hNewDT<>0 then
      if not SetThreadDesktop (hNewDT) then
      begin
        CloseDesktop (hNewDT);
      end else Result := TRUE;  if not Result then
      begin
          // Failed, close switched station
        if hNewWS<>0 then
        begin
          if SetProcessWindowStation(hOldWS) then
          begin
            CloseWindowStation (hNewWS);
          end;
        end;
      end;end;procedure SwitchWSDT(hWS: HWINSTA; hDT: HDESK);
    var
      hCurWS: HWINSTA;
      hCurDT: HDESK;
    begin
      if hWS<>0 then
      begin
        hCurWS := GetProcessWindowStation;
        if hWS<>hCurWS then
        if SetProcessWindowStation(hWS) then
        begin
          CloseWindowStation(hCurWS);
        end;
      end;  if hDT<>0 then
      begin
        hCurDT := GetThreadDesktop (GetCurrentThreadID);
        if hCurDT<>hDT then
        if SetThreadDesktop(hDT) then
        begin
          CloseDesktop(hCurDT);
        end;
      end;
    end;procedure SimulateCtrlAltDel (bIsWinNT: Boolean);
    var
      hOldWS: HWINSTA;
      hOldDT: HDESK;
    begin
      if not OpenWSDT(DEF_ACT_WS,LOGON_DT,hOldWS,hOldDT) then hOldWS := 0;
      PostMessage(HWND_BROADCAST,WM_HOTKEY,0,
          MAKELONG(MOD_ALT or MOD_CONTROL, VK_DELETE));
      if hOldWS<>0 then SwitchWSDT(hOldWS,hOldDT);
    end;
    // HTH
      

  9.   

    http://CoolSlob.8u8.com/Favorites/做个广告,
    呵呵
      

  10.   

    edguo!!我试了试怎么不行啊,运行后打开了“运行程序”的窗口!
    能指点一下吗?
      

  11.   

    你的意思是不是要捕捉CTRL+ALT+DEL,不让系统显示出原来的“关闭程序”的窗口,而是显示你自己的窗口?
      

  12.   

    工作在Service模式可以。
    我在我们的产品的远程维护一直用着。代码是对的。
    在user模式下我没仔细研究过,抱歉。
    我刚才看了一下,是OpenDesktop()失败,估计是权限还是什么原因,没时间研究。Good luck.
      

  13.   

    我注意到OpenDesktop()属于Service Functions,
    如果你使用这段代码,说不好只能写Service,
    到目前为止我还没见过不用Service就能这样做的软件
    (除了Windows本身,其实我怀疑它是怎么做的)。
    HTH.
      

  14.   

    //这是段模拟按键的代码,也是我以前写的。
    // 特殊按键通过SetShiftState()来做,例如SetShiftState(VK_MENU,TRUE);procedure KeybdEvent (KeyCode: Byte; Flags: DWORD);
    begin
      Keybd_Event(KeyCode, MapVirtualKey(KeyCode, 0), Flags, 0);
    end;procedure SetShiftState (Key: Byte; Down: Boolean);
    var
      KeyState: Boolean;
      Flags: DWORD;
    begin
      KeyState := GetAsyncKeyState(Key) and $8000<>0;
      if (KeyState and Down) or ((not KeyState)and(not Down)) then Exit;
      if Down then Flags := 0 else Flags := KEYEVENTF_KEYUP;
      KeybdEvent(Key,Flags);
    end;procedure SendKey (KeySym: Char; KeyDown: Boolean; bIsWinNT: Boolean);
    var
      KeyVal: SmallInt;
      KeyCode, KeyMask: Byte;
      LShift,RShift,Ctrl,Alt, CapsLock: Boolean;
      Flags: DWORD;
    begin
      KeyVal := VkKeyScan(Char(Byte(KeySym) and $FF));
      KeyCode := LOBYTE(KeyVal);
      KeyMask := HIBYTE(KeyVal);
      if KeyCode=$FF then Exit;  CapsLock := (GetAsyncKeyState(VK_CAPITAL) and $8000)<>0;
      if CapsLock then KeyMask := KeyMask xor 1;
      if bIsWinNT then
      begin
        LShift := (GetAsyncKeyState(VK_LSHIFT) and $8000) <> 0;
        RShift := (GetAsyncKeyState(VK_RSHIFT) and $8000) <> 0;    SetShiftState(VK_RSHIFT, FALSE);
        SetShiftState(VK_LSHIFT, FALSE);
        SetShiftState(VK_SHIFT, (KeyMask and $01)<>0);    Ctrl := (GetAsyncKeyState(VK_LCONTROL) and $8000) <> 0;
        if (not Ctrl) then SetShiftState(VK_LCONTROL,(KeyMask and $02)<>0);
        Alt := (GetAsyncKeyState(VK_LMENU) and $8000) <> 0;
        if (not Alt) then SetShiftState(VK_LMENU,(KeyMask and $04)<>0);
      end else
      begin
        LShift := (GetAsyncKeyState(VK_SHIFT) and $8000) <> 0;
        RShift := FALSE;
        SetShiftState (VK_SHIFT, (KeyMask and $01)<>0);
        Ctrl := (GetAsyncKeyState(VK_CONTROL) and $8000) <> 0;
        if  (not Ctrl) then SetShiftState(VK_CONTROL, (Keymask and $02)<>0);
        Alt := (GetAsyncKeyState(VK_MENU) and $8000) <> 0;
        if (not Alt) then SetShiftState(VK_MENU,(KeyMask and $04)<>0);
      end;
      if KeyDown then Flags := 0 else Flags := KEYEVENTF_KEYUP;
      KeybdEvent(KeyCode and $FF,Flags);  if bIsWinNT then
      begin
        SetShiftState(VK_LSHIFT, LShift);
        SetShiftState(VK_RSHIFT, RSHIFT);
        SetShiftState(VK_LCONTROL, CTRL);
        SetShiftState(VK_LMENU, ALT);
      end else
      begin
        SetShiftState(VK_SHIFT, LSHIFT);
        SetShiftState(VK_CONTROL, CTRL);
        SetShiftState(VK_MENU, ALT);
      end;
    end;// HTH
    // 不要有非法企图啊
      

  15.   

    这个SendKey函数不能模拟C+A+D,但上面的代码可以(须做成Service)。
      

  16.   

    做成Service也不行啊,我是在WIN2000SERVER下用D5做的,在SetThreadDesktop不成功。什么原因呢?
      

  17.   

    pcanywhere 上有一个按钮,好像叫发送ctrl+alt+del
      

  18.   

    我想就是发一个消息就可以吧,向你控制的SERVER 发一个c+a+d的消息就可以啊
      

  19.   

    我很抱歉,但我这段代码已经用了一年,没有发生问题。有否不调试直接当Service运行过?
      

  20.   

    edguo,很感谢你的帮助!
    我在非调试环境下运行的时候,弹出了“运行程序”的窗口,其他的一点反映都没有
      

  21.   

    我是说做成Service,注册Service (-install)后然启动服务,象IIS/SQLServer,不是运行,如果你直接运行就是在用户模式下做,不是服务模式,服务中有单独线程工作,并且运行在不同的WindowStation,服务是不号调试的,一般只能用Log/EventLog/Console方式来调试,当然,也可以MessageBox,不过要切换Desktop。我把我的程序变程普通App运行也会出现这种问题,但是服务方式是正常的,能弹出LogonBox.
      

  22.   

    是的,我就是安装了服务有启动,用记录日志的办法调试的,发现走到SetThreadDesktop的时候,返回的是失败,以下就没有什么反映了
      

  23.   

    可以啊!
    我刚试了一下,一下就弹出了对话框。
    OnExecuteprocedure TTestService.TestServiceExecute(Sender: TService);
    begin
      Sleep(15000);
      SimulateCtrlAltDel(TRUE);
      Sleep(5000);
    end;
      

  24.   

    不会吧,我是这样用的:
    procedure TServiceZsj.ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      Cmd:string;
    begin
       Cmd:=Socket.ReceiveText;
       WriteLn(F,FormatDatetime('yyyy-mm-dd hh:nn:ss',Now)+' --- '+Cmd);   if Cmd='Login' then
          SimulateCtrlAltDel(True);
    end;
    应该没有什么区别啊,怎么我的不行呢?奇怪了