c# - मैं कोड में असेंबली का मार्ग कैसे प्राप्त करूं?




.net reflection (18)

क्या असेंबली के लिए रास्ता पाने का कोई तरीका है जिसमें वर्तमान कोड रहता है? मैं कॉलिंग असेंबली का मार्ग नहीं चाहता, केवल कोड वाला एक।

मूल रूप से मेरे यूनिट परीक्षण को कुछ एक्सएमएल परीक्षण फ़ाइलों को पढ़ने की आवश्यकता होती है जो डीएलएल के सापेक्ष स्थित होते हैं। मैं परीक्षण डीएल को TestDriven.NET, MbUnit GUI या कुछ और से चलाने के बावजूद सही ढंग से हल करने का मार्ग चाहता हूं।

संपादित करें : लोग जो मैं पूछ रहा हूं उसे गलत समझना प्रतीत होता है।

मेरी टेस्ट लाइब्रेरी कहने में स्थित है

C: \ परियोजनाओं \ myapplication \ daotests \ बिन \ डीबग \ daotests.dll

और मैं यह रास्ता प्राप्त करना चाहता हूं:

C: \ परियोजनाओं \ myapplication \ daotests \ बिन \ डीबग \

जब मैं एमबीयूनीट गुई से भागता हूं तो तीन सुझाव अब तक विफल हो जाते हैं:

  • Environment.CurrentDirectory डायरेक्टरी सी: \ प्रोग्राम फ़ाइलें \ MbUnit देता है

  • System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location सी: \ दस्तावेज़ और सेटिंग्स \ george \ स्थानीय सेटिंग्स \ Temp \ .... \ DaoTests.dll देता है

  • System.Reflection.Assembly.GetExecutingAssembly().Location पिछले जैसा ही देता है।


अतीत में मुझे NUnit में वही व्यवहार मिला। डिफ़ॉल्ट रूप से NUnit आपकी असेंबली को temp निर्देशिका में कॉपी करता है। आप इस व्यवहार को NUnit सेटिंग्स में बदल सकते हैं:

शायद TestDriven.NET और MbUnit GUI में एक ही सेटिंग है।


आप AppDomain.CurrentDomain.RelativeSearchPath द्वारा बिन पथ प्राप्त कर सकते हैं


इस बारे में कैसा है ...

string ThisdllDirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

फिर बस उस चीज़ को हैक करें जिसे आपको आवश्यकता नहीं है


इस बारे में क्या:

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

क्या यह मदद करता है?

//get the full location of the assembly with DaoTests in it
string fullPath = System.Reflection.Assembly.GetAssembly(typeof(DaoTests)).Location;

//get the folder that's in
string theDirectory = Path.GetDirectoryName( fullPath );

जहां तक ​​मैं कह सकता हूं, अधिकांश अन्य उत्तरों में कुछ समस्याएं हैं।

डिस्क-आधारित (वेब-आधारित के विपरीत) के लिए ऐसा करने का सही तरीका , गैर-जीएसीड असेंबली वर्तमान में निष्पादित असेंबली की CodeBase संपत्ति का उपयोग करना है।

यह एक यूआरएल ( file:// ) देता है। स्ट्रिंग मैनिपुलेशन या UnescapeDataString साथ घूमने के बजाय, इसे UnescapeDataString संपत्ति का लाभ उठाकर न्यूनतम गड़बड़ी के साथ परिवर्तित किया जा सकता है।

var codeBaseUrl = Assembly.GetExecutingAssembly().CodeBase;
var filePathToCodeBase = new Uri(codeBaseUrl).LocalPath;
var directoryPath = Path.GetDirectoryName(filePathToCodeBase);

जॉन सिली के कोड का वीबीएनईटी पोर्ट यहां है। विजुअल बेसिक केस संवेदनशील नहीं है, इसलिए उसके कुछ परिवर्तनीय नाम टाइप नामों के साथ टकरा रहे थे।

Public Shared ReadOnly Property AssemblyDirectory() As String
    Get
        Dim codeBase As String = Assembly.GetExecutingAssembly().CodeBase
        Dim uriBuilder As New UriBuilder(codeBase)
        Dim assemblyPath As String = Uri.UnescapeDataString(uriBuilder.Path)
        Return Path.GetDirectoryName(assemblyPath)
    End Get
End Property

मुझे संदेह है कि असली मुद्दा यह है कि आपका परीक्षण धावक आपकी असेंबली को एक अलग स्थान पर कॉपी कर रहा है। रनटाइम पर कोई रास्ता नहीं है कि यह कहने के लिए कि असेंबली की प्रतिलिपि बनाई गई थी, लेकिन आप संभवतः एक असेंबली को चलाने के लिए परीक्षण धावक को यह कहने के लिए कह सकते हैं कि यह कहां है और इसे छाया निर्देशिका में कॉपी नहीं करना है।

निश्चित रूप से प्रत्येक परीक्षण धावक के लिए ऐसा स्विच अलग होने की संभावना है।

क्या आपने अपने एक्सएमएल डेटा को अपनी टेस्ट असेंबली के अंदर संसाधनों के रूप में एम्बेड करने पर विचार किया है?


मैं इसका उपयोग बिन निर्देशिका का मार्ग पाने के लिए करता हूं:

var i = Environment.CurrentDirectory.LastIndexOf(@"\");
var path = Environment.CurrentDirectory.Substring(0,i); 

आपको यह परिणाम मिलता है:

"सी: \ उपयोगकर्ता \ ricooley \ दस्तावेज़ \ दृश्य स्टूडियो 2010 \ प्रोजेक्ट्स \ Windows_Test_Project \ Windows_Test_Project \ bin"


मैं स्थान के बजाय विधानसभा.कोडबेस का उपयोग कर रहा हूं:

Assembly a;
a = Assembly.GetAssembly(typeof(DaoTests));
string s = a.CodeBase.ToUpper(); // file:///c:/path/name.dll
Assert.AreEqual(true, s.StartsWith("FILE://"), "CodeBase is " + s);
s = s.Substring(7, s.LastIndexOf('/') - 7); // 7 = "file://"
while (s.StartsWith("/")) {
    s = s.Substring(1, s.Length - 1);
}
s = s.Replace("/", "\\");

यह काम कर रहा है, लेकिन मुझे यकीन नहीं है कि यह 100% सही है। http://blogs.msdn.com/suzcook/archive/2003/06/26/assembly-codebase-vs-assembly-location.aspx पर पृष्ठ कहता है:

"कोडबेस उस स्थान पर एक यूआरएल है जहां फ़ाइल मिली थी, जबकि स्थान वह पथ है जहां इसे वास्तव में लोड किया गया था। उदाहरण के लिए, यदि इंटरनेट से असेंबली डाउनलोड की गई थी, तो इसका कोडबेस" http: // "से शुरू हो सकता है। , लेकिन इसका स्थान "सी: \" से शुरू हो सकता है। अगर फ़ाइल छाया-प्रतिलिपि बनाई गई थी, तो स्थान छाया प्रतिलिपि में फ़ाइल की प्रतिलिपि का मार्ग होगा। यह जानना भी अच्छा है कि कोडबेस की गारंटी नहीं है जीएसी में असेंबली के लिए सेट किया जाएगा। स्थान हमेशा डिस्क से लोड असेंबली के लिए सेट किया जाएगा। "

आप स्थान के बजाय कोडबेस का उपयोग करना चाह सकते हैं।


मैंने ये ढूंढ निकाला। वेब परियोजनाओं के बीच, यूनिट परीक्षण (नूनिट और रिशेर्पर टेस्ट धावक) ; मैंने पाया यह मेरे लिए काम किया।

मैं यह पता लगाने के लिए कोड ढूंढ रहा हूं कि निर्माण में कौन सी कॉन्फ़िगरेशन है, Debug/Release/CustomName । हां, #if DEBUGतो अगर कोई इसे सुधार सकता है !

संपादित करने और सुधारने के लिए स्वतंत्र महसूस करें।

ऐप फ़ोल्डर प्राप्त करना वेब जड़ों के लिए उपयोगी, परीक्षण फ़ाइलों के फ़ोल्डर को पाने के लिए unittests।

public static string AppPath
{
    get
    {
        DirectoryInfo appPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory);

        while (appPath.FullName.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
                || appPath.FullName.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            appPath = appPath.Parent;
        }
        return appPath.FullName;
    }
}

बिन फ़ोल्डर प्राप्त करना : प्रतिबिंब का उपयोग करके असेंबली निष्पादित करने के लिए उपयोगी। यदि निर्माण गुणों के कारण फाइलों की प्रतिलिपि बनाई गई है।

public static string BinPath
{
    get
    {
        string binPath = AppDomain.CurrentDomain.BaseDirectory;

        if (!binPath.Contains(@"\bin\", StringComparison.CurrentCultureIgnoreCase)
            && !binPath.EndsWith(@"\bin", StringComparison.CurrentCultureIgnoreCase))
        {
            binPath = Path.Combine(binPath, "bin");
            //-- Please improve this if there is a better way
            //-- Also note that apps like webapps do not have a debug or release folder. So we would just return bin.
#if DEBUG
            if (Directory.Exists(Path.Combine(binPath, "Debug"))) 
                        binPath = Path.Combine(binPath, "Debug");
#else
            if (Directory.Exists(Path.Combine(binPath, "Release"))) 
                        binPath = Path.Combine(binPath, "Release");
#endif
        }
            return binPath;
    }
}

यह उतना आसान है जितना:

var dir = AppDomain.CurrentDomain.BaseDirectory;

यह काम करना चाहिए:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
Assembly asm = Assembly.GetCallingAssembly();
String path = Path.GetDirectoryName(new Uri(asm.EscapedCodeBase).LocalPath);

string strLog4NetConfigPath = System.IO.Path.Combine(path, "log4net.config");

मैं कुछ विन्यास फाइल के साथ डीएलएल फ़ाइल पुस्तकालयों को तैनात करने के लिए इसका उपयोग कर रहा हूं (यह DLL फ़ाइल के भीतर से लॉग 4नेट का उपयोग करना है)।


वर्तमान निर्देशिका जहां आप मौजूद हैं।

Environment.CurrentDirectory;  // This is the current directory of your application

यदि आप निर्माण के साथ .xml फ़ाइल को कॉपी करते हैं तो आपको इसे ढूंढना चाहिए।

या

System.Reflection.Assembly assembly = System.Reflection.Assembly.GetAssembly(typeof(SomeObject));

// The location of the Assembly
assembly.Location;

वेब एप्लीकेशन?

Server.MapPath("~/MyDir/MyFile.ext")

सभी प्रस्तावित उत्तर काम करते हैं जब डेवलपर आवश्यक स्निपेट को शामिल करने के लिए कोड बदल सकता है, लेकिन यदि आप किसी भी कोड को बदलने के बिना ऐसा करना चाहते हैं तो आप प्रोसेस एक्सप्लोरर का उपयोग कर सकते हैं।

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

मैंने द्वितीय के अंदर एक डीएल के लिए यह कैसे किया है इसका एक पूर्ण विवरण लिखा है - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/


string path = Path.GetDirectoryName(typeof(DaoTests).Module.FullyQualifiedName);

var assembly = System.Reflection.Assembly.GetExecutingAssembly();
var assemblyPath = assembly.GetFiles()[0].Name;
var assemblyDir = System.IO.Path.GetDirectoryName(assemblyPath);




reflection