Remove xmlns=“” attribute when adding Reference el

2019-08-27 04:00发布

问题:

I try to programmatic add the reference of dll into csproj file at time of installation service through the MSI Installer.

<Reference Include="TestProject">
    <HintPath>..\..\TestProject.dll</HintPath>
</Reference>

I put below line of source code of add node into
protected override void OnAfterInstall(IDictionary savedState) of ProjectInstaller.cs

var refnode = xml.CreateElement("Reference");
var attribute = xml.CreateAttribute("Include", null);
attribute.Value = "TestProject";
refnode.Attributes.Append(attribute);
var hintPath = xml.CreateNode(XmlNodeType.Element, "HintPath", null);
hintPath.InnerText = "..\..\TestProject.dll";
refnode.AppendChild(hintPath);
xml.AppendChild(refnode);
xml.Save(file);

Output of code

<Reference Include="TestProject" xmlns="">
    <HintPath>..\..\TestProject.dll</HintPath>
</Reference>

But the source code add xmlns="" more attribute into Reference element. what is wrong in this code how I will remove xmlns="" attribute because csproj file not take custom attribute.

回答1:

The default namespace for C# project files is xmlns="http://schemas.microsoft.com/developer/msbuild/2003". You didn't specify any namespace so the namespace had to be cleared to be able to add the children you wanted. Set the right namespaces and you probably won't have a problem.

var ns = "http://schemas.microsoft.com/developer/msbuild/2003";
var refnode = xml.CreateElement("Reference", ns);
var attribute = xml.CreateAttribute("Include", ns);
attribute.Value = "TestProject";
refnode.Attributes.Append(attribute);
var hintPath = xml.CreateNode(XmlNodeType.Element, "HintPath", ns);
hintPath.InnerText = "..\..\TestProject.dll";
refnode.AppendChild(hintPath);
xml.AppendChild(refnode);
xml.Save(file);


回答2:

Although this is not the answer to the original question, I'd like to share what I consider better practices, since I see the design issue behind the question.

When delivering software, one should prefer build-time complexity over install-time complexity.

The first one is fully under developer's control, and the mistake on that phase is not that critical and can be tested. The problem will most likely be caught before it makes damage to the end users.

The latter one is more has much higher effect on the target system. You never know the exact environment you install onto. You can't rely on anything literally. And the mistake on that phase costs much more and is spread in a blink of an eye as people download your software.

So, to repeat myself, prefer build-time complexity over install-time complexity. The installation program should never fix the design issues of the application itself. Leave only those things to the installation time which you can't guess during build.

In your particular case, I suppose you can modify the projects layout during the build in order not to patch project files with DLL references. Teach your build system to include only necessary stuff into the MSI package.

Hope this helps.



回答3:

In your var attribute = xml.CreateAttribute("Include", null); line, you create the attribute with no namespace URI attached. However, in MSBuild files, the default namespace (no namespace prefix) is usually set to xmlns="http://schemas.microsoft.com/developer/msbuild/2003". As you explicitely indicate with your null value that the Include attribute is not associated with that namespace, the Xml writer overrides the default namespace for the respective document fragment.

Try creating your attribute like this:

var attribute = xml.CreateAttribute("Include", "http://schemas.microsoft.com/developer/msbuild/2003");

The same applies to creating the HintPath element a few lines below.