cancel
Showing results for 
Search instead for 
Did you mean: 

Is there a property to get the server's executable path?

VolkerBarth
Contributor
0 Kudos
3,383

Since V9, there is that property CommandLine to the database server's command line.

However, it just returns the program arguments but does not contain the executable's path.

For example, on my box, the returned value for the SA 12 demo database is similar to

"-c 8M -n demo C:\\...\\demo.db"

Question:

Is there a way to get the executable's path, too?

If not, I would like to suggest such a property.

(Workarounds seem not that easy, cf. my comments on John's answer.)

Accepted Solutions (0)

Answers (2)

Answers (2)

johnsmirnios
Employee
Employee

I don't see any property that would give you the executable's path but on Windows you could do it with an external function that calls GetModuleFileName().

-john.

VolkerBarth
Contributor
0 Kudos

Well, the question came up on Breck's current blog article (cf. the comments on http://sqlanywhere.blogspot.com/2011/02/loading-32-bit-versus-64-bit-dlls_16.html). And there's the problem: These Win32 APIs won't work when used from a DLL running in an external C/C++ environment. If I understand the API documentation correctly, it won't give me a module handle to the server's process when called from a different process. - I'd add a product suggestion:)

Breck_Carter
Participant
0 Kudos

@Volker: FWIW GetModuleFileName() is different from the API that didn't work for me (GetCommandLine), so it's not clear that the same problem exists for it.

VolkerBarth
Contributor
0 Kudos

@Breck: I just checked a bit more, and I was wrong: You can also use GetModuleFileName() with a handle of a different process (as you will need when inside an external environment). The PSAPI will help here. You might enumerate and open all processes with EnumProcesses() and OpenProcess(), then use EnumProcessModules() to get all module handles of the opened process, and then use GetModuleBaseName() and the server's version and the IsNetworkServer() property to look for a module named dbengX/dbsrvX, and once you find such a handle, THEN you can call GetModuleFileName() to get the full path.

VolkerBarth
Contributor
0 Kudos

@Breck: I've used that technique in own code (not a SQL Anywhere DLL) - but I guess my product suggestion makes sense, doesn't it:)

VolkerBarth
Contributor
0 Kudos

@Breck: Just to add: 1. Obviously that code works just on the server's box (but that's o.k. for an external function). 2. In case the box runs several engines of the according version installed in different locations (e.g. one of an OEM install) - well, then you might get the wrong file path. - Just a little bit of paranoia:)

johnsmirnios
Employee
Employee
0 Kudos

As Karim noted, I was suggesting a regular external function -- not an external environment.

Former Member

@Volker: John's suggestion was to use an external function but have it loaded by the server rather than run it in an external environment. So basically your CREATE FUNCTION statement would not have a language clause. If you wrote such a function, then calling GetModuleFileName should work since the loading module is the server.

VolkerBarth
Contributor
0 Kudos

OK, yes, then it would defintely be quite simple. But then it would need to fit the server's bitness, and the original problem that raised this question (cf. Breck's blog) was to get rid of bitness-specific DLLs by using an external environment...

johnsmirnios
Employee
Employee
0 Kudos

The server should scan for the DLL with the specified name with the correct bitness if that is not already happening. The EXTERNAL NAME clause should probably be changed to allow a different explicit path to be provided for each bitness too: "Win32:...;Win64:...".

VolkerBarth
Contributor
0 Kudos

@John: So you suggest (or plan?) to extend the syntax (currently only used to distinguish Unix from Windows calls) to differentiate between 32 and 64 bit versions, too (like in the oooold days with Windows95, Windows3X)? - That's a good and reasonable idea IMHO.

VolkerBarth
Contributor
0 Kudos

Nevertheless, I still think such a general thing as the database engine's path should be easily accessable via a server property.

johnsmirnios
Employee
Employee

@Volker: I'm not "planning" anything yet but can log suggestions as enhancement requests. I looked at the code and we essentially use LoadLibrary without scanning for a DLL with the correct bitness first. So we are at the mercy of Windows search rules: http://msdn.microsoft.com/en-us/library/ms682586%28v=vs.85%29.aspx

It seems that Windows always loads DLLs from the same directory as the app first. If you are embedding SA, just put the correct bitness of the external function in the same directory as dbeng/dbsrv and you should be fine.

If not embedding, finer control would be desirable.

johnsmirnios
Employee
Employee

@Volker: Getting the server's executable path seems like a reasonable suggestion. As it stands, I don't think we have found a way to get the executable's path on AIX yet though.