如何在 .NET5 和 .Net6 中使用 UIAutomator
How to use UIAutomation in .NET5 or .Net6
我创建了一个包含 7 个项目的 webApi 解决方案。
其中一个名为'FinanceApp.UIA,下面是我在这个项目中使用的SDK。
请注意,'Microsoft.WindowsDesktop.App' 已包括在内,
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
</ItemGroup>
<ItemGroup>
<Folder Include="SimulateType\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FinanceApp.Comon\FinanceApp.Common.csproj" />
<ProjectReference Include="..\FinanceApp.IRepository\FinanceApp.IRepository.csproj" />
<ProjectReference Include="..\FinanceApp.Model\FinanceApp.Model.csproj" />
</ItemGroup>
</Project>
为什么包含 'Microsoft.WindowsDesktop.App'?下面是我想在这个项目中做的事情
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Automation;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using FinanceApp.Common;
namespace FinanceApp.UIA
{
public class BaseUia:IBaseUia
{
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
IntPtr lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetHwndByClassName(string lpClassName, string lpWindowName);
/// <summary>
/// Get handles by process ID
/// </summary>
/// <param name="processId"></param>
/// <returns></returns>
public IEnumerable<IntPtr> GetHwndFromPid(int processId)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
{
EnumThreadWindows(thread.Id,
(hWnd, lParam) =>
{
handles.Add(hWnd);
return true;
},
IntPtr.Zero);
}
return handles;
}
/// <summary>
/// Get AutomationElement by process id
/// </summary>
/// <param name="processId"></param>
/// <returns></returns>
public IEnumerable<AutomationElement> GetElementsByPid(int processId)
{
var handles = GetHwndFromPid(processId);
return handles.Select(hnd => AutomationElement.FromHandle(hnd));
}
}
}
另一个名为'FinanceApp.Service'的项目,SDK和参考如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>Latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FinanceApp.UIA\FinanceApp.UIA.csproj" />
</ItemGroup>
</Project>
我收到如下错误
The target platform must be set to Windows (usually by including
'-windows' in the TargetFramework property) when using Windows Forms
or WPF, or referencing projects or packages that do
so. FinanceApp.Service C:\Program
Files\dotnet\sdk.0.100-preview.1.21103.13\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets 362
按照Simon的建议,将解决方案中所有项目的目标框架改为'net5.0-windows',然后解决。
我创建了一个包含 7 个项目的 webApi 解决方案。
其中一个名为'FinanceApp.UIA,下面是我在这个项目中使用的SDK。 请注意,'Microsoft.WindowsDesktop.App' 已包括在内,
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.WindowsDesktop.App" />
</ItemGroup>
<ItemGroup>
<Folder Include="SimulateType\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FinanceApp.Comon\FinanceApp.Common.csproj" />
<ProjectReference Include="..\FinanceApp.IRepository\FinanceApp.IRepository.csproj" />
<ProjectReference Include="..\FinanceApp.Model\FinanceApp.Model.csproj" />
</ItemGroup>
</Project>
为什么包含 'Microsoft.WindowsDesktop.App'?下面是我想在这个项目中做的事情
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Automation;
using System.Threading;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using FinanceApp.Common;
namespace FinanceApp.UIA
{
public class BaseUia:IBaseUia
{
delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
IntPtr lParam);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetHwndByClassName(string lpClassName, string lpWindowName);
/// <summary>
/// Get handles by process ID
/// </summary>
/// <param name="processId"></param>
/// <returns></returns>
public IEnumerable<IntPtr> GetHwndFromPid(int processId)
{
var handles = new List<IntPtr>();
foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
{
EnumThreadWindows(thread.Id,
(hWnd, lParam) =>
{
handles.Add(hWnd);
return true;
},
IntPtr.Zero);
}
return handles;
}
/// <summary>
/// Get AutomationElement by process id
/// </summary>
/// <param name="processId"></param>
/// <returns></returns>
public IEnumerable<AutomationElement> GetElementsByPid(int processId)
{
var handles = GetHwndFromPid(processId);
return handles.Select(hnd => AutomationElement.FromHandle(hnd));
}
}
}
另一个名为'FinanceApp.Service'的项目,SDK和参考如下:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>Latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\FinanceApp.UIA\FinanceApp.UIA.csproj" />
</ItemGroup>
</Project>
我收到如下错误
The target platform must be set to Windows (usually by including '-windows' in the TargetFramework property) when using Windows Forms or WPF, or referencing projects or packages that do so. FinanceApp.Service C:\Program Files\dotnet\sdk.0.100-preview.1.21103.13\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.targets 362
按照Simon的建议,将解决方案中所有项目的目标框架改为'net5.0-windows',然后解决。