2012-05-31 11 views
10

私はWindowsサービスのためのナゲットパッケージを作成しています。私の同僚がパッケージをインストールし、デフォルトのロギング設定、entlibライブラリ、その他のハウスキーピングタスクが設定されます。ターゲットのcsprojファイルに<DependentUpon>要素を挿入するにはどうすればよいですか?

私はナッツを動かす1つのことを除いて、ほとんどすべてを稼働させました。

私のナゲットディレクトリのコンテンツフォルダには、Service.csとService.Designer.csがあります。これらはターゲットのcsprojに追加されていますが、関連していません。

私は私が見るcsprojファイルを見てみると:

<Compile Include="Service.cs"> 
    <SubType>Component</SubType> 
</Compile> 
<Compile Include="Service.Designer.cs" /> 

しかし、私が見たい:

<Compile Include="Service.cs"> 
    <SubType>Component</SubType> 
</Compile> 
<Compile Include="Service.Designer.cs"> 
    <DependentUpon>Service.cs</DependentUpon> 
</Compile> 

任意のアイデアを、かなり確信して、それがinstall.psスクリプトを伴うが、私のPowerShellますスキルは存在しない?

他にも、ファイルを削除/上書きすることはできますか?これまでのところはスキップしているようです。

+0

私はあなたの質問の一部になるはずですので、私は尋ねました。また、NuGetの最新バージョン[1.8](http://nuget.codeplex.com/releases)に対してこれをテストすることをお勧めします。 – Sumo

答えて

12

約2日後にpowershellとmsbuild地獄の後、ついに私は解決策を得ました。下記参照。 project.Save()を呼び出す警告は重要です。これがなければ、 "衝突するファイルの変更が検出されました"という警告が表示されます。 project.Save()を呼び出すと、完了したらすぐにソリューションをリロードするよう求められます。

param($installPath, $toolsPath, $package, $project) 

#save the project file first - this commits the changes made by nuget before this  script runs. 
$project.Save() 

#Load the csproj file into an xml object 
$xml = [XML] (gc $project.FullName) 

#grab the namespace from the project element so your xpath works. 
$nsmgr = New-Object System.Xml.XmlNamespaceManager -ArgumentList $xml.NameTable 
$nsmgr.AddNamespace('a',$xml.Project.GetAttribute("xmlns")) 

#link the service designer to the service.cs 
$node = $xml.Project.SelectSingleNode("//a:Compile[@Include='Service.Designer.cs']", $nsmgr) 
$depUpon = $xml.CreateElement("DependentUpon", $xml.Project.GetAttribute("xmlns")) 
$depUpon.InnerXml = "Service.cs" 
$node.AppendChild($depUpon) 

#link the settings file to the settings.designer.cs 
$settings = $xml.Project.SelectSingleNode("//a:None[@Include='ServiceSettings.settings']", $nsmgr) 
$generator = $xml.CreateElement("Generator", $xml.Project.GetAttribute("xmlns")) 
$generator.InnerXml = "SettingsSingleFileGenerator" 
$settings.AppendChild($generator) 

$LastGenOutput = $xml.CreateElement("LastGenOutput", $xml.Project.GetAttribute("xmlns")) 
$LastGenOutput.InnerXml = "ServiceSettings.Designer.cs" 
$settings.AppendChild($LastGenOutput) 

#set the settings designer to be autogen 
$settingsDesigner = $xml.Project.SelectSingleNode("//a:Compile[@Include='ServiceSettings.Designer.cs']", $nsmgr) 
$autoGen = $xml.CreateElement("AutoGen", $xml.Project.GetAttribute("xmlns")) 
$autoGen.InnerXml = "True" 

$DesignTimeSharedInput = $xml.CreateElement("DesignTimeSharedInput", $xml.Project.GetAttribute("xmlns")) 
$DesignTimeSharedInput.InnerXml = "True" 

$AGDependentUpon = $xml.CreateElement("DependentUpon", $xml.Project.GetAttribute("xmlns")) 
$AGDependentUpon.InnerXml = "ServiceSettings.settings" 

$settingsDesigner.AppendChild($autoGen) 
$settingsDesigner.AppendChild($DesignTimeSharedInput) 
$settingsDesigner.AppendChild($AGDependentUpon) 

#fix up the project installer.  
$projectInstallerRes = $xml.Project.SelectSingleNode("//a:EmbeddedResource[@Include='ProjectInstaller.resx']", $nsmgr) 
$projectInstallerResDepUpon = $xml.CreateElement("DependentUpon", $xml.Project.GetAttribute("xmlns")) 
$projectInstallerResDepUpon.InnerXml = "ProjectInstaller.cs" 
$projectInstallerRes.AppendChild($projectInstallerResDepUpon) 

$projectInstallerDesigner = $xml.Project.SelectSingleNode("//a:Compile[@Include='ProjectInstaller.Designer.cs']", $nsmgr) 
$projectInstallerDesignerDepUpon = $xml.CreateElement("DependentUpon", $xml.Project.GetAttribute("xmlns")) 
$projectInstallerDesignerDepUpon.InnerXml = "ProjectInstaller.cs" 
$projectInstallerDesigner.AppendChild($projectInstallerDesignerDepUpon) 

#delete the bundled program.cs file. 
$prog = $xml.Project.SelectSingleNode("//a:Compile[@Include='Program.cs']", $nsmgr) 
$prog.SelectSingleNode("..").RemoveChild($prog) 

#delete the bundled service1 file 
$oldServiceFile = $xml.Project.SelectSingleNode("//a:Compile[@Include='Service1.cs']", $nsmgr) 
$oldServiceFile.SelectSingleNode("..").RemoveChild($oldServiceFile) 

$oldServiceDesignerFile = $xml.Project.SelectSingleNode("//a:Compile[@Include='Service1.Designer.cs']", $nsmgr) 
$oldServiceDesignerFile.SelectSingleNode("..").RemoveChild($oldServiceDesignerFile) 

#save the changes. 
$xml.Save($project.FullName) 

恥知らずな自己施栓:I'll do a full write up of the solution and issues I encountered on my blog cianm.com が、これはそこに誰かいくつかの時間を節約できます願っています。ここで

2

は、Visual Studioの一部2010+

$buildProject = @([Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.GetLoadedProjects($project.FullName))[0] 


$toEdit = $buildProject.Xml.Items | where-object { $_.Include -eq "Service.Designer.cs" } 
$toEdit.AddMetaData("DependentUpon", "Service.cs") 
# ... for the other files 

$project.Save() 
5

私はこれを行うための簡単な方法を考える(そしておそらくよりサポートされている)であるBuild.Evaluationを使用して簡単な例だ指す$project変数を介してですDTEプロジェクト

注:1年後にこれに着手しますが、同様の問題に直面しています。私はこの答えを見つけ出して使い始めましたが、PowerShellスクリプトの終わりにSave呼び出しに問題がありました。もしPowerShellスクリプトでパッケージに依存しているパッケージが1つインストールされていたら、Save呼び出しは "壊しました"他のパッケージは正しくインストールできませんでした。とにかく、NuGet 2.5を使用していますが、VS 2003以降DTEは何の意味もなく変更されていないので、使用していた古いNuGetでも動作します。

param($installPath, $toolsPath, $package, $project) 

# Selections of items in the project are done with Where-Object rather than 
# direct access into the ProjectItems collection because if the object is 
# moved or doesn't exist then Where-Object will give us a null response rather 
# than the error that DTE will give us. 

# The Service.cs will show with a sub-item if it's already got the designer 
# file set. In the package upgrade scenario, you don't want to re-set all 
# this, so skip it if it's set. 
$service = $project.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "Service.cs" -and $_.ProjectItems.Count -eq 0 } 

if($service -eq $null) 
{ 
    # Upgrade scenario - user has moved/removed the Service.cs 
    # or it already has the sub-items set. 
    return 
} 

$designer = $project.ProjectItems | Where-Object { $_.Properties.Item("Filename").Value -eq "Service.Designer.cs" } 

if($designer -eq $null) 
{ 
    # Upgrade scenario - user has moved/removed the Service.Desginer.cs. 
    return 
} 

# Here's where you set the designer to be a dependent file of 
# the primary code file. 
$service.ProjectItems.AddFromFile($designer.Properties.Item("FullPath").Value) 

似た何かを達成するために探して、将来的に人々を助けうまくいけば。このようにすると、依存関係のあるパッケージのインストールで問題が発生するのを避けることができます。これは、パッケージのインストール中にプロジェクトが保存されるためです。

関連する問題