Announcement

Collapse
No announcement yet.

DLL Path

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DLL Path

    I have recently modified a DLL to record certain aspects, e. g. data returned. Previously I placed the DLL in the calling app's path, but I want to put it in a path that is NOT in the windows search path. I can hard-code the path; however, I do not want to do that simply because I may move it.

    Is there a way the DLL can find it's own location?
    Walt Decker

  • #2
    > Is there a way the DLL can find it's own location?
    OCX's and DLL's are sometimes registered, but don't know if it could be done with a standard PB DLL.
    Sounds like COM. Hopefully someone will jump in.
    https://duckduckgo.com instead of google

    Comment


    • #3
      If I understand the scenario correctly (EXE calls DLL, but DLL location might not be know at EXE compile time), I suggest you have a look at the API LoadLibrary / LoadLibraryEx. I'm pretty sure there are samples for its usage here in this forum.

      Comment


      • #4
        LoadLibrary will not work unless the DLL is in the windows path search sequence or the fully qualified path is stated.

        The DLL does NOT know where it is on disk. An .EXE can find itself. I am looking for a way that the DLL can find itself so I do not have to hard code it's location.
        Walt Decker

        Comment


        • #5
          Walt,
          The calling EXE has to know the DLL location, so how about letting the EXE pass that known location to the DLL?

          Comment


          • #6
            Mr. Beene, that is the solution I just thought of. The dll is sort of like a common dialog so it will be loaded dynamically. What I will do is create a thread that will search for it while other things are happening, When it is found the location will be placed in either a static or global variable which will be passed to the dll on call.

            Not the best solution, but it should work.

            Thank you all for your ideas and input!
            Walt Decker

            Comment


            • #7
              A DLL that can be anywhere? The virus checkers will not like that. How about a registry entry or a subdirectory of main application.
              https://duckduckgo.com instead of google

              Comment


              • #8
                Mr. Doty, it can be used by a variety of apps each residing in a different location. For example, the color-picker and choosefont dialogs are in a location different from all the other apps that use them. Windows knows where they are, so there is no problem. This dll is similar but performs different functions.
                Walt Decker

                Comment


                • #9
                  Walt, what is the problem with placing the DLL in the system path ? That is the normal way to get the access you require from any location on the machine.
                  hutch at movsd dot com
                  The MASM Forum

                  www.masm32.com

                  Comment


                  • #10
                    I agree with Steve, if it is a shared DLL that can be used by different applications, it should be in the Path. That's the whole purpose of the Path.

                    Comment


                    • #11
                      Walt, here is some exe and dll code.
                      The dll will know it's ownn path via GetModuleFileName(hDllInstance...).

                      Code:
                      #COMPILE EXE "Test03.exe" '#Win#
                      #DIM ALL
                      #INCLUDE "Win32Api.inc"
                      
                      DECLARE FUNCTION DllInstance LIB "Test03.dll" ALIAS "DllInstance" AS DWORD
                      
                      $AppName  = "Get DLL path"
                      %Button01 = 101
                      
                      GLOBAL hDlg AS DWORD
                      '_____________________________________________________________________________
                      
                      CALLBACK FUNCTION DlgProc
                      
                       SELECT CASE CBMSG
                         CASE %WM_COMMAND
                           IF CBCTL = %Button01 THEN
                             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
                      
                               LOCAL zExe         AS ASCIIZ * %MAX_PATH
                               LOCAL zDll         AS ASCIIZ * %MAX_PATH
                               LOCAL hDllInstance AS DWORD
                               hDllInstance = DllInstance()
                               GetModuleFileName(hDllInstance, zDll, SIZEOF(zDll))
                               GetModuleFileName(%NULL, zExe, SIZEOF(zExe))
                               MessageBox(hDlg,"Now in EXE" & $CRLF & "Exe: " & zExe & $CRLF & "DLL: " & zDll, $AppName, %MB_OK OR %MB_TOPMOST)
                      
                             END IF
                           END IF
                       END SELECT
                      END FUNCTION
                      '_____________________________________________________________________________
                      
                      FUNCTION PBMAIN()
                       LOCAL hIcon AS DWORD
                      
                       DIALOG FONT "Segoe UI", 9
                       DIALOG NEW %HWND_DESKTOP, $AppName, , , 150, 50, _
                       %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, %WS_EX_LEFT TO hDlg
                      
                       hIcon = ExtractIcon(GetModuleHandle(""), "Shell32.dll", 294) 'o
                       SetClassLong(hDlg, %GCL_HICON, hIcon)
                      
                       CONTROL ADD BUTTON, hDlg, %Button01, "Get DLL path", 50, 18, 50, 15
                       DIALOG SHOW MODAL hDlg CALL DlgProc
                      
                       DestroyIcon(hIcon)
                      
                      END FUNCTION
                      '_____________________________________________________________________________
                      '
                      Code:
                      #COMPILE DLL "Test03.DLL" '#Win#
                      #DIM ALL
                      #INCLUDE "Win32Api.inc"
                      
                      GLOBAL hDllInstance AS DWORD
                      '______________________________________________________________________________
                      
                      FUNCTION DllInstance ALIAS "DllInstance"() EXPORT AS DWORD
                       LOCAL zExe AS ASCIIZ * %MAX_PATH
                       LOCAL zDll AS ASCIIZ * %MAX_PATH
                      
                       GetModuleFileName(hDllInstance, zDll, SIZEOF(zDll))
                       GetModuleFileName(%NULL, zExe, SIZEOF(zExe))
                       MessageBox(%HWND_DESKTOP,"Now in DLL" & $CRLF & "Exe: " & zExe & $CRLF & "DLL: " & zDll, zDll, %MB_OK OR %MB_TOPMOST)
                       FUNCTION = hDllInstance
                      
                      END FUNCTION
                      '______________________________________________________________________________
                      
                      FUNCTION LIBMAIN(BYVAL hInstance AS DWORD, BYVAL lReason AS LONG, BYVAL lReserved AS LONG) AS LONG
                      
                       SELECT CASE AS LONG lReason
                      
                         CASE %DLL_PROCESS_ATTACH
                           hDllInstance = hInstance
                           LIBMAIN = 1
                           EXIT FUNCTION
                      
                         CASE %DLL_PROCESS_DETACH
                           EXIT FUNCTION
                      
                         CASE %DLL_THREAD_ATTACH
                           EXIT FUNCTION
                      
                         CASE %DLL_THREAD_DETACH
                           EXIT FUNCTION
                      
                       END SELECT
                       LIBMAIN = 0
                      
                      END FUNCTION
                      '______________________________________________________________________________
                      '

                      Comment


                      • #12
                        Originally posted by Walt Decker View Post
                        LoadLibrary will not work unless the DLL is in the windows path search sequence or the fully qualified path is stated.
                        Indeed.

                        The DLL does NOT know where it is on disk. An .EXE can find itself. I am looking for a way that the DLL can find itself so I do not have to hard code it's location.
                        There's no (easy) way to do that with a standard Win32 DLL, as it simply lacks the mechanism, which e.g. COM DLLs do provide.

                        You can do all sorts of shenanigans, e.g. an installer for the DLL which writes the DLL's location to the registry or other locations. Or create a folder <YourCompany> under "Common", as MS and others do it.

                        Comment


                        • #13
                          Knuth, if I may ask, did you try the code above?

                          Comment


                          • #14
                            No, I didn't, because I know what it does.

                            But how is the DLL supposed to be started (and therefore be able to run that code), if the calling EXE doesn't know its location? And if the EXE knows how to call the DLL, the point of the code is kinda moot, don't you think?

                            Comment


                            • #15
                              I didn't run Pierre's code either since it won't be found.

                              Back to trying to register a DLL.

                              Create a folder named c:\junk

                              A standard DLL will execute with regsvr32 test.dll or regsvr32 /u test.dll
                              If /s switch is used it will only go through its shutdown.
                              Of course, this isn't of any use to callers.

                              Is there a way to get a standard DLL to be registered?
                              If it could, how would it be loaded from anywhere?
                              Looks like this would be done with COM.

                              What is wrong with using the path or the registry, he wondered.
                              Windows automatically tracks some renamed files, but not sure that could be applied to a DLL.

                              Walt,
                              Using MAP or NET SHARE a location might be assigned and put the DLL in there.

                              Code:
                              #DIM ALL
                              #COMPILE DLL "C:\JUNK\TEST.DLL"
                              #INCLUDE "win32api.inc"
                              
                              GLOBAL gNumOfTimes AS DWORD
                              GLOBAL gs AS STRING
                              
                              FUNCTION LIBMAIN(BYVAL hInstance AS DWORD, _
                               BYVAL lReason AS LONG, _
                               BYVAL lReserved AS LONG) AS LONG
                              
                               INCR gNumOfTimes
                              
                               SELECT CASE AS LONG lReason
                                 CASE %DLL_PROCESS_ATTACH
                                   ' This DLL has been mapped into the memory context of
                                   ' the calling program, and can be initialized as required.
                                   ' Here we return a non-zero LIBMAIN result to indicate success.
                                   LIBMAIN = 1
                                   gs+="LIBMAIN=1" + $CR
                                   EXIT FUNCTION
                                 CASE %DLL_PROCESS_DETACH
                                   gs += "This DLL is about to be unloaded" + $CR
                                   ? gs
                                   EXIT FUNCTION
                                 CASE %DLL_THREAD_ATTACH
                                   gs+= " A [New] thread is starting (see THREADID)" + $CR
                                   EXIT FUNCTION
                                 CASE %DLL_THREAD_DETACH
                                   gs+="This thread is closing (see THREADID)" + $CR
                                   EXIT FUNCTION
                               END SELECT
                              
                               ' Theoretically execution should never get to this point.
                               ' However, if the DLL is being implicitly linked then return
                               ' Zero (0) and the process (program) will fail to start
                               ' running. For Explicit linking, returning Zero (0) will
                               ' simply cause the LoadLibrary/LoadLibraryEx API call to fail.
                               LIBMAIN = 0 ' Indicate failure to initialize the DLL!
                              
                              END FUNCTION
                              
                              SUB Tester ALIAS "Tester" EXPORT
                               MSGBOX "TestIt" + $CRLF + "gNumOfTimes =" + STR$(gNumOfTimes)
                              END SUB
                              https://duckduckgo.com instead of google

                              Comment


                              • #16
                                I have recently modified a DLL to record certain aspects, e. g. data returned. Previously I placed the DLL in the calling app's path, but I want to put it in a path that is NOT in the windows search path. I can hard-code the path; however, I do not want to do that simply because I may move it.

                                Is there a way the DLL can find it's own location?
                                ---
                                No. Functions in a dll can only be used after being loaded into the process space of an exe.
                                ---


                                --- Here is a solution ---
                                Hard-code share name in declare statement.
                                Create/change path of files in share statement.


                                Create share statement:
                                net share walt /delete
                                net share walt=c:\junk /grant:everyone,full

                                Code:
                                #COMPILE EXE
                                DECLARE SUB tester LIB "\\localhost\walt\test.dll"
                                FUNCTION PBMAIN () AS LONG
                                 tester
                                END FUNCTION

                                These would all work in the declare statement:
                                "\\computername\walt\test.dll"
                                "\\127.0.0.1\walt\test.dll"
                                "\\localhost\walt\test.dll"
                                Last edited by Mike Doty; 10 Jan 2020, 05:30 PM.
                                https://duckduckgo.com instead of google

                                Comment


                                • #17
                                  Gentlemen,

                                  Sorry for the late response. Was 80 miles away with some health issues.

                                  I am exploring putting the dll in the path. I am not very familiar with what win10 will let me get away with or what the win10 path is. My original thought of having an app look for it did work out; however, it is not very useful if someone
                                  writes an app and wants to use my dll.

                                  Thank you for your help.
                                  Walt Decker

                                  Comment


                                  • #18
                                    Hope you are ok!
                                    Copy DLL's to c:\windows\system32 or let your installer do everything https://www.jrsoftware.org/isinfo.php
                                    The share in post#16 above did work.
                                    https://duckduckgo.com instead of google

                                    Comment


                                    • #19
                                      You wrote this dll? Make an SLL and link it in.

                                      Comment


                                      • #20
                                        Get a copy of FILEMON and watch how windows goes looking for stuff. I think it always starts with the directory the exe is running from.

                                        Why not just put it in a sub directory under the exe directory? Assuming you dont want it in the exe directory.

                                        Comment

                                        Working...
                                        X