WPF 获取DLL中的资源方法
文件结构:
创建了一个WPF项目,然后添加了一个类库,在类库中新建了一个Files文件夹,并在文件夹中放入一个txt文件和一个png文件,并将这两个文件的属性中的复制到输出目录设成不复制,生成操作改为Resource;
操作:获取文本和图片
WPF xaml代码:
<Window x:Class="WPF001.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF001"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="400">
<StackPanel Margin="20">
<Button Width="100" Height="25" Content="Test File" Click="Button_Click" Margin="0 0 0 20"/>
<Button Width="100" Height="25" Content="Test PNG" Click="Button_Click_1" Margin="0 0 0 20"/>
<Image x:Name="packImage" Width="50" Height="50"/>
</StackPanel>
</Window>
后台代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF001
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "ClassLibrary.dll";
Assembly assembly = Assembly.LoadFile(path1);
string resourceName = assembly.GetName().Name + ".g";
//ResourceManager manager = new ResourceManager(resourceName,this.GetType().Assembly);
ResourceManager manager = new ResourceManager(resourceName, assembly);
var resourceSet = manager.GetResourceSet(CultureInfo.CurrentCulture, true, true);
var dictionaryEntries = resourceSet.OfType<DictionaryEntry>().ToList();
dictionaryEntries.ForEach(arg => {
if (arg.Key.ToString().Contains(".txt"))
{
Stream stream = (Stream)arg.Value;
//StreamReader reader = new StreamReader(stream, Encoding.GetEncoding("GB2312"));
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
MessageBox.Show(text);
}
});
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
string path1 = System.AppDomain.CurrentDomain.BaseDirectory + "ClassLibrary.dll";
Assembly assembly = Assembly.LoadFile(path1);
string resourceName = assembly.GetName().Name + ".g";
//ResourceManager manager = new ResourceManager(resourceName,this.GetType().Assembly);
ResourceManager manager = new ResourceManager(resourceName, assembly);
var resourceSet = manager.GetResourceSet(CultureInfo.CurrentCulture, true, true);
var dictionaryEntries = resourceSet.OfType<DictionaryEntry>().ToList();
dictionaryEntries.ForEach(arg => {
if (arg.Key.ToString().Contains(".png"))
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = (Stream)arg.Value;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
packImage.Source = bitmapImage;
}
});
//-------------------------------------------------------------------------------------------------------
//或者使用绝对路径
packImage.Source = new BitmapImage(new Uri("pack://application:,,,/ClassLibrary;component/Files/msg.png"));
}
}
//复制DLL中的资源文件
private void Button_Click_4(object sender, RoutedEventArgs e)
{
string fileName = System.AppDomain.CurrentDomain.BaseDirectory + "1.txt";
if (File.Exists(fileName))
File.Delete(fileName);
using (FileStream fs = new FileStream(fileName, FileMode.Create))
{
//StreamResourceInfo resource = Application.GetResourceStream(new Uri("/xx;component/Resources/" + fileName, UriKind.Relative));
StreamResourceInfo resource = Application.GetResourceStream(new Uri("pack://application:,,,/ClassLibrary;component/Files/data.txt", UriKind.Absolute));
resource.Stream.CopyTo(fs);
}
}
}
或者:
System.IO.Stream src = Application.GetResourceStream(new Uri("/PhoneApp4;component/image/a.png", UriKind.Relative)).Stream;
关键在Uri的格式,PhoneApp4是项目名称,component是固定路径,image/a.jpg才是图片资源相对路径,得到的是Stream,在微软官方的例子中,使用下面的方法来转换成图片:
BitmapImage bi = new BitmapImage();
bi.SetSource(src);
Image img = new Image();
img.Source = bi;
获取类库中xml文件内容的方法:
xml文件XMLFile.xml内容(注意文件属性也改为Resource):
<?xml version="1.0" encoding="utf-8" ?>
<Config>
<Item name="node1" content="Hello World"></Item>
</Config>
读取方法:
private void btn_XML_Click(object sender, RoutedEventArgs e)
{
string fileName = AppDomain.CurrentDomain.BaseDirectory + "ClassLibrary.dll";
Assembly assembly = Assembly.LoadFile(fileName);
string resourceName = assembly.GetName().Name + ".g";
ResourceManager manager = new ResourceManager(resourceName, assembly);
object obj = manager.GetObject("files/xmlfile.xml"); //注意这里文件路径全改为小写
if (obj != null)
{
Stream stream = (System.IO.Stream)obj;
XmlDocument doc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释,因为在没有特别说明的情况下,注释也是一个节点
XmlReader reader = XmlReader.Create(stream, settings);
doc.Load(reader);
XmlNode xn = doc.SelectSingleNode("Config");
XmlNodeList xnl1 = xn.ChildNodes;
foreach (XmlNode xn1 in xnl1)
{
XmlElement xe1 = (XmlElement)xn1;
if (xe1.GetAttribute("name").ToString() == "node1")
{
MessageBox.Show(xe1.GetAttribute("content").ToString());
}
}
reader.Close();
}
}
附Stream类一般操作:
将 Stream 写入文件
// 把 Stream 转换成 byte[]
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
// 设置当前流的位置为流的开始
stream.Seek(0, SeekOrigin.Begin);
// 把 byte[] 写入文件
FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
fs.Close();