Building manually with MS Build fails at references [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am learning the WPF structure in C# and XAML. I believe the best way to learn is without the use of any tools other than a compiler and a basic text editor. Unfortunately, because I refuse to use Visual Studio I have had quite the difficulty running my code.
My Question: I have a basic WPF application with the following structure:
+HelloWorld
|-app.xaml
|-app.proj
|-compile.proj
|+main
|-mainWindow.xaml
|+obj
|+Debug
|-app.g.cs
|+main
|-mainwindow.g.cs
The files of interest are mainwindow.xaml, app.xaml, app.proj, and compile.proj.
I first compile the app.xaml and mainwindow.xaml into generated c# code with this:
msbuild compile.proj /tv:4.0
where compile.proj looks like:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="Microsoft.Build.Tasks.Windows.MarkupCompilePass1"
AssemblyFile="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
<Target Name="MarkupCompilePass1Task">
<MarkupCompilePass1
AssemblyName="HelloWorld"
Language="C#"
OutputType="WinExe"
OutputPath="obj\Debug\"
ApplicationMarkup="App.xaml"
PageMarkup="main\mainwindow.xaml"
References="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Xaml.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\PresentationCore.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\PresentationFramework.dll;C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\WindowsBase.dll" />
</Target>
</Project>
after this (which builds successfully) I compile the generated c# code into an executable. with this:
msbuild app.proj /tv:4.0
The code for app.proj is as follows:
<Project DefaultTargets="Compile"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask
TaskName="Microsoft.Build.Tasks.Windows.MarkupCompilePass1"
AssemblyFile="C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\PresentationBuildTasks.dll" />
<PropertyGroup>
<appname>HelloWorld</appname>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Core.dll" />
<Reference Include="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Xaml.dll" />
<Reference Include="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\WindowsBase.dll" />
<Reference Include="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\PresentationCore.dll" />
<Reference Include="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF\PresentationFramework.dll" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="app.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="G:\Docs\Programming\work\WPF\HelloWorld2\obj\debug\App.g.cs">
<DependentUpon>app.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="main/mainwindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="G:\Docs\Programming\work\WPF\HelloWorld2\obj\debug\main\mainwindow.g.cs">
<DependentUpon>main\mainwindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<Target Name="Compile">
<CSC
Sources = "#(Compile)"
References="#(Reference)"
OutputAssembly ="$(appname).exe">
<Output
TaskParameter = "OutputAssembly"
ItemName = "EXEFile" />
</CSC>
</Target>
</Project>
This also builds successfully. This then creates helloworld.exe. unfortunately when ran, the executable fails saying the following
Unhandled Exception: System.IO.IOException: Cannot locate resource 'main/mainwindow.xaml'.
After this it lists the function trail which ends in:
at HelloWorld.app.Main()
The only other two written files are app.xaml and mainwindow.xaml
app.xaml:
<Application x:Class="HelloWorld2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="main/mainwindow.xaml">
<Application.Resources>
</Application.Resources>
</Application>
mainwindow.xaml:
<Window x:Class="HelloWorld.mainwindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="mainwindow" Height="350" Width="525">
<Grid>
<TextBox Height="23" Width="120" Margin="78,89,319,207" Name="MainTextBox" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left"></TextBox>
</Grid>
</Window>
I have no clue why it can't find the proper xaml file. am I using a improper file structure? Am I missing a compile option on either of the msbuild calls? Thank you for your help.

That MarkupCompilePass1 task is used by MsBuild to perform a preliminary build. Why? Because in order for the XamlCompilePass to be successful, it needs to reference local types in a compiled binary.
Rather than reinvent the wheel, poorly, check out the structure of a WPF project file created by Visual Studio. You'll notice such things like default binary references and default property group values like the following:
<ProjectGuid>{CAFEFCAD-429A-4C61-BD3A-157F042E1FE7}</ProjectGuid>
<OutputType>WinExe</OutputType>
This should get you started on your way to building your WPF projects with MsBuild.
Regarding your issues with Visual Studio and MsBuild, did you know that MsBuild now ships with Visual Studio rather than the .NET Framework?

Related

How to write csproj file if i want to include all files in a specific folder?

|---test.csproj
|---FolderA---
|--- a.cs
|--- b.cs
|---FolderB---
I can write test.csproj file as follow to include all files in FolderA:
<Compile Include="FolderA\*.cs" />
But all files will be displayed at the root view of visual studio, what should I do if I
want to display them in FolderB?
<Folder Include="Class\">
<Compile Include="FolderA\*.cs" />
</Folder>
Code above not works.

Can't find System.Windows.GridLength in ..Net5.0

I'm having trouble converting an application from .NetFramework to .Net5.0. For example, I have a variable of type System.Windiws.GridLength correctly set in Properties.Settings.Default that I can no longer refer to in Net5.0 because it is nowhere to be found (I get the error "System.Windows.GridLength type is not defined" by inserting the type name in the appropriate field in the type selection window shown by choosing the 'Browse' item from the pop-up menu in the 'Type' column of the Settings window). What i am missing?
**** EDIT ************
My project's .csproj as requested:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
<StartupObject>Stats4Betting_NetCore.App</StartupObject>
<ApplicationIcon>Resources\soccer_boom_alt.ico</ApplicationIcon>
<Platforms>AnyCPU;x64;x86</Platforms>
</PropertyGroup>
<ItemGroup>
....
</ItemGroup>
</Project>

Add external font failed but for all fonts

So i try to add external font int my application using this post
Steps:
Add a /Fonts folder to your solution.
Add the True Type Fonts (*.ttf) files to that folder
Include the files to the project
Select the fonts and add them to the solution
Set BuildAction: Resource and Copy To Output Directory: Do not copy. Your .csproj file should now should have a section like this one:
<ItemGroup>
<Resource Include="Fonts\NotoSans-Bold.ttf" />
<Resource Include="Fonts\NotoSans-BoldItalic.ttf" />
<Resource Include="Fonts\NotoSans-Italic.ttf" />
<Resource Include="Fonts\NotoSans-Regular.ttf" />
<Resource Include="Fonts\NotoSansSymbols-Regular.ttf" />
</ItemGroup>
In App.xaml add Resources. It should look like in the following code sample. Note that the URI doesn't contain the filename when packing with the application.
<Applicaton ...>
<Application.Resources>
<FontFamily x:Key="NotoSans">pack://application:,,,/Fonts/#Noto Sans</FontFamily>
<FontFamily x:Key="NotoSansSymbols">pack://application:,,,/Fonts/#Noto Sans Symbols</FontFamily>
</Application.Resources>
</Application>
Apply your Fonts like this:
<TextBlock x:Name="myTextBlock" Text="foobar" FontFamily="{StaticResource NotoSans}"
FontSize="10.0" FontStyle="Normal" FontWeight="Regular" />
So i download several fonts but this works only for some of them.
Any ideas?

How to create multiple partial classes of same xaml file

I need to separate code from a single code behind to multiple partial classes, but didn't know how I can achieve this, I saw in one msdn code sample that this is possible, could you please tell me how I can achieve this.
I know I can move to MVVM, but for now I just need to organize code through partial classes.
Please have a look at the below screenshot.
You can do that by creating the additional files in the naming convention you like and adding the partial class to them. code will compile and work same as before.
MainPage.xaml.cs:
public partial class MainPage : Page {...}
MainPage.Flash.xaml.cs:
public partial class MainPage {...}
To get what you show in the attached image will involve manually editing the project file. Open you project file in a text editor and look at how it is done for your current code behind and the process is the same
Here is an example of what the image you provided would look like in the project file
<ItemGroup>
<Page Include="MainPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="MainPage.ExposureValue.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.Flash.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.Focus.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.IsoSpeed.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.Shutter.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.WhiteBalance.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="MainPage.Zoom.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
</ItemGroup>
Note that with new VS (e.g. VS 2022) and the new SDK-style .csproj files, there are already hidden/automatically generated compile elements for .cs files, so you get an error doing the same as #Nkosi suggests above, as you end up with effectively duplicated compile elements.
Little tweak seems to work for me in these newer csproj files, i.e. just a None (instead of compile) element for each file you want to nest.
<ItemGroup>
<None Include="MainWindow.Helpers.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</None>
</ItemGroup>

Project Item Template: where does Visual Studio specify dependencies?

as explained here http://davidhayden.com/blog/dave/archive/2005/11/05/2556.aspx one can customize project item template.
But at the moment I just try to understand how it works. For example I unzipped the usercontrol file and in usercontrol.vstemplate I cannot see how mycontrol.designer.cs is dependant on mycontrol.cs as this appear in project file as:
<DependentUpon>mycontrol.cs</DependentUpon>
so any idea ?
Update: Could this dependency not specified somewhere in the project type template ? This would be more clever than relying on the IDE heuristic rule which is rather limited since it can only recognize .Designer.cs and not for example .MyCustom.cs.
usercontrol.vstemplate:
<?xml version="1.0" encoding="utf-8"?>
<VSTemplate Version="3.0.0" Type="Item" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
<TemplateData>
<Name Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2295" />
<Description Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2296" />
<Icon Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="4532" />
<TemplateID>Microsoft.CSharp.WindowsFormsUserControl</TemplateID>
<ProjectType>CSharp</ProjectType>
<SortOrder>94</SortOrder>
<RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
<NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>
<DefaultName>UserControl.cs</DefaultName>
</TemplateData>
<TemplateContent>
<References>
<Reference>
<Assembly>System</Assembly>
</Reference>
<Reference>
<Assembly>System.Data</Assembly>
</Reference>
<Reference>
<Assembly>System.Drawing</Assembly>
</Reference>
<Reference>
<Assembly>System.Windows.Forms</Assembly>
</Reference>
<Reference>
<Assembly>System.Xml</Assembly>
</Reference>
</References>
<ProjectItem ReplaceParameters="true" SubType="UserControl">UserControl.cs</ProjectItem>
<ProjectItem ReplaceParameters="true">UserControl.Designer.cs</ProjectItem>
</TemplateContent>
</VSTemplate>
The IDE is smart enough to figure this out by itself. Try this in a sample project: Project + Add New Item, Class, named it Foo.cs. Repeat, now name it Foo.Designer.cs. Note how it automatically becomes a sub-item of Foo.cs. The ".Designer" part of the name matters.
For types the IDE knows like Window it figures it out automatically.
But if you want to combine files that aren't known to the designer/use a different naming pattern for the files you have to manually add tags. I've tried this in a project and I concluded it just wasn't worth the effort, also because the IDE will only automatically rename dependent files it knows of (when you change the file name of the main file).

Categories