利用 XAML 执行命令

XAML 简介

XAML(Extensible Application Markup Language)Windows Presentation Foundation(WPF)的一部分,是微软开发的一种基于 XML、基于声明,用于初始化结构化值和对象的用户界面描述语言,它有着HTML 的外观,又揉合了 XML 语法的本质,例如:可以使用 <Button> 标签设置按钮。它类似 Linux 平台下的 glade。至于WinFX XAML Browser Application(XBAP) 是用 XAML 作界面描述,在浏览器中运行的程序,可取代过去的ActiveXJava AppletFlash

XAML本质上属于一种 .NET 编程语言,属于通用语言运行库(Common Language Runtime),同 C#VB.NET 等同。与 HTML 类似,特点是用来描述用户界面。XAML的语法格式为:<Application... />Application是必备的基本元素。XAML可以定义 2D3D对象、旋转(rotations)、动画(animations),以及各式各样的效果。

参考:维基百科

利用方式

以执行 notepad.exe 为例。
VS2019 中新建一个 .net 的空项目,新建一个目录Resources,在该目录中新建一个 xml 文件,名为exec_notepad.xml,内容如下:

1
2
3
4
5
6
7
8
9
10
11
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=System">
<ObjectDataProvider x:Key="notepad" ObjectType="{x:Type diag:Process}" MethodName="Start">
<ObjectDataProvider.MethodParameters>
<s:String>notepad.exe</s:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>

需要注意的是:

  1. ObjectType用来指定类名;
  2. MethodName用来指定函数名称;
  3. MethodParameters为函数参数列表;

此处的代码实现了利用 XAML 执行Process.Start("notepad.exe")

还需要将该 xml 文件的属性设置为embedded resource:

再新建一个类文件Program.cs,用来载入该资源文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Markup;
using System.Windows.Data;
using System.Diagnostics;

namespace TestProject
{
class Program
{
private static string resName = "exec_notepad.xml";
public static string getResourceAsString(string resName, string resDir="Resources")
{
string _content = null;
string _namespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace; // 动态获取 namespace
var _assembly = Assembly.GetExecutingAssembly(); // 动态获取当前执行的 Assembly
using (Stream stream = _assembly.GetManifestResourceStream($"{_namespace}.{resDir}.{resName}"))
{
using(StreamReader _txtReader = new StreamReader(stream))
{
_content = _txtReader.ReadToEnd();
}
}
return _content;
}

static void Main(string[] args)
{
//Console.WriteLine(getResourceAsString(resName));
XamlReader.Parse(getResourceAsString(resName)); // 解析 AXML,以此实现打开记事本
}
}
}

XAML 转成 C

将上面的 XAML 转成 C# 代码,如下:

1
2
3
4
5
6
7
public static void testExecNotepad()
{
var odp = new ObjectDataProvider();
odp.ObjectType = typeof(System.Diagnostics.Process);
odp.MethodParameters.Add("notepad");
odp.MethodName = "Start";
}

需要注意的是,MethodParameters.Add要在 MethodName 之前,否则会导致出现 TargetInvocationException 异常,即如果先指定函数名称,那么将直接执行该函数。





root@kali ~# cat 重要声明
本博客所有原创文章,作者皆保留权利。转载必须包含本声明,保持文本完整,并以超链接形式注明出处【Techliu】。查看和编写文章评论都需翻墙,为了更方便地获取文章信息,可订阅RSS,如果您还没有一款喜爱的阅读器,不妨试试Inoreader.
root@kali ~# Thankyou!