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