मैं रनटाइम पर [DllImport] पथ कैसे निर्दिष्ट कर सकता हूं?


141

वास्तव में, मुझे एक सी ++ (काम करने वाला) डीएलएल मिला है जिसे मैं अपने सी # प्रोजेक्ट में आयात करना चाहता हूं ताकि यह फ़ंक्शन हो।

यह काम करता है जब मैं इस तरह से DLL के लिए पूर्ण पथ निर्दिष्ट करता हूं:

string str = "C:\\Users\\userName\\AppData\\Local\\myLibFolder\\myDLL.dll";
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);

समस्या यह है कि यह एक इंस्टॉल करने योग्य परियोजना होने जा रही है, इसलिए उपयोगकर्ता का फ़ोल्डर एक ही नहीं होगा (उदा: पियरे, पाउल, जैक, मम, डैड, ...) कंप्यूटर / सत्र पर निर्भर करता है जहां इसे चलाया जाएगा।

इसलिए मैं अपने कोड को थोड़ा और सामान्य होना चाहूंगा, जैसे:

/* 
goes right to the temp folder of the user 
    "C:\\Users\\userName\\AppData\\Local\\temp"
then go to parent folder
    "C:\\Users\\userName\\AppData\\Local"
and finally go to the DLL's folder
    "C:\\Users\\userName\\AppData\\Local\\temp\\myLibFolder"
*/

string str = Path.GetTempPath() + "..\\myLibFolder\\myDLL.dll"; 
[DllImport(str, CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);

बड़ी बात यह है कि DLL की निर्देशिका के लिए "DllImport" एक "const string" पैरामीटर है।

तो मेरा सवाल है :: इस मामले में क्या किया जा सकता है?


15
केवल उसी फ़ोल्डर में DLL को EXE के रूप में तैनात करें ताकि आपको कुछ भी करने की आवश्यकता न हो लेकिन पथ के बिना DLL नाम निर्दिष्ट करें। अन्य योजनाएं संभव हैं लेकिन सभी परेशान हैं।
हंस पैसेंट

2
बात यह है कि यह एक एमएस ऑफिस एक्सेल ऐड होने वाला है, इसलिए मैं बात नहीं करता कि
एक्सई

8
आपका समाधान गलत है। विंडोज या सिस्टम फोल्डर में फाइल न रखें। उन्होंने उन नामों को एक कारण से चुना: क्योंकि वे विंडोज सिस्टम फाइलों के लिए हैं। आप उनमें से एक नहीं बना रहे हैं क्योंकि आप Windows टीम पर Microsoft के लिए काम नहीं करते हैं। याद रखें कि आप किंडरगार्टन में उन चीजों का उपयोग करने के बारे में क्या सीखते हैं जो आपकी अनुमति के बिना आपके पास नहीं हैं, और अपनी फाइलों को कहीं भी रख दें।
कोड़ी ग्रे

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

3
इसे प्रोग्राम फ़ाइलों में रखना निरंतर नहीं है। उदाहरण के लिए 64bit मशीनों में प्रोग्राम फ़ाइल (x86) है।
लुइस कोट्टमन

जवाबों:


184

कुछ अन्य उत्तरों के सुझावों के विपरीत, DllImportविशेषता का उपयोग करना अभी भी सही दृष्टिकोण है।

मुझे ईमानदारी से समझ में नहीं आता कि आप दुनिया में हर किसी की तरह क्यों नहीं कर सकते हैं और अपने DLL के लिए एक रिश्तेदार रास्ता बता सकते हैं । हां, जिस पथ पर आपका एप्लिकेशन इंस्टॉल किया जाएगा वह अलग-अलग लोगों के कंप्यूटरों पर भिन्न होता है, लेकिन यह मूल रूप से एक सार्वभौमिक नियम है जब यह तैनाती की बात आती है। DllImportतंत्र इसे ध्यान में रखकर बनाया गया है।

वास्तव में, यह भी नहीं है DllImportकि इसे संभालता है। यह मूल Win32 DLL लोडिंग नियम है जो चीजों को नियंत्रित करता है, भले ही आप आसान प्रबंधित रैपर (P / Invoke marshaller सिर्फ कॉल LoadLibrary) का उपयोग कर रहे हों । उन नियमों को यहां बड़े विस्तार से प्रस्तुत किया गया है , लेकिन महत्वपूर्ण यहां प्रस्तुत हैं:

सिस्टम DLL के लिए खोज करने से पहले, यह निम्नलिखित की जाँच करता है:

  • यदि समान मॉड्यूल नाम वाला DLL पहले से ही मेमोरी में लोड है, तो सिस्टम लोड की गई DLL का उपयोग करता है, चाहे वह किसी भी निर्देशिका में हो। सिस्टम DLL के लिए खोज नहीं करता है।
  • यदि DLL Windows के संस्करण के लिए ज्ञात DLL की सूची में है, जिस पर अनुप्रयोग चल रहा है, तो सिस्टम ज्ञात DLL की प्रतिलिपि का उपयोग करता है (और ज्ञात DLL के निर्भर DLL, यदि कोई हो)। सिस्टम DLL के लिए खोज नहीं करता है।

यदि SafeDllSearchModeसक्षम (डिफ़ॉल्ट) है, तो खोज क्रम निम्नानुसार है:

  1. वह निर्देशिका जिससे एप्लिकेशन लोड की गई है।
  2. सिस्टम निर्देशिका। उपयोगGetSystemDirectoryइस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का ।
  3. 16-बिट सिस्टम निर्देशिका। ऐसा कोई फ़ंक्शन नहीं है जो इस निर्देशिका का पथ प्राप्त करता है, लेकिन इसे खोजा जाता है।
  4. विंडोज निर्देशिका। उपयोगGetWindowsDirectoryइस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का ।
  5. वर्तमान निर्देशिका।
  6. निर्देशिका जो PATHपर्यावरण चर में सूचीबद्ध हैं । ध्यान दें कि इसमें एप्लिकेशन पथ रजिस्ट्री कुंजी द्वारा निर्दिष्ट प्रति-एप्लिकेशन पथ शामिल नहीं है। DLL खोज पथ की गणना करते समय ऐप पथ कुंजी का उपयोग नहीं किया जाता है।

इसलिए, जब तक आप अपने DLL को सिस्टम DLL (जिसे आप स्पष्ट रूप से, कभी भी, किसी भी परिस्थिति में नहीं करना चाहिए) के रूप में एक ही चीज़ का नामकरण कर रहे हैं, तो डिफ़ॉल्ट खोज क्रम उस निर्देशिका में दिखना शुरू हो जाएगा जहाँ से आपका आवेदन लोड किया गया था। यदि आप इंस्टॉल के दौरान वहां डीएलएल रखते हैं, तो यह मिल जाएगा। यदि आप केवल सापेक्ष रास्तों का उपयोग करते हैं, तो सभी जटिल समस्याएं दूर हो जाती हैं।

बस लिखें:

[DllImport("MyAppDll.dll")] // relative path; just give the DLL's name
static extern bool MyGreatFunction(int myFirstParam, int mySecondParam);

लेकिन अगर यह किसी भी कारण से काम नहीं करता है , और आपको DLL के लिए एक अलग निर्देशिका में देखने के लिए एप्लिकेशन को मजबूर करने की आवश्यकता है, तो आप SetDllDirectoryफ़ंक्शन का उपयोग करके डिफ़ॉल्ट खोज पथ को संशोधित कर सकते हैं ।
ध्यान दें कि, प्रलेखन के अनुसार:

कॉल करने के बाद SetDllDirectory, मानक DLL खोज पथ है:

  1. वह निर्देशिका जिससे एप्लिकेशन लोड की गई है।
  2. lpPathNameपैरामीटर द्वारा निर्दिष्ट निर्देशिका ।
  3. सिस्टम निर्देशिका। GetSystemDirectoryइस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का उपयोग करें ।
  4. 16-बिट सिस्टम निर्देशिका। ऐसा कोई फ़ंक्शन नहीं है जो इस निर्देशिका का पथ प्राप्त करता है, लेकिन इसे खोजा जाता है।
  5. विंडोज निर्देशिका। GetWindowsDirectoryइस निर्देशिका का पथ प्राप्त करने के लिए फ़ंक्शन का उपयोग करें ।
  6. निर्देशिका जो PATHपर्यावरण चर में सूचीबद्ध हैं ।

इसलिए जब तक आप इस फ़ंक्शन को पहली बार DLL से आयात किए गए फ़ंक्शन को कॉल करते हैं, तब तक आप DLL का पता लगाने के लिए उपयोग किए गए डिफ़ॉल्ट खोज पथ को संशोधित कर सकते हैं। बेशक, लाभ यह है कि आप इस फ़ंक्शन को एक गतिशील मान पास कर सकते हैं जो रन-टाइम पर गणना की जाती है। यह DllImportविशेषता के साथ संभव नहीं है , इसलिए आप अभी भी एक रिश्तेदार पथ (केवल DLL का नाम) का उपयोग करेंगे, और आपके लिए इसे खोजने के लिए नए खोज क्रम पर भरोसा करेंगे।

आपको इस फ़ंक्शन को P / Invoke करना होगा। घोषणा इस तरह दिखती है:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);

16
इस पर एक और मामूली सुधार डीएलएल नाम से विस्तार को छोड़ने के लिए हो सकता है। विंडोज स्वचालित रूप से जोड़ देगा .dllऔर अन्य सिस्टम मोनो (जैसे .soलिनक्स पर) के तहत उचित विस्तार जोड़ देगा । यदि पोर्टेबिलिटी एक चिंता का विषय है तो इससे मदद मिल सकती है।
jheddings

6
के लिए +1 SetDllDirectory। आप बस बदल भी सकते हैं Environment.CurrentDirectoryऔर उस पथ से सभी रिश्तेदार पथों का मूल्यांकन किया जाएगा!
गेमस्क्रिप्ट

2
इससे पहले कि यह पोस्ट किया गया था, ओपी ने स्पष्ट किया कि वह एक प्लगइन बना रहा है, इसलिए Microsoft के प्रोग्राम फ़ाइलों में DLL को डालना एक गैर-स्टार्टर की तरह है। इसके अलावा, DllDirectory या CWD प्रक्रिया में फेरबदल एक अच्छा विचार नहीं हो सकता है, वे प्रक्रिया को विफल करने का कारण बन सकते हैं। अब AddDllDirectoryदूसरी तरफ ...
Mooing Duck

3
कार्यशील निर्देशिका पर भरोसा करना एक संभावित गंभीर सुरक्षा भेद्यता है, @GameScripting, और विशेष रूप से सुपरसुअर अनुमतियों के साथ चलने वाली किसी चीज़ के लिए बीमार होने की सलाह दी जाती है। कोड को लिखने और इसे सही करने के लिए डिज़ाइन का काम करने के लायक।
कोड़ी ग्रे

2
ध्यान दें कि DllImportकेवल एक आवरण से अधिक है LoadLibrary। यह विधानसभा की निर्देशिका कोextern भी मानता है जिसमें विधि परिभाषित की गई हैDllImportखोज पथ अतिरिक्त का उपयोग कर सीमित किया जा सकता DefaultDllImportSearchPath
मिच

38

उपयोग करने के रैन के सुझाव से भी बेहतर GetProcAddress, बस LoadLibraryकिसी भी कॉल को DllImportफंक्शन से पहले करने के लिए कॉल करें (पथ के बिना केवल फ़ाइल नाम के साथ) और वे स्वचालित रूप से लोड किए गए मॉड्यूल का उपयोग करेंगे।

मैंने इस पद्धति का उपयोग रनटाइम को चुनने के लिए किया है कि क्या 32-बिट या 64-बिट देशी DLL को P / Invoke-d फ़ंक्शन का एक गुच्छा संशोधित किए बिना लोड करना है। उस प्रकार के लिए स्थैतिक निर्माता में लोडिंग कोड चिपकाएं जिसमें आयातित फ़ंक्शन हैं और यह सभी ठीक काम करेगा।


1
मुझे यकीन नहीं है कि यह काम करने की गारंटी है। या अगर यह सिर्फ फ्रेमवर्क के वर्तमान संस्करण पर होता है।
कोडइन्चोस

3
@ कोड: मेरे लिए गारंटी लगता है: डायनामिक-लिंक लाइब्रेरी सर्च ऑर्डर । विशेष रूप से, "कारक जो खोज को प्रभावित करते हैं", एक बिंदु।
कोड़ी ग्रे

अच्छा लगा। वैसे मेरे समाधान का एक छोटा अतिरिक्त लाभ है, क्योंकि फंक्शन का नाम भी स्थिर समय पर स्थिर और ज्ञात नहीं है। यदि आपके पास एक ही हस्ताक्षर और एक अलग नाम के साथ 2 कार्य हैं, तो आप मेरे FunctionLoaderकोड का उपयोग करके उन्हें आमंत्रित कर सकते हैं ।
रैन

मुझे जो चाहिए वो लगता है। मैं mylibrary32.dll और mylibrary64.dll जैसे फ़ाइल नाम का उपयोग करने की उम्मीद कर रहा था, लेकिन मुझे लगता है कि मैं उनके साथ एक ही नाम पर अलग-अलग फ़ोल्डर में रह सकता हूं।
योयो

27

यदि आपको एक .dll फ़ाइल की आवश्यकता है जो पथ पर या एप्लिकेशन के स्थान पर नहीं है, तो मुझे नहीं लगता कि आप ऐसा कर सकते हैं, क्योंकि DllImportएक विशेषता है, और विशेषताएँ केवल मेटाडेटा हैं जो कि प्रकार, सदस्यों और अन्य पर सेट है भाषा तत्व।

एक विकल्प जो आपको यह सोचने में मदद कर सकता है कि आपको क्या लगता है कि आप क्या कोशिश कर रहे हैं, LoadLibraryपी / इनवोक के माध्यम से मूल का उपयोग करना है , ताकि आप जिस रास्ते से ज़रूरत हो उसे लोड कर सकें और फिर उपयोग करें।GetProcAddress उस फ़ंक्शन का संदर्भ प्राप्त करें जिसका आपको ज़रूरत है। उस .dll से। फिर एक प्रतिनिधि बनाने के लिए इनका उपयोग करें जिसे आप आमंत्रित कर सकते हैं।

इसे उपयोग करना आसान बनाने के लिए, आप इस प्रतिनिधि को अपनी कक्षा में एक फ़ील्ड पर सेट कर सकते हैं, ताकि इसका उपयोग करना सदस्य पद्धति को कॉल करने जैसा लगे।

संपादित करें

यहाँ एक कोड स्निपेट है जो काम करता है, और दिखाता है कि मेरा क्या मतलब है।

class Program
{
    static void Main(string[] args)
    {
        var a = new MyClass();
        var result = a.ShowMessage();
    }
}

class FunctionLoader
{
    [DllImport("Kernel32.dll")]
    private static extern IntPtr LoadLibrary(string path);

    [DllImport("Kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    public static Delegate LoadFunction<T>(string dllPath, string functionName)
    {
        var hModule = LoadLibrary(dllPath);
        var functionAddress = GetProcAddress(hModule, functionName);
        return Marshal.GetDelegateForFunctionPointer(functionAddress, typeof (T));
    }
}

public class MyClass
{
    static MyClass()
    {
        // Load functions and set them up as delegates
        // This is just an example - you could load the .dll from any path,
        // and you could even determine the file location at runtime.
        MessageBox = (MessageBoxDelegate) 
            FunctionLoader.LoadFunction<MessageBoxDelegate>(
                @"c:\windows\system32\user32.dll", "MessageBoxA");
    }

    private delegate int MessageBoxDelegate(
        IntPtr hwnd, string title, string message, int buttons); 

    /// <summary>
    /// This is the dynamic P/Invoke alternative
    /// </summary>
    static private MessageBoxDelegate MessageBox;

    /// <summary>
    /// Example for a method that uses the "dynamic P/Invoke"
    /// </summary>
    public int ShowMessage()
    {
        // 3 means "yes/no/cancel" buttons, just to show that it works...
        return MessageBox(IntPtr.Zero, "Hello world", "Loaded dynamically", 3);
    }
}

नोट: मैंने उपयोग करने के लिए परेशान नहीं किया है FreeLibrary, इसलिए यह कोड पूरा नहीं है। एक वास्तविक एप्लिकेशन में, आपको मेमोरी रिसाव से बचने के लिए लोड किए गए मॉड्यूल को जारी करने का ध्यान रखना चाहिए।


LoadLibrary (असेंबली क्लास में) के लिए प्रबंधित समकक्ष है।
लुका

यदि आपके पास कुछ कोड उदाहरण होते, तो मेरे लिए समझना आसान होता! ^ ^ (वास्तव में, यह थोड़ा
गलत है

1
@ लुका पिकाओनी: यदि आपका मतलब विधानसभा से है। तोफादर, यह केवल नेट असेंबलियों को लोड करता है, न कि देशी पुस्तकालयों को। आप क्या मतलब था?
रण

1
मैं इस अर्थ में था, लेकिन मैं इस सीमा के बारे में नहीं जानता था। आह।
लुका

1
बिलकूल नही। यह दिखाने के लिए सिर्फ एक नमूना था कि आप P / Invoke का उपयोग किए बिना एक देशी dll में एक फ़ंक्शन को कॉल कर सकते हैं जिसके लिए एक स्थिर पथ की आवश्यकता होती है।
रैन

5

जब तक आप उस निर्देशिका को जानते हैं जहां आपके सी ++ लाइब्रेरी रन टाइम पर मिल सकते हैं, यह सरल होना चाहिए। मैं स्पष्ट रूप से देख सकता हूं कि आपके कोड में यही स्थिति है। आपका वर्तमान उपयोगकर्ता के अस्थायी फ़ोल्डर के myDll.dllअंदर myLibFolderनिर्देशिका के अंदर मौजूद होगा ।

string str = Path.GetTempPath() + "..\\myLibFolder\\myDLL.dll"; 

अब आप DllImport स्टेटमेंट को नीचे दिखाए अनुसार कास्ट स्ट्रिंग का उपयोग करके जारी रख सकते हैं:

[DllImport("myDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);

DLLFunctionफ़ंक्शन को कॉल करने से पहले बस रन समय पर (C ++ लाइब्रेरी में मौजूद) C # कोड में कोड की यह पंक्ति जोड़ें:

string assemblyProbeDirectory = Path.GetTempPath() + "..\\myLibFolder\\myDLL.dll"; 
Directory.SetCurrentDirectory(assemblyProbeDirectory);

यह केवल सीएलआर को निर्देश देता है कि आप अपने प्रोग्राम के रन टाइम पर प्राप्त निर्देशिका पथ पर अप्रबंधित C ++ पुस्तकालयों की तलाश करें। Directory.SetCurrentDirectoryकॉल एप्लिकेशन की वर्तमान कार्यशील निर्देशिका को निर्दिष्ट निर्देशिका पर सेट करता है। यदि आपका myDLL.dllमार्ग पथ द्वारा प्रस्तुत पथ पर मौजूद assemblyProbeDirectoryहै तो यह लोड हो जाएगा और वांछित फ़ंक्शन को पी / इनवोक के माध्यम से बुलाया जाएगा।


3
इसने मेरे लिए काम किया। मेरे पास मेरे निष्पादन एप्लिकेशन के "बिन" निर्देशिका में स्थित एक फ़ोल्डर "मॉड्यूल" है। वहाँ मैं एक प्रबंधित dll रख रहा हूँ और कुछ unmanaged dll है कि प्रबंधित dll की आवश्यकता है। इस समाधान का उपयोग करना और अपने ऐप में प्रोबिंग पथ को सेट करना ।config मुझे आवश्यक असेंबली को गतिशील रूप से लोड करने की अनुमति देता है।
WBuck

एज़्योर फ़ंक्शंस का उपयोग करने वाले लोगों के लिए: स्ट्रिंग वर्कडायरेक्टरी = Path.GetFullPath (Path.Combine (निष्पादनContext.FunctionDirectory, @ ".. \ bin"));
रेड राइडिंग हूड

4

config फ़ाइल में dll पथ सेट करें

<add key="dllPath" value="C:\Users\UserName\YourApp\myLibFolder\myDLL.dll" />

आप ऐप में dll को कॉल करने से पहले, निम्न कार्य करें

string dllPath= ConfigurationManager.AppSettings["dllPath"];    
   string appDirectory = Path.GetDirectoryName(dllPath);
   Directory.SetCurrentDirectory(appDirectory);

फिर dll को कॉल करें और आप नीचे की तरह उपयोग कर सकते हैं

 [DllImport("myDLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int DLLFunction(int Number1, int Number2);

0

DllImport पूरी तरह से निर्दिष्ट पथ के बिना ठीक काम करेगा जब तक कि dll सिस्टम पथ पर कहीं स्थित है। आप उपयोगकर्ता के फ़ोल्डर को पथ में अस्थायी रूप से जोड़ने में सक्षम हो सकते हैं।


मैंने इसे सिस्टम में रखने की कोशिश की पर्यावरण चर चर लेकिन यह अभी भी गैर स्थिर माना जाता है (तार्किक, मुझे लगता है)
Jsncrdnl

-14

यदि सब विफल रहता है, तो बस DLL को windows\system32फ़ोल्डर में रखें। कंपाइलर उसे ढूंढ लेगा। DLL को इसके साथ लोड करने के लिए निर्दिष्ट करें:, अपने C # ऐप में अपने इच्छित अप्रबंधित फ़ंक्शन को आयात DllImport("user32.dll"...करने के EntryPoint = "my_unmanaged_function"लिए सेट करें:

 using System;
using System.Runtime.InteropServices;

class Example
{
   // Use DllImport to import the Win32 MessageBox function.

   [DllImport ("user32.dll", CharSet = CharSet.Auto)]
   public static extern int MessageBox 
      (IntPtr hWnd, String text, String caption, uint type);

   static void Main()
   {
      // Call the MessageBox function using platform invoke.
      MessageBox (new IntPtr(0), "Hello, World!", "Hello Dialog", 0);    
   }
}

स्रोत और भी अधिक DllImportउदाहरण: http://msdn.microsoft.com/en-us/library/aa288468(v=vs.71).aspx


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

यदि इसका उपयोग डिबगिंग सहायता से अधिक कुछ के लिए किया जाता है, तो यह मेरी पुस्तक में किसी भी समीक्षा (सुरक्षा या अन्यथा) के माध्यम से आएगा।
क्रिश्चियन.के

21
यह एक बहुत भयानक समाधान है। सिस्टम फ़ोल्डर सिस्टम DLL के लिए है। अब आपको व्यवस्थापक विशेषाधिकारों की आवश्यकता है और आप केवल आलसी होने के कारण बुरी प्रथाओं पर भरोसा कर रहे हैं।
माइक

5
इस जवाब के लिए, माइक के लिए +1। यह एक भयानक समाधान है, जो कोई भी ऐसा करता है उसे द ओल्ड न्यू थिंग पढ़ने के लिए मजबूर किया जाता है । जैसे आपने बालवाड़ी में सीखा है: सिस्टम फ़ोल्डर आपके लिए नहीं है, इसलिए आपको इसे बिना अनुमति के उपयोग नहीं करना चाहिए।
कोड़ी ग्रे

ओकोक, मैं आपसे सहमत हूं, लेकिन मेरी समस्या का समाधान नहीं हुआ है ... आप किस स्थान पर मेरी सिफारिश करेंगे? (यह जानते हुए कि मैं इसे सेट करने के लिए चर का उपयोग नहीं कर सकता हूं -क्योंकि यह एक निरंतर स्ट्रिंग की प्रतीक्षा कर रहा है- तो मैं उस स्थान का उपयोग करना चाहूंगा जो प्रत्येक कंप्यूटर पर एक जैसा हो?) (या एक चर का उपयोग करने के लिए कोई रास्ता है, एक निरंतर के बजाय, इसे करने के लिए?)
Jsncrdnl
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.