कस्टम MSBuild कार्य बनाते समय आपको C # कोड से वर्तमान प्रोजेक्ट निर्देशिका कैसे मिलती है?


133

बजाय इसके हार्डकोड के साथ एक बाहरी कार्यक्रम चलाने के बजाय, मैं वर्तमान प्रोजेक्ट डिर को प्राप्त करना चाहूंगा। मैं कस्टम कार्य में एक प्रक्रिया का उपयोग करके एक बाहरी कार्यक्रम को बुला रहा हूं।

मुझे यह कैसे करना है? AppDomain.CurrentDomain.BaseDirectory मुझे केवल VS 2008 का स्थान देता है।

जवाबों:


112

आप इस दो तरीकों में से एक को आजमा सकते हैं।

string startupPath = System.IO.Directory.GetCurrentDirectory();

string startupPath = Environment.CurrentDirectory;

मुझे बताओ, जो आपको बेहतर लगता है


85
ये दोनों उपरोक्त आपको बिन निर्देशिका के लिए इंगित करते हैं, इसलिए यदि आपके पास आपके संपूर्ण समाधान के लिए एक बिन निर्देशिका है, तो यह आपको वहां इंगित करेगा और आपकी परियोजना निर्देशिका के लिए नहीं (या दो स्तर अपनी परियोजना निर्देशिका को कम करेगा)
matcheek

16
टेस्ट एक्सप्लोरर का उपयोग करते समय दोनों समाधान अपेक्षा के अनुरूप काम नहीं करेंगे।
Gucu112

264
using System;
using System.IO;

// This will get the current WORKING directory (i.e. \bin\Debug)
string workingDirectory = Environment.CurrentDirectory;
// or: Directory.GetCurrentDirectory() gives the same result

// This will get the current PROJECT directory
string projectDirectory = Directory.GetParent(workingDirectory).Parent.FullName;

25
+1 के लिए Directory.GetParent () तो हमें \ Bin \ Debug निर्देशिका नहीं मिलती है :)
Eystein Bye

5
यदि हम कस्टम लक्ष्य CPU का उपयोग करते हैं तो क्या होगा? उदाहरण के लिए, यदि मैंने x64 को लक्षित करने के लिए अपना निर्माण सेट किया है तो यह उन दोनों के बीच एक और फ़ोल्डर बनाता है।
समीर अगुइर

3
यह सही जवाब है। स्वीकृत उत्तर बिन निर्देशिका के लिए पथ देता है, जो परियोजना निर्देशिका नहीं है।
pookie

@ pookie का उत्तर मेरे मामले के लिए पुनरावर्ती रूप से गलत है। यह मुझे * / {प्रोजेक्ट} / बिन फ़ोल्डर दे रहा है, इसलिए मुझे एक .parent को सम्‍मिलित करना होगा।
कप्तान प्रिंसेस

1
अच्छी तरह से काम करना और यह स्वीकृत उत्तर होना चाहिए
अशोक कुमार गणेशन

42

यदि कोई प्रोजेक्ट IIS एक्सप्रेस पर चल रहा है, तो Environment.CurrentDirectoryयह इंगित कर सकता है कि IIS एक्सप्रेस कहाँ स्थित है (डिफ़ॉल्ट पथ C: \ Program Files (x86) \ IIS एक्सप्रेस होगा ), न कि जहाँ आपका प्रोजेक्ट रहता है।


यह संभवतः विभिन्न प्रकार की परियोजनाओं के लिए सबसे उपयुक्त निर्देशिका पथ है।

AppDomain.CurrentDomain.BaseDirectory

यह MSDN परिभाषा है।

असेंबली रिज़ॉल्वर असेंबली के लिए जांच करने के लिए उपयोग करता है कि आधार निर्देशिका हो जाता है।


21
9 साल बाद और किसी के पास वास्तव में असली जवाब है।
जेफ डेविस

.NET Core में कोई AppDomain नहीं है। आपको ऐसा कुछ करना होगा। System.Runtime.Loader.AssemblyLoadContext.Default.Unloading + = संदर्भ => InvokeBatchProcessors ();
लेटेंसी

इसके अलावा, आप Visual Studio SDK का उपयोग कर सकते हैं और DTE2 का उपयोग करके समाधान कॉन्फ़िगरेशन लेआउट से स्थान प्राप्त कर सकते हैं।
लेटेंसी

2
@Latency में एक .net कोर 3 WPF प्रोजेक्ट है
अलेक्जेंडर

हाँ, मैं ऐनक पढ़ता हूँ। 3,0 जैसा कुछ भी सुनिश्चित नहीं है। मैं तब से इसका इस्तेमाल कर रहा हूं। बहुत खुश। मुझे लगता है कि मैंने इस प्री 3.0 को पोस्ट किया ताकि स्पष्टीकरण के लिए धन्यवाद।
लेटेंसी

18

यह आपको मौजूदा निष्पादन निर्देशिका से दो स्तरों को नेविगेट करके परियोजना निर्देशिका भी देगा (यह प्रत्येक बिल्ड के लिए परियोजना निर्देशिका वापस नहीं करेगा, लेकिन यह सबसे आम है)।

System.IO.Path.GetFullPath(@"..\..\")

बेशक आप इसे किसी प्रकार के सत्यापन / त्रुटि से निपटने के तर्क के अंदर समाहित करना चाहेंगे।


IMO यह सबसे लचीली विधि है। मैं यूनिट परीक्षणों और एकीकरण परीक्षणों से इसका उपयोग कर रहा हूं, जो पथ वास्तव में एक फ़ोल्डर से अधिक गहरा है।
सोइल - मैथ्यू प्रेवोट

यह मुझे किसी कारण से रूट ड्राइव दे रहा है।
कप्तान प्रिन्स

10

यदि आप चाहते हैं कि ओ.टी. पता है कि वह निर्देशिका क्या है जहाँ आपका समाधान स्थित है, तो आपको यह करने की आवश्यकता है:

 var parent = Directory.GetParent(Directory.GetCurrentDirectory()).Parent;
            if (parent != null)
            {
                var directoryInfo = parent.Parent;
                string startDirectory = null;
                if (directoryInfo != null)
                {
                    startDirectory = directoryInfo.FullName;
                }
                if (startDirectory != null)
                { /*Do whatever you want "startDirectory" variable*/}
            }

यदि आप केवल GetCurrrentDirectory()विधि के साथ करते हैं, तो आप डिबगिंग या विमोचन कर रहे हैं, तो कोई फर्क नहीं पड़ता। मुझे उम्मीद है कि इस मदद! यदि आप मान्यताओं के बारे में भूल जाते हैं तो यह इस तरह होगा:

var startDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).Parent.Parent.FullName;

5

मैं भी यही चाह रहा था। मुझे एक प्रोजेक्ट मिला है जो HWC चलाता है, और मैं वेब साइट को ऐप ट्री से बाहर रखना चाहूंगा, लेकिन मैं इसे डिबग (या रिलीज़) निर्देशिका में नहीं रखना चाहता। एफडब्ल्यूआईडब्ल्यू, स्वीकृत समाधान (और यह एक भी) केवल उस निर्देशिका की पहचान करता है जिसमें निष्पादन योग्य चल रहा है।

उस निर्देशिका को खोजने के लिए, मैं उपयोग कर रहा हूं

string startupPath = System.IO.Path.GetFullPath(".\\").

5

Gucu112 के उत्तर के आधार पर , लेकिन .NET कोर कंसोल / विंडो एप्लिकेशन के लिए, यह होना चाहिए:

string projectDir = 
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\.."));

मैं एक .NET कोर विंडो एप्लिकेशन के लिए xUnit प्रोजेक्ट में इसका उपयोग कर रहा हूं।


4

ऐसा करने का दूसरा तरीका

string startupPath = System.IO.Directory.GetParent(@"./").FullName;

अगर आप बिन फोल्डर का रास्ता पाना चाहते हैं

string startupPath = System.IO.Directory.GetParent(@"../").FullName;

हो सकता है बेहतर तरीका =)


4

अभी तक एक और अपूर्ण समाधान (लेकिन शायद दूसरों के मुकाबले कुछ हद तक सही है):

    protected static string GetSolutionFSPath() {
        return System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.Parent.FullName;
    }
    protected static string GetProjectFSPath() {
        return String.Format("{0}\\{1}", GetSolutionFSPath(), System.Reflection.Assembly.GetExecutingAssembly().GetName().Name);
    }

यह संस्करण वर्तमान प्रोजेक्ट के फ़ोल्डर को वापस कर देगा भले ही वर्तमान प्रोजेक्ट Startup Projectसमाधान के लिए न हो ।

इसके साथ पहला दोष यह है कि मैंने सभी त्रुटि जाँच को छोड़ दिया है। यह काफी आसान तय किया जा सकता है, लेकिन केवल एक समस्या होनी चाहिए यदि आप ड्राइव के लिए रूट डायरेक्टरी में अपना प्रोजेक्ट स्टोर कर रहे हैं या अपने रास्ते में एक जंक्शन का उपयोग कर रहे हैं (और यह जंक्शन समाधान फ़ोल्डर का वंशज है) तो इस परिदृश्य की संभावना नहीं है । मुझे पूरा यकीन नहीं है कि विज़ुअल स्टूडियो इन सेटअपों में से किसी भी तरह से संभाल सकता है।

एक और (अधिक संभावना) समस्या जिसे आप चला सकते हैं, वह यह है कि प्रोजेक्ट का नाम प्रोजेक्ट के लिए फ़ोल्डर के नाम से मेल खाना चाहिए

आपके पास एक और समस्या यह हो सकती है कि परियोजना समाधान फ़ोल्डर के अंदर होनी चाहिए। यह आमतौर पर कोई समस्या नहीं है, लेकिन यदि आपने Add Existing Project to Solutionसमाधान में परियोजना को जोड़ने के लिए विकल्प का उपयोग किया है, तो यह आपके समाधान को व्यवस्थित करने का तरीका नहीं हो सकता है।

अंत में, यदि आप आवेदन कर रहे हैं, तो आप कार्यशील निर्देशिका को संशोधित कर रहे हैं, आपको यह मान जमा करने से पहले करना चाहिए क्योंकि यह मान वर्तमान कार्यशील निर्देशिका के सापेक्ष निर्धारित होता है।

बेशक, यह सब भी इसका मतलब है कि आपको अपनी परियोजनाओं के लिए डिफ़ॉल्ट मानों में परिवर्तन नहीं करना चाहिए Build-> Output pathया Debug-> Working directoryपरियोजना गुण संवाद में विकल्प।



4

यह समाधान मेरे लिए अच्छी तरह से काम करता है, विकास पर और साथ ही ASP.NET MVC5 के साथ TEST और PROD सर्वरों पर C # :

var projectDir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);

यदि आपको प्रोजेक्ट कॉन्फ़िगरेशन फ़ाइल उपयोग में प्रोजेक्ट निर्देशिका की आवश्यकता है :

$(ProjectDir)

3

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

सबसे पहले, आपको Microsoft.in32 नामस्थान को शामिल करना होगा ताकि आप रजिस्ट्री के साथ काम कर सकें:

using Microsoft.Win32;    // required for reading and / or writing the registry

यहाँ मुख्य कोड है:

RegistryKey Projects_Key = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\VisualStudio\9.0", false);
string DirProject = (string)Projects_Key.GetValue(@"DefaultNewProjectLocation");

इस उत्तर पर एक नोट:

मैं विजुअल स्टूडियो 2008 प्रोफेशनल संस्करण का उपयोग कर रहा हूं। यदि आप किसी अन्य संस्करण का उपयोग कर रहे हैं, (यानी 2003, 2005, 2010; आदि), तो आपको उप-स्ट्रिंग (यानी 8.0, 7.0; आदि) के 'संस्करण' भाग को संशोधित करना होगा।

यदि आप मेरे किसी एक उत्तर का उपयोग करते हैं, और यदि यह पूछने के लिए बहुत अधिक नहीं है, तो मैं जानना चाहूंगा कि आपने मेरे कौन से तरीकों का इस्तेमाल किया और क्यों। सौभाग्य।

  • dm

3

मेरे पास एक समान स्थिति थी, और फलहीन गूगल्स के बाद, मैंने एक सार्वजनिक स्ट्रिंग घोषित की, जो प्रोजेक्ट पथ को प्राप्त करने के लिए डीबग / रिलीज़ पथ के एक स्ट्रिंग मान को नियंत्रित करता है। इस पद्धति का उपयोग करने का एक लाभ यह है कि चूंकि यह क्यूरेट प्रोजेक्ट की डायरेक्टरी का उपयोग करता है, इसलिए यह मायने नहीं रखता कि आप डिबग डायरेक्टरी या रिलीज़ डायरेक्टरी से काम कर रहे हैं:

public string DirProject()
{
    string DirDebug = System.IO.Directory.GetCurrentDirectory();
    string DirProject = DirDebug;

    for (int counter_slash = 0; counter_slash < 4; counter_slash++)
    {
        DirProject = DirProject.Substring(0, DirProject.LastIndexOf(@"\"));
    }

    return DirProject;
}

आप केवल एक लाइन का उपयोग करके, जब चाहें तब इसे कॉल कर पाएंगे:

string MyProjectDir = DirProject();

यह ज्यादातर मामलों में काम करना चाहिए ।


3

प्रोजेक्ट निर्देशिका (मेरे लिए काम किया) प्राप्त करने के लिए इसका उपयोग करें:

string projectPath = 
    Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName;

3
using System;
using System.IO;

// Get the current directory and make it a DirectoryInfo object.
// Do not use Environment.CurrentDirectory, vistual studio 
// and visual studio code will return different result:
// Visual studio will return @"projectDir\bin\Release\netcoreapp2.0\", yet 
// vs code will return @"projectDir\"
var currentDirectory = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

// On windows, the current directory is the compiled binary sits,
// so string like @"bin\Release\netcoreapp2.0\" will follow the project directory. 
// Hense, the project directory is the great grand-father of the current directory.
string projectDirectory = currentDirectory.Parent.Parent.Parent.FullName;

2

मैंने काम पाने के लिए निम्नलिखित उपाय का उपयोग किया है:

string projectDir =
    Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\.."));

2

प्रयत्न:

var pathRegex = new Regex(@"\\bin(\\x86|\\x64)?\\(Debug|Release)$", RegexOptions.Compiled);
var directory = pathRegex.Replace(Directory.GetCurrentDirectory(), String.Empty);

यह अन्य x86 या x64 बिल्ड को भी ध्यान में रखते हुए अलग है।


यह समाधान लगभग नई csproj फ़ाइलों के लिए भी है जहाँ TargetFramework पथ में शामिल है।
ग्लेन वॉटसन

1
नए .netcore शैली प्रारूप के लिए मेरे पास नया Regex (@ "\\ bin (\\ x86 | \ x64) है?" , RegexOptions.Compiled)
ग्लेन वॉटसन

1

सबसे अच्छा समाधान

string PjFolder1 =
    Directory.GetParent(AppDomain.CurrentDomain.BaseDirectory).
        Parent.Parent.FullName;

अन्य समाधान

string pjFolder2 = Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(
                System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)));

यह परीक्षण करें, AppDomain.CurrentDomain.BaseDirectory ने मेरे लिए पिछले प्रोजेक्ट पर काम किया, अब मुझे डिबग फ़ोल्डर मिल गया .... चयनित अच्छा जवाब अभी काम नहीं करता है!।

//Project DEBUG folder, but STILL PROJECT FOLDER
string pjDebugFolder = AppDomain.CurrentDomain.BaseDirectory;

//Visual studio folder, NOT PROJECT FOLDER
//This solutions just not work
string vsFolder = Directory.GetCurrentDirectory();
string vsFolder2 = Environment.CurrentDirectory;
string vsFolder3 = Path.GetFullPath(".\\");   

//Current PROJECT FOLDER
string ProjectFolder = 
    //Get Debug Folder object from BaseDirectory ( the same with end slash)
    Directory.GetParent(pjDebugFolder).
    Parent.//Bin Folder object
    Parent. //Project Folder object
    FullName;//Project Folder complete path

0

यदि आप वास्तव में यह सुनिश्चित करना चाहते हैं कि आपको स्रोत प्रोजेक्ट डायरेक्टरी मिले, तो कोई फर्क नहीं पड़ता कि बिन आउटपुट पथ किस पर सेट है:

  1. प्री-बिल्ड इवेंट कमांड लाइन (विजुअल स्टूडियो: प्रोजेक्ट प्रॉपर्टीज़ -> बिल्ड इवेंट्स) जोड़ें:

    echo $(MSBuildProjectDirectory) > $(MSBuildProjectDirectory)\Resources\ProjectDirectory.txt

  2. ProjectDirectory.txtप्रोजेक्ट के Resources.resx में फ़ाइल जोड़ें (यदि यह अभी तक मौजूद नहीं है, तो राइट क्लिक प्रोजेक्ट -> नया आइटम जोड़ें -> संसाधन फ़ाइल)

  3. के साथ कोड से पहुँच Resources.ProjectDirectory

-1

यह VS2017 w / SDK कोर MSBuild कॉन्फ़िगरेशन पर काम करता है।

आपको EnvDTE / EnvDTE80 पैकेज में NuGet की आवश्यकता है।

COM या इंटरॉप का उपयोग न करें। कुछ भी .... कचरा !!

 internal class Program {
    private static readonly DTE2 _dte2;

    // Static Constructor
    static Program() {
      _dte2 = (DTE2)Marshal.GetActiveObject("VisualStudio.DTE.15.0");
    }


    private static void FindProjectsIn(ProjectItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      if (item.ProjectItems != null)
        foreach (ProjectItem innerItem in item.ProjectItems)
          FindProjectsIn(innerItem, results);
    }


    private static void FindProjectsIn(UIHierarchyItem item, List<Project> results) {
      if (item.Object is Project) {
        var proj = (Project) item.Object;
        if (new Guid(proj.Kind) != new Guid(Constants.vsProjectItemKindPhysicalFolder))
          results.Add((Project) item.Object);
        else
          foreach (ProjectItem innerItem in proj.ProjectItems)
            FindProjectsIn(innerItem, results);
      }

      foreach (UIHierarchyItem innerItem in item.UIHierarchyItems)
        FindProjectsIn(innerItem, results);
    }


    private static IEnumerable<Project> GetEnvDTEProjectsInSolution() {
      var ret = new List<Project>();
      var hierarchy = _dte2.ToolWindows.SolutionExplorer;
      foreach (UIHierarchyItem innerItem in hierarchy.UIHierarchyItems)
        FindProjectsIn(innerItem, ret);
      return ret;
    }


    private static void Main() {
      var projects = GetEnvDTEProjectsInSolution();
      var solutiondir = Path.GetDirectoryName(_dte2.Solution.FullName);

      // TODO
      ...

      var project = projects.FirstOrDefault(p => p.Name == <current project>);
      Console.WriteLine(project.FullName);
    }
  }

-6

Directory.GetParent (Directory.GetCurrentDirectory ())। Parent.Parent.Parent.Parent.FullName

आपको प्रोजेक्ट डायरेक्टरी देगा।


77
वास्तव में? मुझे लगता है कि आपको
शॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.