[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖
回复 15# Five66


    C:\Users\Administrator\Desktop\FLAUI\_MouseTests_Click.ps1 : 发生错误: 使用“0”个参数调用“Invoke”时发生异常:“The requested pattern 'Invoke [#10000]' is not supp
orted”
    + CategoryInfo          : NotSpecified: ( [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,_MouseTests_Click.ps1

TOP

回复 16# 小白龙


    貌似是这样的 ,错误是由flaui抛出的 ,并不是ps本身的错误
原来c#的是测试代码 ,ps代码的话自己根据实际来 ,可以看看ps代码里的那个$dontSaveButton是什么

TOP

回复 17# Five66


    这个就是咱们在关闭记事本的时候, 弹出来的那个, 保存的对话框, 这代码相当于点了 否

TOP

回复 18# 小白龙


    这样的话 ,调用那个 FindFirstDescendant 方法的参数就不是SecondaryButton和CommandButton_7了
看错误提示那个#10000 ,大概是用窗口类名的 ,自己换成记事本对应的窗口类 ,比如#32770是对话框的类名
还有如果不是用ps代码启动的记事本 ,还得找到记事本的窗口然后调用CloseWindowWithDontSave函数 ,总之就自己按照实际来
;
像这种还不直接调winapi ,FindWindow FindWindowEx SendMessage简单

TOP

回复 19# Five66


    他这个函数就是一个通用的关闭对话框的函数, 在所有语言的操作系统上都适用, 不管是英文还是日文系统, 所以感觉很有用, 就想转换一下powershell, 大佬能方便的时候再看看吗?

TOP

本帖最后由 Five66 于 2025-3-25 00:54 编辑

回复 20# 小白龙


    参考下面的 ,先打开记事本程序 ,然后往记事本里随便输入一些东西 ,接着运行代码
  1. add-type -LiteralPath ($pwd.path+'\FlaUI.Core.dll')
  2. add-type -LiteralPath ($pwd.path+'\Interop.UIAutomationClient.dll')
  3. add-type -LiteralPath ($pwd.path+'\FlaUI.UIA3.dll')
  4. function CloseWindowWithDontSave {
  5.    param($window)
  6.    $window.Close()
  7.    [FlaUI.Core.Input.Wait]::UntilInputIsProcessed()
  8.     # 获取窗口的模态对话框
  9.     $modalWindows=[FlaUI.Core.Tools.Retry]::WhileEmpty([func[[FlaUI.Core.AutomationElements.Window[]]]]{$window.ModalWindows}, [TimeSpan]::FromSeconds(1),$null,$false,$false,$null).Result
  10.     # 查找 "不保存" 按钮
  11.     if ([FlaUI.Core.Tools.OperatingSystem]::IsWindows11()) {
  12.         $dontSaveButton = $modalWindows[0].FindFirstDescendant("SecondaryButton")
  13.     } else {
  14.         $dontSaveButton = $modalWindows[0].FindFirstDescendant( { param($cf) $cf.ByAutomationId("CommandButton_7")} )
  15.     }
  16. if($dontSaveButton){$dontSaveButton=[FlaUI.Core.AutomationElements.AutomationElementExtensions]::AsButton($dontSaveButton)
  17.     # 点击 "不保存" 按钮
  18.     $dontSaveButton.Invoke()
  19. }}
  20. #获取记事本进程
  21. $ntp=[object[]](ps -Name notepad)
  22. #创建第一个记事本进程Application对象
  23. $app=[FlaUI.Core.Application]::Attach($ntp[0].id)
  24. #创建UIA3Automation对象
  25. $auto=[FlaUI.UIA3.UIA3Automation]::new()
  26. #获取记事本进程窗口对象
  27. $window=$app.GetMainWindow($auto)
  28. #调用函数
  29. CloseWindowWithDontSave($window)
复制代码
1

评分人数

TOP

回复 21# Five66


    补充点 ,上面说的记事本是指系统自带的记事本 ,其他记事本的话可能因为窗口层次关系或窗口类名不同而出错 ,反正就是自己按实际来

TOP

本帖最后由 小白龙 于 2025-3-25 03:31 编辑

回复 21# Five66


    多谢大佬, 这回行了, 看了一下, 原来是这行代码不行
$modalWindows = [Retry]::WhileEmpty({$window.ModalWindows}, [TimeSpan]::FromSeconds(1)).Result
改成下面就行了,
$modalWindows = [FlaUI.Core.Tools.Retry]::WhileEmpty([func[[FlaUI.Core.AutomationElements.Window[]]]]{$window.ModalWindows}, [TimeSpan]::FromSeconds(1),$null,$false,$false,$null).Result
原C#是
var modalWindows = Retry.WhileEmpty(() => window.ModalWindows, TimeSpan.FromSeconds(1)).Result;
为什么多了好几个参数呢

TOP

回复 21# Five66


    我看cs的定义, 如下图, 其它几个参数都有默认值的, C#只用了两个参数就行了, 为啥powershell要补全呢

TOP

回复 21# Five66


    问了一下GPT, 说可以省啊!, 下面是gpt的解释
如果 C# 方法 **没有重载**,但有 **可选参数**,在 PowerShell 中仍然 **可以省略这些可选参数**,方法会使用默认值。  

---

## **示例:C# 只有一个方法(无重载),但有可选参数**
假设 C# 代码如下:
```csharp
public class MyClass
{
    public void MyMethod(int a, string b = "defaultB", int c = 10, bool d = false)
    {
        Console.WriteLine($"a={a}, b={b}, c={c}, d={d}");
    }
}
```

在 PowerShell 中调用:
```powershell
# 创建对象
$object = New-Object MyClass

# 只传递必需参数 `a`,省略 `b`, `c`, `d`
$object.MyMethod(1)
# 输出: a=1, b=defaultB, c=10, d=False

# 传递 `a`, `b`,省略 `c`, `d`
$object.MyMethod(1, "CustomB")
# 输出: a=1, b=CustomB, c=10, d=False

# 传递 `a`, `b`, `c`,省略 `d`
$object.MyMethod(1, "CustomB", 20)
# 输出: a=1, b=CustomB, c=20, d=False

# 传递所有参数
$object.MyMethod(1, "CustomB", 20, $true)
# 输出: a=1, b=CustomB, c=20, d=True
```

---

## **PowerShell 省略可选参数的规则**
1. **PowerShell 会自动使用 C# 方法定义的默认值**。
2. **参数必须按顺序传递**,不能直接跳过中间参数。例如:
   ```powershell
   $object.MyMethod(1, , , $true)  # ❌ 错误,PowerShell 不允许省略中间的逗号
   ```
   如果需要指定后面的参数,必须传 `null`:
   ```powershell
   $object.MyMethod(1, $null, $null, $true)  # ✅ 这样可以
   ```

---

## **结论**
✅ **C# 只有一个方法,没有重载,但有可选参数时,PowerShell 仍然可以省略可选参数**。  
✅ **必须按顺序传递参数,不能直接跳过中间参数**,如果想跳过,可以传 `$null` 作为占位符。  

你在转换 C# 代码时遇到了什么问题?可以贴出来,我可以帮你看看!😊

TOP

回复 23# 小白龙


    啊 ,WhileEmpty方法调用代码13楼不是发过了
需要调用泛型的WhileEmpty方法 ,C#有编译支持 ,可以指定泛型方法的类型 ,也有参数演绎
但是ps并没有参数演绎 ,ps版本7.3才能指定泛型方法的类型 ,因此ps版本7.3以下调用泛型方法要么依靠ps本身的参数推断 ,要么使用反射 ,省略参数不行就带上全部参数 ,带上参数不行就用反射 ,就是这样的规则和设定
ps调用泛型方法可参考:https://learn.microsoft.com/zh-c ... view=powershell-7.3

TOP

回复 22# Five66
大佬像下面这种的, 都得像上面那样改吗? 怎么个更改思路? 对C#还不熟悉

            var mainWindow = Application.GetMainWindow(Automation);
            var tab = mainWindow.FindFirstDescendant(cf => cf.ByControlType(ControlType.Tab)).AsTab();
            tab.SelectTabItem(1);
            var grid = mainWindow.FindFirstDescendant(cf => cf.ByAutomationId("listView1")).AsGrid();

TOP

回复 27# 小白龙


   
普通方法直接改
拓展方法改成对应的静态方法调用 ,AsTab ,AsButton ,AsCalendar ,Asxxx....之类的都是FlaUI.Core.AutomationElements.AutomationElementExtensions类的静态方法
泛型方法改的时候尽量指定参数类型并带上所有参数 ,不行就只能反射 ,反射参考26楼的链接
lambda改成块或func或action
不知道啥类型的在ps里gm一下或者直接看源码

TOP

回复 28# Five66

多谢大佬指导, 能帮看一下这个问题吗? 多谢
http://www.bathome.net/thread-70714-1-1.html

TOP

返回列表