2012-05-31 33 views
10

में तत्वों को सम्मिलित करने के लिए nuget (powerhell) कैसे प्राप्त कर सकता हूं, मैं एक विंडोज सेवा के लिए एक nuget पैकेज लिख रहा हूं, विचार यह है कि मेरे सहयोगी एक विंडोज सेवा बना सकते हैं पैकेज स्थापित करें और सभी डिफ़ॉल्ट लॉगिंग सेटिंग्स, एंटरलिब पुस्तकालयों और अन्य घरों को उनके लिए कार्य स्थापित किया जाएगा। मैं लक्ष्य csproj फ़ाइल

मुझे एक चीज को छोड़कर काम करने के लिए बहुत कुछ मिल गया है जो मुझे पागल कर रहा है।

मेरी nuget निर्देशिका के सामग्री फ़ोल्डर में मेरे पास 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 दिनों के बाद मुझे अंततः एक कामकाजी समाधान मिला। निचे देखो। चेतावनी कॉलिंग प्रोजेक्ट का एक शब्द। सेव() महत्वपूर्ण है - इसके बिना आपको "विवादित फ़ाइल संशोधन पता चला" चेतावनी मिलेगी। यदि आप प्रोजेक्ट को कॉल करते हैं। सेव() पहले आपको केवल एक बार पूरा करने के बाद समाधान को फिर से लोड करने के लिए कहा जाएगा।

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) 

बेशर्म आत्म plugging: I'll do a full write up of the solution and issues I encountered on my blog cianm.com आशा इस कोई वहाँ बाहर कुछ समय बचाता है।

2

यहाँ कि विजुअल स्टूडियो का हिस्सा है Build.Evaluation का उपयोग कर एक छोटी उदाहरण है 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

मुझे लगता है कि यह (और संभवतः अधिक समर्थित) करने के लिए एक आसान तरीका $project चर के लिए अंक के माध्यम से है डीटीई परियोजना।

नोट: मैं इस साल एक साल बाद आ रहा हूं, लेकिन इसी तरह की समस्या का सामना कर रहा हूं। मुझे यह जवाब मिला और इसका उपयोग करना शुरू कर दिया, लेकिन मुझे PowerShell स्क्रिप्ट के अंत में सेव कॉल के साथ परेशानी हुई - अगर मेरे पास एक पैकेज स्थापित हो रहा था जो PowerShell स्क्रिप्ट के साथ पैकेज पर निर्भर था, तो सहेजें कॉल "चीज़ें तोड़ दी" अन्य पैकेज ठीक तरह से स्थापित नहीं हो सका। वैसे भी, अब मैं NuGet 2.5 का उपयोग कर रहा हूं, लेकिन वीटीई 2003 के बाद से किसी भी महत्व के साथ डीटीई नहीं बदला है, इसलिए यह आपके द्वारा उपयोग किए जा रहे पुराने 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) 

उम्मीद है कि है कि भविष्य में लोगों को कुछ इसी तरह पूरा करने के लिए देख मदद करता है। इसे इस तरह से करने से, आप निर्भर पैकेज स्थापित करने में समस्या से बचने में असफल हो जाते हैं क्योंकि प्रोजेक्ट पैकेज के बीच में सहेजा जा रहा है।