Powershell代码在PowerShell_ise上运行良好,但在PowerShell中破解

问题描述:

我试图编写一个代码,可以快速锁定密钥的LED(使用-comObject发送密钥)。 Powershell(来自CMD)的代码运行速度非常慢,并且错过了一些按键,但似乎在Powershell_ise上效果很好。Powershell代码在PowerShell_ise上运行良好,但在PowerShell中破解

该代码将文件读取为二进制文件,然后将每个位传输到num/scroll lock。这需要运行得非常快 - 尽可能快。

这是代码:

$wsh = New-Object -ComObject "WScript.Shell" 
$bytes = [Byte[]] (Get-Content $env:temp\temp1536.txt -Encoding Byte -ReadCount 0) | ForEach-Object {[System.Convert]::ToString($_,2)} 
##($i=0; $i -le $byte.length; $i++){ 

foreach ($byte in $bytes) { 
#$byte; 
    while($byte.length -ne 1){ 
    if($byte[1] -eq '1'){ 
     #echo "1"; 
     $wsh.SendKeys('{SCROLLLOCK}'); 
     [System.Threading.Thread]::Sleep(40); 
     $wsh.SendKeys('{SCROLLLOCK}'); 
    } Else { 
     #echo "0"; 
     $wsh.SendKeys('{NUMLOCK}'); 
     [System.Threading.Thread]::Sleep(40); 
     $wsh.SendKeys('{NUMLOCK}'); 
    } 
    $byte=$byte.Substring(1); 
    [System.Threading.Thread]::Sleep(50); 


    } 
    #echo " "; 
    #echo "1"; 

    $wsh.SendKeys('{CAPSLOCK}'); 
    [System.Threading.Thread]::Sleep(55); 

    $wsh.SendKeys('{CAPSLOCK}'); 
    [System.Threading.Thread]::Sleep(20); 

} 

任何人都知道为什么出现这种情况?

编辑: 我添加了一个视频,显示在Powershell Console Vs.上闪烁的锁定键的延迟。 Powershell_ISE http://youtu.be/OnOmr50OBhs

I/Windows 7上

试过这对PowerShell的V3.0 4.0我用这个文本文件名-'temp1536.txt”在%temp%文件夹 的文件导入到二进制文件,然后相应地点亮领导。

$bytes = [Byte[]] (Get-Content $env:temp\temp1536.txt -Encoding Byte -ReadCount 0) | ForEach-Object {[System.Convert]::ToString($_,2)} 

这似乎是一些个人电脑的问题。 真的不明白为什么。但是我在一些电脑上正常工作。

我不能让你的代码工作(它从来没有踏进if($byte[1] -eq '1')),但这里是用keybd_event \ GetKeyState的Win32 API的作品在我的ISE和控制台精致的版本。摘自代码here

$Keyboard = @' 
using System.Runtime.InteropServices; 

namespace My 
{ 
    public class Keyboard 
    { 
     private const byte VK_SCROLL = 0x91; 
     private const byte VK_NUMLOCK = 0x90; 
     private const byte VK_CAPITAL = 0x14; 
     private const uint KEYEVENTF_KEYUP = 0x2; 

     [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)] 
     static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo); 

     [DllImport("user32.dll", EntryPoint = "GetKeyState", SetLastError = true)] 
     static extern short GetKeyState(uint nVirtKey); 

     // SCROLLLOCK 
     public static void SetScrollLockKey(bool newState) 
     { 
      bool scrollLockSet = GetKeyState(VK_SCROLL) != 0; 
      if (scrollLockSet != newState) 
      { 
       keybd_event(VK_SCROLL, 0, 0, 0); 
       keybd_event(VK_SCROLL, 0, KEYEVENTF_KEYUP, 0); 
      } 
     } 
     public static bool GetScrollLockState() 
     { 
      return GetKeyState(VK_SCROLL) != 0; 
     } 

     // NUMLOCK 
     public static void SetNumLockKey(bool newState) 
     { 
      bool scrollLockSet = GetKeyState(VK_NUMLOCK) != 0; 
      if (scrollLockSet != newState) 
      { 
       keybd_event(VK_NUMLOCK, 0, 0, 0); 
       keybd_event(VK_NUMLOCK, 0, KEYEVENTF_KEYUP, 0); 
      } 
     } 

     public static bool GetNumLockState() 
     { 
      return GetKeyState(VK_NUMLOCK) != 0; 
     } 

     // CAPSLOCK 
     public static void SetCapsLockKey(bool newState) 
     { 
      bool scrollLockSet = GetKeyState(VK_NUMLOCK) != 0; 
      if (scrollLockSet != newState) 
      { 
       keybd_event(VK_CAPITAL, 0, 0, 0); 
       keybd_event(VK_CAPITAL, 0, KEYEVENTF_KEYUP, 0); 
      } 
     } 

     public static bool GetCapsLockState() 
     { 
      return GetKeyState(VK_CAPITAL) != 0; 
     } 
    } 
} 
'@ 

Add-Type -TypeDefinition $Keyboard -ErrorAction Stop 

$Bytes = Get-Content -Path '.\led.txt' -Encoding Byte 

foreach ($byte in $Bytes) { 
    if($byte) 
    { 
     [My.Keyboard]::SetScrollLockKey($true) 
     [System.Threading.Thread]::Sleep(40) 
     [My.Keyboard]::SetScrollLockKey($false) 
    } 
    else 
    { 
     [My.Keyboard]::SetNumLockKey($true) 
     [System.Threading.Thread]::Sleep(40) 
     [My.Keyboard]::SetNumLockKey($false) 
    } 

    [My.Keyboard]::SetCapsLockKey($true) 
    [System.Threading.Thread]::Sleep(55) 

    [My.Keyboard]::SetNumLockKey($false) 
    [System.Threading.Thread]::Sleep(20) 
} 
+0

谢谢。 你能在控制台和ISE中看到不同的性能吗?当我在控制台上运行它时,它的运行速度非常慢......我可以看到LED慢速闪烁,并且在运行“测量命令”时也显示为 – oriez

+0

@oriez您的意思是我的代码在控制台中运行缓慢?只需使用'Measure-Command'在另一台PC上检查它,仍然没有问题:它的运行速度与ISE一样快。检查这个问题,也许它与代码本身没有任何关系:[KB3057134中描述的更新似乎使PowerShell开始缓慢](http://serverfault.com/questions/691873/it-seems-like -updates-in-the-kb3057134-make-powershell-to-start-slow) – beatcracker

+0

@oriez Btw,你使用的是什么版本的PowerShell?这可以实现STA \ MTA模式:[PowerShell控制台和PowerShell ISE之间的区别](http://*.com/questions/20022976/difference-between-powershell-console-and-powershell-ise)。尝试使用'-sta'和'-mta'开关运行PS控制台,看看它是否有帮助。 – beatcracker