将Reference元素添加到csproj时删除xmlns =“”属性

时间:2012-06-06 13:44:05

标签: c# xml windows-installer xmldocument csproj

我尝试通过MSI安装程序在安装服务时以编程方式将dll的引用添加到csproj文件中。

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

我将添加节点的源代码行放在下面  ProjectInstaller.cs的protected override void OnAfterInstall(IDictionary savedState)

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

代码输出

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

但是源代码会在Reference元素中添加xmlns=""个更多属性。这段代码有什么问题我将删除xmlns=""属性,因为csproj文件没有自定义属性。

3 个答案:

答案 0 :(得分:2)

C#项目文件的默认命名空间是xmlns="http://schemas.microsoft.com/developer/msbuild/2003"。您没有指定任何名称空间,因此必须清除名称空间才能添加您想要的子项。设置正确的命名空间,你可能不会有问题。

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

答案 1 :(得分:1)

虽然这不是原始问题的答案,但我想分享我认为更好的做法,因为我看到问题背后的设计问题。

在交付软件时,人们应该更喜欢构建时复杂性而不是安装时复杂性。

第一个完全由开发人员控制,该阶段的错误并不重要,可以进行测试。在对最终用户造成损害之前,问题很可能会被捕获。

后者对目标系统的影响要大得多。你永远不知道你安装的确切环境。你不能完全依赖任何东西。当人们下载你的软件时,那个阶段的错误会花费更多,并且会在一眨眼之间传播。

因此,重复一遍,更喜欢构建时复杂性而不是安装时复杂性。安装程序永远不应该修复应用程序本身的设计问题。只保留那些在构建期间无法猜测的安装时间。

在您的特定情况下,我认为您可以在构建期间修改项目布局,以便不使用DLL引用修补项目文件。教你的构建系统只包含必要的东西到MSI包中。

希望这有帮助。

答案 2 :(得分:0)

var attribute = xml.CreateAttribute("Include", null);行中,您创建的属性没有附加名称空间URI。但是,在MSBuild文件中,默认命名空间(无名称空间前缀)通常设置为xmlns="http://schemas.microsoft.com/developer/msbuild/2003"。当您用null值明确指出Include属性与该命名空间无关时,Xml编写器会覆盖相应文档片段的默认命名空间。

尝试创建这样的属性:

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

同样适用于在下面几行创建HintPath元素。