Как я могу открыть приложение в определенных местах на своих мониторах с помощью Powershell

#c# #powershell

#c# #powershell

Вопрос:

Это то, что я собрал воедино, и я не могу понять, почему это не работает. Смысл скрипта в том, что он должен открыть google-chrome и разместить его в правой части экрана.

Я не лучший в powershell, поэтому я надеюсь, что вы, ребята, сможете помочь мне понять, почему это не работает. И помогите мне найти решение.

 $source = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KeyboardSend
{
    public class KeyboardSend
    {
        [DllImport("user32.dll")]
        public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
        private const int KEYEVENTF_EXTENDEDKEY = 1;
        private const int KEYEVENTF_KEYUP = 2;
        public static void KeyDown(Keys vKey)
        {
            keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
        }
        public static void KeyUp(Keys vKey)
        {
            keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
        }
    }
}
"@

Add-Type -TypeDefinition $source -ReferencedAssemblies "System.Windows.Forms"

Function Win ($Key)
{
    [KeyboardSend.KeyboardSend]::KeyDown("LWin")
    [KeyboardSend.KeyboardSend]::KeyDown("$Key")
    [KeyboardSend.KeyboardSend]::KeyUp("LWin")

}


$chrome = 'C:Program FilesGoogleChromeApplicationchrome.exe' 
$url = 'www.google.com'
amp; $chrome $url

$wshell = New-Object -ComObject wscript.shell;

[KeyboardSend.KeyboardSend]::KeyDown("LWin")
sleep 1
$wshell.SendKeys('{RIGHT}')


[KeyboardSend.KeyboardSend]::KeyUp("LWin")
  

Ответ №1:

# 1: Похоже, вы пытаетесь выполнить несколько действий для выполнения одной и той же функции. Например. Win() функция, the $wshell.SendKeys и the KeyUp/KeyDown из C #.

Чтобы исправить это, мы представим простую новую функцию C # для замены SendKeys:

 public static void KeyPress(Keys vKey)
{
    KeyDown(vKey);
    KeyUp(vKey);
}
  

Итак, теперь вы можете отправлять свои Win Right подобные сообщения:

 KeyDown("LWin");
KeyPress("Right");
KeyUp("LWin");
  

# 2: Для отправки ключей приложениям Windows требует, чтобы окно приложения было готово и активно на переднем плане. Если вы попытаетесь отправить слишком быстро после выполнения, это не сработает. Если вы попытаетесь, пока окно находится в фоновом режиме, это не сработает.

Чтобы справиться с этим, мы будем использовать Windows API:

 [DllImport("User32.dll")]
static extern int SetForegroundWindow(IntPtr hWnd);
public static bool SetForeground(string processName)
{
    Process proc = null;
    var procs = Process.GetProcessesByName(processName);
    // Wait until a window handle is available.
    // Some apps like Chrome spawns MANY processes, but only
    // one will have a MainWindowHandle.
    System.Threading.Tasks.Task.Run(() =>
    {
        while (proc == null)
            proc = procs.FirstOrDefault(p => p.MainWindowHandle != IntPtr.Zero);
    }).Wait(2000); // Quit if none found in this time
    if (proc == null) return false;
    SetForegroundWindow(proc.MainWindowHandle);
    return true;
}
  

И вы можете просто использовать его следующим образом:

 SetForeground("chrome");
  

Теперь полный код.

ПРИМЕЧАНИЕ: я использую msedge , поскольку у меня не установлен Chrome. Вы должны быть в состоянии найти 2 ссылки на edge и заменить их обе на chrome .

 $source = @"
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KeyboardSend
{
public class KeyboardSend
{
    private const int KEYEVENTF_EXTENDEDKEY = 1;
    private const int KEYEVENTF_KEYUP = 2;
    [DllImport("user32.dll")]
    public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
    [DllImport("User32.dll")]
    static extern int SetForegroundWindow(IntPtr hWnd);
    public static bool SetForeground(string processName)
    {
        Process proc = null;
        var procs = Process.GetProcessesByName(processName);
        // Wait until a window handle is available.
        // Some apps like Chrome spawns MANY processes, but only
        // one will have a MainWindowHandle.
        System.Threading.Tasks.Task.Run(() =>
        {
            while (proc == null)
                proc = procs.FirstOrDefault(p => p.MainWindowHandle != IntPtr.Zero);
        }).Wait(2000); // Quit if none found in this time
        if (proc == null) return false;
        SetForegroundWindow(proc.MainWindowHandle);
        return true;
    }
    public static void KeyDown(Keys vKey)
    {
        keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
    }
    public static void KeyUp(Keys vKey)
    {
        keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
    }
    public static void KeyPress(Keys vKey)
    {
        KeyDown(vKey);
        KeyUp(vKey);
    }
}
}
"@

Add-Type -TypeDefinition $source -ReferencedAssemblies "System.Windows.Forms"

# Start your app
$chrome = 'msedge.exe' #change to chrome
$url = 'about:blank'
Start-Process -PassThru $chrome $url 

# Wait for window to be available and pull to front.
[KeyboardSend.KeyboardSend]::SetForeground("msedge"); #change to chrome
# May wanna wrap in an IF statement in case it failed.

# Send your keys
[KeyboardSend.KeyboardSend]::KeyDown("LWin");
[KeyboardSend.KeyboardSend]::KeyPress("Right");
[KeyboardSend.KeyboardSend]::KeyUp("LWin");

# You may need to send escape if Windows10 asks you 
# what you want to snap to the other side.
sleep -Milliseconds 200
[KeyboardSend.KeyboardSend]::KeyPress("Escape");