none
Мне нужен компилятор WPF C# приложений RRS feed

  • Вопрос

  • Подскажите где можно найти компилятор приложений С# WPF

    + Мне нужно в программу вставить возможность просмотра XAML файлов чтобы прога видела все кнопки и элементы управления индивидуально.Мне нужен XAML Designer такой как в Visual Studio.

    Помогите пожалуйста, буду очень признателен)

    31 декабря 2018 г. 0:47

Ответы

  • "Подскажите где можно найти компилятор приложений С# WPF"

    MSBuild (https://docs.microsoft.com/ru-ru/visualstudio/msbuild/msbuild?view=vs-2017)

    "Мне нужен XAML Designer такой как в Visual Studio"

    Если нужно работать только с голым XAML, без Code-behind, можно использовать System.Windows.Markup.XamlReader (https://docs.microsoft.com/ru-ru/dotnet/api/system.windows.markup.xamlreader?view=netframework-4.7.2). Однако, когда доходит до XAML с Code-Behind, задача распарсить все это на уровне исходного кода становится неподъемно сложной. Вместо этого, куда проще собрать проект и проанализировать бинарную сборку через Reflection. 

    Вот пример кода для сборки проекта через MSBuild и отображения содержащихся в нем окон.

    XAML:

    <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>


    C#:

    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;
            }
        }
    }



    31 декабря 2018 г. 9:43