Date: 31.12.2018 9:43:52
<Window x:Class="WpfBuild.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF Viewer" Height="350" Width="525" WindowState="Maximized">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Label Content="Путь к проекту" HorizontalAlignment="Left" Margin="31,31,0,0" VerticalAlignment="Top"/>
<Label Content="Каталог для вывода" HorizontalAlignment="Left" Margin="31,87,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="tbProject" HorizontalAlignment="Stretch" Height="26" Margin="189,31,10,00"
TextWrapping="Wrap" Text="" VerticalAlignment="Top" />
<TextBox x:Name="tbOutputDir" HorizontalAlignment="Stretch" Height="26" Margin="189,87,10,10"
TextWrapping="Wrap" Text="" VerticalAlignment="Top"/>
<Button x:Name="btnBuild" Content="Построить" HorizontalAlignment="Left" Height="25"
Margin="31,141,0,0" VerticalAlignment="Top" Width="130" Click="btnBuild_Click"/>
<Button x:Name="btnView" Content="Просмотр" HorizontalAlignment="Left" Height="25"
Margin="189,141,0,0" VerticalAlignment="Top" Width="130" Click="btnView_Click" />
<ListBox x:Name="lbBamlList" HorizontalAlignment="Left" Margin="10,189,10,10"
VerticalAlignment="Stretch" Width="198" SelectionChanged="lbBamlList_SelectionChanged"/>
<Grid x:Name="grid" HorizontalAlignment="Stretch" Margin="236,190,10,10" VerticalAlignment="Stretch" Background="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;
using System.Resources;
namespace WpfBuild
{
public partial class MainWindow : Window
{
List<string> BamlList = new List<string>();
Assembly ass = null;
public MainWindow()
{
InitializeComponent();
btnView.IsEnabled = false;
}
bool BuildProject(string proj, string outdir)
{
if (String.IsNullOrEmpty(proj))
{
MessageBox.Show("Project path not specified", "Error");
return false;
}
if (String.IsNullOrEmpty(outdir))
{
MessageBox.Show("Output path not specified", "Error");
return false;
}
string DotnetPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Windows),
"Microsoft.NET\\Framework\\"
);
try
{
//найдем самую новую версию MSBuild на этой машине...
string[] dirs = Directory.GetDirectories(DotnetPath);
Array.Sort(dirs);
string MSBuildPath = "";
for (int i = dirs.Length - 1; i >= 0; i--)
{
string s = Path.Combine(dirs[i], "msbuild.exe");
if (File.Exists(s))
{
MSBuildPath = s; break;
}
}
if (MSBuildPath == "")
{
throw new FileNotFoundException("Fatal error: MSBuild not found!");
}
//соберем проект через MSBuild...
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = MSBuildPath;
psi.Arguments = String.Format(
"\"{0}\" /property:OutDir=\"{1}\"", proj, outdir
);
psi.WindowStyle = ProcessWindowStyle.Hidden;
Process pr = Process.Start(psi);
pr.WaitForExit();
int code = pr.ExitCode;
if (code == 0)
{
MessageBox.Show("Build success");
return true;
}
else
{
MessageBox.Show("MSBuild error: " + code.ToString());
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().ToString());
return false;
}
}
void ShowWindowFromBaml()
{
object val = lbBamlList.SelectedValue;
if (val == null) return;
string name = Path.GetFileNameWithoutExtension(val.ToString());
try
{
var types = ass.DefinedTypes;
//найдем в сборке класс окна, соответствующий по имени baml-файлу
foreach (TypeInfo type in types)
{
if (type.BaseType == typeof(Window) && type.Name.ToLower() == name.ToLower())
{
//создадим экземпляр окна и отобразим его в Grid'е
Point basepoint = grid.TranslatePoint(new Point(0, 0), this);
Window wnd = (Window)Activator.CreateInstance(type);
wnd.Owner = this;
wnd.Top = basepoint.Y + SystemParameters.CaptionHeight;
wnd.Left = basepoint.X;
wnd.WindowState = System.Windows.WindowState.Normal;
wnd.Show();
return;
}
}
MessageBox.Show("Error: window class not found in assembly");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().ToString());
}
}
private void btnBuild_Click(object sender, RoutedEventArgs e)
{
btnView.IsEnabled = false;
bool success = BuildProject(tbProject.Text, tbOutputDir.Text);
if (!success) return;
try
{
//найдем сборку в выходных файлах MSBuild
string AssPath = Path.Combine(tbOutputDir.Text, Path.GetFileNameWithoutExtension(tbProject.Text) + ".exe");
ass = Assembly.LoadFrom(AssPath);
var names = ass.GetManifestResourceNames();
//найдем все BAML-ресурсы в сборке
BamlList.Clear();
foreach (var s in names)
{
var stream = ass.GetManifestResourceStream(s);
using (ResourceReader reader = new ResourceReader(stream))
{
foreach (System.Collections.DictionaryEntry entry in reader)
{
BamlList.Add(entry.Key.ToString());
}
}
}
lbBamlList.ItemsSource = BamlList;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, ex.GetType().ToString());
}
}
private void btnView_Click(object sender, RoutedEventArgs e)
{
ShowWindowFromBaml(); //отобразим окно для выбранного BAML-файла
}
private void lbBamlList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
object val = lbBamlList.SelectedValue;
if (val != null) btnView.IsEnabled = true;
}
}
}
Автор: VadimTagil