I have made a small C# application, with 1 solution and 2 projects (test1
,test2
). The first project have two files Program.cs
and function1.cs
, while second project consist of only Program2.cs
.
Project test1
creates .exe
file, and test2
creates .dll
file.
The problem is when I try to build it as VS creates .csproj it runs fine, but when I tried to edit that .csproj (or write my own) to implement incremental build (as it was in example on MS sites) it throws an CS0246
The type or namespace name 'type/namespace' could not be found (are you missing a using directive or an assembly reference?)
Despite that I have added the references first to test2.csproj
, and then to .dll
that it creates, and also using the using
directive.
The same error occurs when I try to run in command prompt
csc.exe program.cs function1.cs
but it can be quickly fixed by adding the /:r
with the .dll
as in example:
\csc.exe program.cs function1.cs /r:test2.dll
And then it runs fine. I just simply dont know how to acknowledge msbuild of that reference between files. And I'm also forced to used cmd instead of building it inside VS.
Below I put code that I use in my project.
Here's the snippet that I'm adding at the end of test1.csproj
to force it into incremental build:
<ItemGroup>
<Compile Include="function1.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Target Name="program2">
<MSBuild Projects="..\test2\test2.csproj" />
<Message Text="Target program 2" />
</Target>
<Target Name="Compile" Inputs="@(Compile)" Outputs="$(OutputPath) $(AssemblyName).exe" DependsOnTargets="program2">
<Message Text="Target program 1" />
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" />
</Target>
Here's the code for Program.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test1
{
class Program
{
static void Main(string[] args)
{
int a;
int b;
string pause;
function1 var = new function1();
a = Convert.ToInt32(Console.ReadLine());
b = var.funkcja1(a);
Console.WriteLine(b);
pause = Console.ReadLine();
}
}
}
Here's function1.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using test2;
namespace test1
{
class function1
{
public int funkcja1(int a)
{
int b;
Program2 p2 = new Program2();
b = p2.program2(a);
return (b);
}
}
}
And here's code for Program2.cs
:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace test2
{
public class Program2
{
public class function2
{
public int funkcja2(int a)
{
return (a + 1);
}
}
public int program2(int c)
{
int d;
function2 var = new function2();
d = var.funkcja2(c) + 1;
return (d);
}
public static void Main(string[] args)
{
string pause;
pause = Console.ReadLine();
}
}
}
CS0246 error while creating incremental build
You should specify the reference when you build it with csc.exe
, like References="..\test2\bin\Debug\test2.dll"
, otherwise, csc.exe could not know the test.dll is referenced by the test1.project, so the target Compile
looks like:
<Target Name="Compile" Inputs="@(Compile)" Outputs="$(OutputPath) $(AssemblyName).exe" DependsOnTargets="program2">
<Message Text="Target program 1" />
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" References="..\test2\bin\Debug\test2.dll" />
</Target>
Besides, AFAIK, you should not edit that .csproj (or write my own) to implement incremental build directly. That because when you build the project test1, Visual Studio/MSBuild has already used incremental build by default, we do not need to incremental build it again. If you are want to implement incremental build, you can create a mini MSBuild Project File to implement incremental build. I have created a new Test.proj
under the test1 project folder with following code:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Compile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Include="function1.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<PropertyGroup>
<AssemblyName>MSBuildTestSample</AssemblyName>
<OutputPath>Bin\</OutputPath>
</PropertyGroup>
<Target Name="program2">
<MSBuild Projects="..\test2\test2.csproj" />
<Message Text="Target program 2" />
</Target>
<Target Name="Compile" Inputs="@(Compile)" Outputs="$(OutputPath) $(AssemblyName).exe" DependsOnTargets="program2">
<Message Text="Target program 1" />
<MakeDir Directories="$(OutputPath)" Condition="!Exists('$OutputPath)')" />
<Csc Sources="@(Compile)" OutputAssembly="$(OutputPath)$(AssemblyName).exe" References="..\test2\bin\Debug\test2.dll" />
</Target>
</Project>
Then we could build this Test.proj
file with MSBuild command line.
Hope this helps.