রানটাইমে আমি কীভাবে একটি [DllImport] পাথ নির্দিষ্ট করতে পারি?


141

প্রকৃতপক্ষে, আমি একটি সি ++ (কর্মরত) ডিএলএল পেয়েছি যা আমি আমার সি # প্রকল্পে এটির ফাংশনগুলি বলতে কল করতে আমদানি করতে চাই।

আমি যখন ডিএলএল-এর পূর্ণ পথ নির্দিষ্ট করি তখন এটি কার্যকর হয়:

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);

বড় কথা হ'ল "DllImport" DLL ডিরেক্টরিতে একটি "কনস্ট্রিং স্ট্রিং" পরামিতি চায়।

সুতরাং আমার প্রশ্ন :: এই ক্ষেত্রে কী করা যেতে পারে?


15
EXE হিসাবে একই ফোল্ডারে কেবল DLL স্থাপন করুন যাতে আপনাকে কিছু করতে হবে না তবে পথ ছাড়াই DLL নাম নির্দিষ্ট করতে হবে। অন্যান্য স্কিমগুলি সম্ভব তবে সবগুলি সমস্যাজনক।
হ্যানস প্যাস্যান্ট

2
বিষয়টি হ'ল এটি একটি এমএস অফিস এক্সেল যুক্ত হতে চলেছে, তাই আমি
এক্সির ডিরেক্টরিতে ডেল লাগানো

8
আপনার সমাধানটি ভুল। উইন্ডোজ বা সিস্টেম ফোল্ডারে ফাইল রাখবেন না। তারা এই কারণগুলি এই কারণে বেছে নিয়েছিল: কারণ তারা উইন্ডোজ সিস্টেম ফাইলগুলির জন্য। আপনি সেগুলির একটি তৈরি করছেন না কারণ আপনি উইন্ডোজ টিমে মাইক্রোসফ্টের জন্য কাজ করেন না। অনুমতি ছাড়া আপনার নিজের নয় এমন জিনিসগুলি ব্যবহার করার জন্য আপনি কিন্ডারগার্টেনে যা শিখেছিলেন তা মনে রাখুন এবং আপনার ফাইলগুলি অন্য কোথাও রেখে দিন।
কোডি গ্রে

আপনার সমাধানটি এখনও ভুল। ভাল আচরণযুক্ত অ্যাপ্লিকেশনগুলি যা প্রশাসনিক জিনিসগুলি আসলে না করে তাদের প্রশাসনিক অ্যাক্সেসের প্রয়োজন হবে না। অন্য একটি বিষয় যে আপনি আপনার আবেদন আসলে হবে জানি না করা যে ফোল্ডারে ইনস্টল করা নেই। আমি এটিকে অন্য কোথাও স্থানান্তর করতে পারি, বা সেটআপের সময় ইনস্টলনের পথটি পরিবর্তন করতে পারি (মজাদার জন্য আমি এই ধরণের জিনিস করি, কেবলমাত্র খারাপ আচরণযুক্ত অ্যাপ্লিকেশনগুলি ভাঙার জন্য)। হার্ড-কোডিং পাথগুলি খারাপ আচরণের প্রতিমূর্তি এবং এটি সম্পূর্ণ অপ্রয়োজনীয়। আপনি যদি নিজের অ্যাপ্লিকেশনটির ফোল্ডার ব্যবহার করেন, তবে এটি ডিএলএলগুলির জন্য ডিফল্ট অনুসন্ধান ক্রমের প্রথম পথ । সমস্ত স্বয়ংক্রিয়।
কোডি গ্রে

3
প্রোগ্রাম ফাইলগুলিতে এটি লাগানো ধ্রুব নয়। উদাহরণস্বরূপ, 64 বিট মেশিনগুলির পরিবর্তে প্রোগ্রাম ফাইল (x86) রয়েছে।
লুই কোটম্যান

উত্তর:


184

অন্য কয়েকটি উত্তরের পরামর্শগুলির বিপরীতে, গুণাবলীটি ব্যবহার DllImportকরা এখনও সঠিক পদ্ধতির approach

আমি কেন সত্যই বুঝতে পারছি না যে আপনি কেন বিশ্বের অন্য সবার মতো করতে পারবেন না এবং আপনার ডিএলএল সম্পর্কিত একটি আপেক্ষিক পথ নির্দিষ্ট করতে পারেন। হ্যাঁ, আপনার অ্যাপ্লিকেশনটি যে পদ্ধতিতে ইনস্টল করা হবে তা বিভিন্ন লোকের কম্পিউটারে পৃথক, তবে যখন এটি মোতায়েনের কথা আসে তখন এটি মূলত সর্বজনীন নিয়ম। এই বিষয়টি মাথায় রেখে DllImportপ্রক্রিয়াটি তৈরি করা হয়েছে।

আসলে এটি DllImportএটিকে পরিচালনা করে না। এটি হিন্দি উইন 32 ডিএলএল লোডিংয়ের নিয়ম যা জিনিস পরিচালনা করে, আপনি হ্যান্ডি ম্যানেজড রেপার ব্যবহার করছেন কিনা তা বিবেচনা না করেই (পি / ইনভোক মার্শালার কেবল কল করেছেন LoadLibrary)। এই বিধিগুলি এখানে বিস্তৃতভাবে গণনা করা হয়েছে , তবে গুরুত্বপূর্ণগুলি এখানে উদ্ধৃত হয়েছে:

সিস্টেমটি কোনও ডিএলএল অনুসন্ধান করার আগে এটি নিম্নলিখিতগুলি পরীক্ষা করে:

  • যদি একই মডিউল নামের কোনও ডিএলএল ইতিমধ্যে মেমরিতে লোড করা থাকে তবে সিস্টেমটি লোডড ডিএলএল ব্যবহার করে, এটি যে ডিরেক্টরিতে থাকুক না কেন। সিস্টেমটি ডিএলএল অনুসন্ধান করে না।
  • উইন্ডোজ যে সংস্করণটিতে অ্যাপ্লিকেশন চলছে তার সংস্করণটির জন্য যদি ডিএলএল পরিচিত ডিএলএলগুলির তালিকায় থাকে তবে সিস্টেমটি তার পরিচিত ডিএলএল (এবং পরিচিত ডিএলএল নির্ভর ডিএলএল, যদি থাকে) এর অনুলিপি ব্যবহার করে। সিস্টেমটি ডিএলএল অনুসন্ধান করে না।

যদি SafeDllSearchModeসক্ষম হয় (ডিফল্ট), সন্ধান ক্রমটি নিম্নরূপ:

  1. যে ডিরেক্টরিটি থেকে অ্যাপ্লিকেশনটি লোড হয়েছে।
  2. সিস্টেম ডিরেক্টরি। GetSystemDirectoryএই ডিরেক্টরিটির পথ পেতে ফাংশনটি ব্যবহার করুন ।
  3. 16-বিট সিস্টেম ডিরেক্টরি। এই ডিরেক্টরিটির পথ অর্জন করে এমন কোনও কার্য নেই, তবে এটি অনুসন্ধান করা হয়।
  4. উইন্ডোজ ডিরেক্টরি। GetWindowsDirectoryএই ডিরেক্টরিটির পথ পেতে ফাংশনটি ব্যবহার করুন ।
  5. বর্তমান ডিরেক্টরি।
  6. PATHপরিবেশে পরিবর্তনশীল তালিকাভুক্ত ডিরেক্টরিগুলি । দ্রষ্টব্য যে এতে অ্যাপ পাথস রেজিস্ট্রি কী দ্বারা নির্দিষ্ট করা প্রতি অ্যাপ্লিকেশন পাথ অন্তর্ভুক্ত নয়। ডিএলএল অনুসন্ধানের পথের গণনা করার সময় অ্যাপ পাথ কী ব্যবহার করা হয় না।

সুতরাং, যদি না আপনি আপনার ডিএলএলকে সিস্টেম ডিএলএল হিসাবে একই নামকরণ করেন (যা আপনার সম্ভবত কোনও অবস্থাতেই করা উচিত নয়), আপনার অ্যাপ্লিকেশনটি লোড হওয়া ডিরেক্টরিটি ডিফল্ট অনুসন্ধান আদেশটি সন্ধান করা শুরু করবে। আপনি যদি ইনস্টল করার সময় সেখানে ডিএলএল রাখেন তবে এটি পাওয়া যাবে। আপনি যদি কেবলমাত্র আপেক্ষিক পাথ ব্যবহার করেন তবে সমস্ত জটিল সমস্যা চলে যায়।

শুধু লেখো:

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

তবে যদি এটি কোনও কারণে কার্যকর না হয় এবং আপনাকে ডিএলএলটির জন্য আলাদা ডিরেক্টরিতে অ্যাপ্লিকেশনটিকে বাধ্য করার প্রয়োজন হয়, আপনি SetDllDirectoryফাংশনটি ব্যবহার করে ডিফল্ট অনুসন্ধানের পথটি পরিবর্তন করতে পারেন ।
নথি হিসাবে নোট করুন:

কল করার পরে SetDllDirectory, মানক ডিএলএল অনুসন্ধানের পথটি হ'ল:

  1. যে ডিরেক্টরিটি থেকে অ্যাপ্লিকেশনটি লোড হয়েছে।
  2. lpPathNameপ্যারামিটার দ্বারা নির্দিষ্ট ডিরেক্টরি ।
  3. সিস্টেম ডিরেক্টরি। GetSystemDirectoryএই ডিরেক্টরিটির পথ পেতে ফাংশনটি ব্যবহার করুন ।
  4. 16-বিট সিস্টেম ডিরেক্টরি। এই ডিরেক্টরিটির পথ অর্জন করে এমন কোনও কার্য নেই, তবে এটি অনুসন্ধান করা হয়।
  5. উইন্ডোজ ডিরেক্টরি। GetWindowsDirectoryএই ডিরেক্টরিটির পথ পেতে ফাংশনটি ব্যবহার করুন ।
  6. PATHপরিবেশে পরিবর্তনশীল তালিকাভুক্ত ডিরেক্টরিগুলি ।

সুতরাং আপনি প্রথমবার ডিএলএল থেকে আমদানি করা ফাংশনটি কল করার আগে আপনি যতক্ষণ এই ফাংশনটি কল করবেন ততক্ষণ আপনি ডিএলএলগুলি সনাক্ত করতে ব্যবহৃত ডিফল্ট অনুসন্ধানের পথটি পরিবর্তন করতে পারবেন। অবশ্যই সুবিধাটি হ'ল আপনি রান-টাইমে গণনা করা এই ফাংশনটিতে একটি গতিশীল মান পাস করতে পারেন । DllImportবৈশিষ্ট্যটি দিয়ে এটি সম্ভব নয় , সুতরাং আপনি এখনও সেখানে একটি আপেক্ষিক পথ (কেবলমাত্র ডিএলএলের নাম) ব্যবহার করবেন এবং এটি আপনার অনুসন্ধানের জন্য নতুন অনুসন্ধান ক্রমের উপর নির্ভর করুন।

আপনাকে এই ফাংশনটি পি / ইনভোক করতে হবে। ঘোষণাটি এর মতো দেখাচ্ছে:

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

16
ডিএলএল নাম থেকে এক্সটেনশানটি বাদ দেওয়া এ সম্পর্কিত আরও একটি ছোটখাটো উন্নতি হতে পারে। উইন্ডোজ স্বয়ংক্রিয়ভাবে যুক্ত হবে .dllএবং অন্যান্য সিস্টেমগুলি মনো এর অধীনে উপযুক্ত এক্সটেনশন যুক্ত করবে (যেমন .soলিনাক্সের উপরে)। পোর্টেবিলিটিটি উদ্বেগজনক হলে এটি সহায়তা করতে পারে।
jeddings

6
জন্য +1 SetDllDirectory। আপনি কেবল পরিবর্তন করতে পারেন Environment.CurrentDirectoryএবং সমস্ত আপেক্ষিক প্যাথগুলি সেই পথ থেকে মূল্যায়ন করা হবে!
গেমস্ক্রিপ্টিং

2
এটি পোস্ট হওয়ার আগেও ওপি স্পষ্ট করে দিয়েছিল যে তিনি একটি প্লাগইন তৈরি করছেন, তাই মাইক্রোসফ্টের প্রোগ্রাম ফাইলগুলিতে ডিএলএল স্থাপন করা একটি স্টার-স্টার্টার বাছাই করা। এছাড়াও, DllDirectory বা CWD প্রক্রিয়া পরিবর্তন করা ভাল ধারণা নাও থাকতে পারে, তারা প্রক্রিয়াটি ব্যর্থ হতে পারে। এখন AddDllDirectoryঅন্যদিকে ...
মাকিং হাঁস

3
ওয়ার্কিং ডিরেক্টরিতে ভরসা করা একটি সম্ভাব্য গুরুতর সুরক্ষা দুর্বলতা, @ গেমস্ক্রিপ্টিং এবং বিশেষত সুপারভাইজার অনুমতি নিয়ে চলমান কোনও কিছুর জন্য অসুস্থ-পরামর্শ দেওয়া। কোডটি লেখার এবং এটি ঠিক করার জন্য ডিজাইনের কাজ করা মূল্যবান।
কোডি গ্রে

2
মনে রাখবেন যে DllImportএটি কেবল একটি মোড়কের উপরে রয়েছে LoadLibrary। এটি সমাবেশের ডিরেক্টরিটিও externপদ্ধতিটিকে সংজ্ঞায়িত করা বিবেচনা করেDllImportঅনুসন্ধান পাথ অতিরিক্ত ব্যবহার সীমিত করা যাবে DefaultDllImportSearchPath
মিচ

38

রানের ব্যবহারের পরামর্শের চেয়ে আরও ভাল GetProcAddress, ফাংশনগুলিতে LoadLibraryকোনও কল করার আগে কেবল কল করুন DllImport(কোনও পাথ ছাড়াই কেবল একটি ফাইল নাম সহ) এবং তারা স্বয়ংক্রিয়ভাবে লোড মডিউলটি ব্যবহার করবে।

আমি রানটাইমে বেছে নেওয়ার জন্য এই পদ্ধতিটি ব্যবহার করেছি, পি / ইনভোক-ডি ফাংশনগুলির একগুচ্ছ পরিবর্তন না করেই 32-বিট বা 64-বিট নেটিভ ডিএলএল লোড করা যায় কিনা। যে ধরণের আমদানি করা ফাংশন রয়েছে তার জন্য স্থিতিশীল কনস্ট্রাক্টরে লোডিং কোডটি আটকে দিন এবং এটি সব ঠিকঠাক কাজ করবে।


1
আমি নিশ্চিত নই যে এটির কাজের নিশ্চয়তা রয়েছে কিনা। বা যদি এটি ফ্রেমওয়ার্কের বর্তমান সংস্করণে ঘটে থাকে।
কোডসইনচওস

3
@ কোড: আমার কাছে গ্যারান্টিযুক্ত মনে হচ্ছে: ডায়নামিক-লিংক লাইব্রেরি অনুসন্ধান আদেশ । বিশেষত, "বিষয়গুলি যা অনুসন্ধানকে প্রভাবিত করে", পয়েন্ট এক।
কোডি ধূসর

খুশী হলাম। ঠিক আছে তবে আমার সমাধানটির একটি অতিরিক্ত অতিরিক্ত সুবিধা রয়েছে, এমনকি ফাংশনটির নাম স্থির থাকতে হবে এবং সংকলনের সময় জানা উচিত নয়। যদি আপনার একই স্বাক্ষর এবং একটি আলাদা নামের সাথে দুটি ফাংশন থাকে তবে আপনি আমার FunctionLoaderকোড ব্যবহার করে সেগুলি শুরু করতে পারেন ।
রান

এটি আমার যা চাই তা মনে হচ্ছে। আমি আশা করছিলাম যে ফাইলের নামগুলি mylibrary32.dll এবং mylibrary64.dll এর মতো ব্যবহার করা হবে তবে আমি অনুমান করি যে আমি তাদের একই নাম থাকলেও বিভিন্ন ফোল্ডারে থাকতে পারি।
yoyo

27

আপনার যদি একটি .dll ফাইলের প্রয়োজন হয় যা পথে বা অ্যাপ্লিকেশনটির অবস্থানের ভিত্তিতে না থাকে তবে আমি মনে করি না আপনি কেবল এটি করতে পারবেন, কারণ DllImportএকটি বৈশিষ্ট্য, এবং বৈশিষ্ট্যগুলি কেবল মেটাডেটা যা টাইপ, সদস্য এবং অন্যান্যতে সেট করা থাকে ভাষা উপাদান।

আপনি যে চেষ্টা করছেন বলে মনে করছেন তা অর্জনে আপনাকে সহায়তা করতে পারে এমন একটি বিকল্প হ'ল LoadLibraryআপনার প্রয়োজনীয় পথ থেকে একটি .dll লোড করার জন্য পি / ইনভোকের মাধ্যমে নেটিভ ব্যবহার 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, সুতরাং এই কোডটি সম্পূর্ণ নয়। একটি সত্যিকারের অ্যাপ্লিকেশনটিতে, মেমরির ফাঁস এড়াতে আপনার বোঝা মডিউলগুলি ছেড়ে দেওয়ার যত্ন নেওয়া উচিত।


লোডলিবারি (বিধানসভা ক্লাসে) এর পরিচালনা ব্যবস্থা রয়েছে।
লুকা

আপনার যদি কিছু কোড উদাহরণ থাকে তবে আমার পক্ষে এটি বোঝা সহজ হবে! । (আসলে, এটি কিছুটা ভুল)
Jsncrdnl

1
@ লুকা পিকসিওনি: আপনি যদি সংসদ বলতে চান o লোডফ্রোম থেকে, এটি কেবল নেট নেট এসেম্বলিগুলি লোড করে, নেটিভ লাইব্রেরি নয় not আপনি কি বুঝাতে চাচ্ছিলেন?
রান হয়েছে

1
আমি এর অর্থ ছিল, কিন্তু আমি এই সীমাবদ্ধতা সম্পর্কে জানতাম না। দীর্ঘশ্বাস.
লুকা

1
অবশ্যই না. এটি কেবলমাত্র একটি নমুনা ছিল তা দেখানোর জন্য যে আপনি পি / ইনভোক ব্যবহার না করেই কোনও স্থানীয় ডিএলে একটি ফাংশন কল করতে পারেন যার জন্য একটি স্ট্যাটিক পাথ প্রয়োজন।
রান

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ফাংশনটি কল করার আগে রান টাইমে (সি ++ লাইব্রেরিতে উপস্থিত) সি # কোডে এই লাইন কোডটি যুক্ত করুন:

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

এটি সরাসরি আপনার প্রোগ্রামের রান সময় আপনি যে ডিরেক্টরিটি পেয়েছিলেন সেটি পরিচালনা পন্থায় পরিচালনা না করা সি ++ লাইব্রেরি সন্ধানের জন্য সিএলআরকে নির্দেশ দেয়। Directory.SetCurrentDirectoryকল অ্যাপ্লিকেশনটির বর্তমান কার্যকারী ডিরেক্টরিকে নির্দিষ্ট ডিরেক্টরিতে সেট করে। আপনার যদি myDLL.dllপথ দ্বারা উপস্থাপিত পথে উপস্থিত থাকে assemblyProbeDirectoryতবে এটি লোড হয়ে যাবে এবং কাঙ্ক্ষিত ফাংশনটি p / আহ্বানের মাধ্যমে কল হবে।


3
এটি আমার পক্ষে কাজ করেছে। আমার এক্সিকিউটিভ অ্যাপ্লিকেশনটির "বিন" ডিরেক্টরিতে একটি ফোল্ডার "মডিউল" রয়েছে। সেখানে আমি একটি পরিচালিত ডিএল এবং কিছু পরিচালিত ডিএল রাখছি যা পরিচালিত ডিএল প্রয়োজন। এই সমাধানটি ব্যবহার করে এবং আমার app.config- এ অনুসন্ধানের পথটি সেট করা আমাকে প্রয়োজনীয় সমাবেশগুলি গতিশীলভাবে লোড করতে দেয়।
ডাব্লুবুক

অ্যাজুরে ফাংশন ব্যবহারকারী ব্যক্তিদের জন্য: স্ট্রিং ওয়ার্কিংডাইরেক্টরি = পাথ.গেটফুলপাথ (পাথ.কোমাইন (এক্সিকিউশনকন্টেক্সট। ফাংশন ডিরেক্টরী, @ "" \ বিন "));
রেড রাইডিং হুড

4

কনফিগার ফাইলে 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

যদি সমস্ত ব্যর্থ হয় তবে কেবল windows\system32ফোল্ডারে ডিএলএল রাখুন । সংকলক এটি খুঁজে পাবেন। সাথে থেকে লোড ডিএলএল উল্লেখ করুন DllImport("user32.dll"..., সেট EntryPoint = "my_unmanaged_function"আপনার C # এর অ্যাপ্লিকেশানে আপনার পছন্দসই অপরিচালিত ফাংশন আমদানি করতে:

 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
এটি একটি দুর্দান্ত ভয়ঙ্কর সমাধান। সিস্টেম ফোল্ডারটি সিস্টেম ডিএলএলগুলির জন্য। এখন আপনার অ্যাডমিন সুবিধাগুলি প্রয়োজন এবং আপনি অলসতার কারণে খারাপ অভ্যাসগুলির উপর নির্ভর করছেন।
মাইকপ

5
মাইকেরপির জন্য +1, এই উত্তরের জন্য -1। এটি একটি ভয়াবহ সমাধান, যে কেউ এটি করে তাকে ওল্ড নিউ থিং পড়তে বাধ্য করার সময় বারবার আঘাত করা উচিত । আপনি কিন্ডারগার্টেনে যেমন শিখেছেন: সিস্টেম ফোল্ডারটি আপনার নিজস্ব নয়, সুতরাং আপনার অনুমতি ছাড়া এটি ব্যবহার করা উচিত নয়।
কোডি গ্রে

ওকোক, আমি আপনার সাথে একমত, তবে আমার সমস্যাটি এতটা মিটে যায় নি ... তাহলে আপনি কোন অবস্থানটি আমাকে প্রস্তাব করবেন? (এটা জেনে যে আমি এটির সেট আপ করতে ভেরিয়েবলগুলি ব্যবহার করতে পারি না - কারণ এটি একটি ধ্রুব স্ট্রিংয়ের জন্য অপেক্ষা করছে - সুতরাং যে আমার কাছে এমন কোনও অবস্থান ব্যবহার করা উচিত যা প্রতিটি কম্পিউটারে একই রকম হয়?) (বা এটি সম্পাদন করার জন্য ধ্রুবকের পরিবর্তে কোনও ভেরিয়েবলগুলি ব্যবহার করার কোনও উপায় আছে?)
জেএসএনসিআরএনএল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.