DLLImport - using dynamic file path  
Author Message
lufa





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

hello

I want to use unmanaged dll in my c# project, but I don't know were user will put the unmanaged dll file during instalation, so I can't hard coded file path in DLLImport attribute. During Instalation user will choose common file folder then I want to put this path to registry or to some xml file. But what then - of course i can read this path on application start up but i can't set path in DLLImport. -- Is there a way to do this if not, is there any other way then adding during instalation path to unmanaged dll to PATH environment variable If not is there any other way to use unmanaged dll in c# (it isn't interop any com object).




Visual C#17  
 
 
Brendan Grant





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

Bad news... the DllImport attribute is just that, an attribute and like most of them they tend to remain pretty static after the application is built, because of that you cannot dynamically change it.

That being said... all is not lost, you could dynamically emit new code with the exact attributes you want at runtime to do this... that would be however very very dirty.

Instead... you’ve got two major options, first, require that the file be placed inside of a given directory (where you know the directory name and the file name) or you modify the PATH environmental variable.

In the last case you’ve got 2 ways in the C# world, first, if you are using the 2.0 framework you can use Environment.SetEnvironmentVariable() to set it. If you are running 1.1 then you are stuck with doing a P/Invoke against kernel32 with:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool SetEnvironmentVariable( string lpName, string lpValue );

In either case of setting it, in order to retrieve what is there you can use Environment.GetEnvironmentVariable() under either version.



 
 
Peter Ritchie





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

If the dll is in the PATH .NET will find it. During installation make sure the PATH has the directory where this DLL is loaded. If you're dependant on the DLL you have to make sure the system is setup properly during installation. You could always just install the DLL in the same directory as your application.

 
 
lufa





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

Hi

Thanks for your advise, I tihnk the best was, add path to environment variable (PATH) during starup application and then on close remove it.- Imagin what would happen if each application would add path during instalation.

Any how i thing i found the best solution for me, now I can put dll path to registry on instalation, then on application start up read registry and use dll from path.

I did this.

Of course I always know where is kernel32.dll so I can use DllImport to load kernel32.dll then I'm using 3 functions.

/// <summary>
/// To load the dll - dllFilePath dosen't have to be const - so I can read path from registry
/// </summary>
/// <param name="dllFilePath">file path with file name</param>
/// <param name="hFile">use IntPtr.Zero</param>
/// <param name="dwFlags">What will happend during loading dll
/// <para>LOAD_LIBRARY_AS_DATAFILE</para>
/// <para>DONT_RESOLVE_DLL_REFERENCES</para>
/// <para>LOAD_WITH_ALTERED_SEARCH_PATH</para>
/// <para>LOAD_IGNORE_CODE_AUTHZ_LEVEL</para>
/// </param>
/// <returns>Pointer to loaded Dll</returns>
[
DllImport(kernel32)]
private static extern IntPtr LoadLibraryEx(string dllFilePath, IntPtr hFile, uint dwFlags);

///
<summary>
/// To unload library
/// </summary>
/// <param name="dllPointer">Pointer to Dll witch was returned from LoadLibraryEx</param>
/// <returns>If unloaded library was correct then true, else false</returns>
[DllImport(kernel32)]
public extern static bool FreeLibrary(IntPtr dllPointer);

/// <summary>
/// To get function pointer from loaded dll
/// </summary>
/// <param name="dllPointer">Pointer to Dll witch was returned from LoadLibraryEx</param>
/// <param name="functionName">Function name with you want to call</param>
/// <returns>Pointer to function</returns>
[DllImport(kernel32, CharSet = CharSet.Ansi)]
public extern static IntPtr GetProcAddress(IntPtr dllPointer, string functionName);

/// <summary>
/// This will to load concret dll file
/// </summary>
/// <param name="dllFilePath">Dll file path</param>
/// <returns>Pointer to loaded dll</returns>
/// <exception cref="ApplicationException">
/// when loading dll will failure
/// </exception>
public static IntPtr LoadWin32Library(string dllFilePath)
{
System.
IntPtr moduleHandle = LoadLibraryEx(dllFilePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
if (moduleHandle == IntPtr.Zero)
{
// I'm gettin last dll error
int errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(
string.Format("There was an error during dll loading : {0}, error - {1}", dllFilePath, errorCode)
);
}
return moduleHandle;
}

// **************************************************************************************************************************
// That is all, now how to use this functions
// **************************************************************************************************************************

private IntPtr myDll ;

public static void InitializeMyDll()
{
try
{
myDll =
Dll.LoadWin32Library("path to my dll with file path name");
// here you can add, dl version check
}
catch (ApplicationException exc)
{
MessageBox.Show(exc.Message, "There was an error during dll loading",MessageBoxButtons.OK,MessageBoxIcon.Error);
throw exc;
}
}

// The last thing is to create delegate to calling function

// delegate must to have the same parameter then calling function (from dll)
public
delegate RETURN_TYPE DllFunctionDelegate(int a, string b);
public static RETURN_TYPE functionName(int a, string b)
{
if (myDll == IntPtr.Zero)
InitializeMyDll();
IntPtr pProc = Dll.GetProcAddress(myDll , "CallingFunctionNameFromCallingDllFile");
CPVdelegate cpv = (CPVdelegate)Marshal.GetDelegateForFunctionPointer(pProc, typeof(CPVdelegate));
// Now i'm calling delegate, with is calling function from dll file

return cpv(nOper, hWnd, out dwData);
}

// Now if you want to call dll function from program code use this
// for ex. you want to call c++ function RETURN_TYPE CallingFunctionNameFromCallingDllFile(int nID, LPSTR lpstrName);

RETURN_TYPE ret;
ret = functionName
(2, "name");

I hope it will help a lot of people. If you have any question write me.

Lufa




 
 
New-Bee





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

Hello there,
I've encountered the same problem, and noticed that whenever I publish my application and install it on a different computer, I get a DllNotFoundException. The odd thing is that the message says the dll wasn't found in the bin/debug path of the project. How come it is being searched in the bin/debug project path and not where the exe is I did put [DllImport("MyDll.dll")] before the required method...
If I understood Peter's answer correctly, then all I had to do was to make sure a copy of MyDll.dll exists in the same directory where the exe is, right


 
 
zawmn83





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

I declare functions for excel export like that

<DllImport("ExcelFG.dll", EntryPoint:="SetCell")> _

Shared Sub SetCell(ByVal nRow As Integer, ByVal nColumn As Integer, ByVal cellValue As Byte())

End Sub

<DllImport("ExcelFG.dll", EntryPoint:="WriteFile")> _

Shared Sub WriteFile()

End Sub

And loading the dynamic dll path like that

Dim DLLPath As String

DLLPath = Server.MapPath("bin\") & "ExcelFG.dll"

Dim mlib As IntPtr = LoadLibrary(DLLPath)

If mlib = 0 Then

Response.Write("Load Library Fail" & Server.MapPath("bin\") & "ExcelFG.dll")

Exit Sub

End If

And free the loaded library with

FreeLibrary(mlib)

Everything is work fine for my asp application. But after I call the function, ExcelFG.dll is access deny and can't delete or overwrite. What is the problem

this dll can only delete or overwrite when I stop w3wp.exe from task manager.



 
 
Anil15





PostPosted: Visual C# Language, DLLImport - using dynamic file path Top

I am using the delegate to call a dll function , but suppose one function (inside my c# code) for which i am writing the delegate is calling another dll function .., then to make that call happen, should i write another delegate for second function which is called inside function1.
e.g. : Let F1() is a function inside my dll , for which i am writing this delegate.
public delegate ret_type FD1()
public static ret_type F1()
{
// here another function F2() is to be called which is also inside my dll.
// how to call this function F2()
}
thanks in advance,
Anil.