0_o Posted May 5, 2019 Report Share Posted May 5, 2019 Hi, I'm trying to convert a local file path c:\... to a URI path file:///wdcwdc%20wdcwc... Windows MPR.dll (C:\Windows\System32\mpr.dll) does that conversion using WNetGetUniversalNameA https://docs.microsoft.com/en-us/windows/desktop/api/winnetwk/nf-winnetwk-wnetgetuniversalnamea#see-also For some reason, I don't get the prototype to work using the call dll function. Help will be much appreciated. Quote Link to comment
Darin Posted May 5, 2019 Report Share Posted May 5, 2019 Well, there is a lot that could go wrong and not a lot of info to go on. If not working = crash, then I would check the calling convention. Windows API calls not-surprisingly use the WINAPI setting which is very easy to overlook. If not working = non-zero return value then you have to follow the links for system errors, mostly make sure that you are using a valid path from a mapped network drive. Other than that this function should work for you. It is similar to many other Windows API functions. The buffer upon return will have 1 or 3 pointers (these will be U32 or U64 depending on the dll bitness) after the pointers will come the 1 or 3 C strings. If you try to simply return a C string (with some min length of say 1024), you will either get a buffer with some random bytes (the addresses) followed by the string you want, or about 1% of the time, the buffer address you pass in will have a zero in it and you will get just a couple of bytes and no string. In this case you could simply retry and you'll get a different address that probably works. To be totally safe you can use the vi.lib functions to create a buffer with sufficient length (DSNewPtr), and then use GetValueByXNode to dereference a cluster with a single U32 or U64 (depends on dll bitness) and a string (for infoLevel=1) or 3 U32s/U64s and a string (for infoLevel=2). In this case the buffer parameter is simply passed as a pointer sized integer. About all the help I can offer at the moment with no idea what the real failure mode is, and no LV around to show you an example. Quote Link to comment
LogMAN Posted May 6, 2019 Report Share Posted May 6, 2019 Find a working implementation here https://www.labviewforum.de/Thread-Aktuellen-VI-Pfad-als-UNC?pid=133946#pid133946 Quote Link to comment
Rolf Kalbermatter Posted May 6, 2019 Report Share Posted May 6, 2019 (edited) 5 hours ago, LogMAN said: Find a working implementation here https://www.labviewforum.de/Thread-Aktuellen-VI-Pfad-als-UNC?pid=133946#pid133946 This implementation has a few limitations, one of them being that it will only work for 32 bit systems and also that it makes assumptions about how the buffer is allocated that may not necessarily true. Basically it assumes that the string the pointer in the first 4 bytes is pointing at are directly following the pointer itself in memory. While this is probably usually true there is no guarantee that this is the case as there might be certain memory allocation strategies used in the underlaying function that might place the actual string in some other location in the returned buffer. So beware when using this in your VI and make a notice that it will definitely not work as is for 64-bit LabVIEW. Also the title is indicating that this function is not the correct one to use. URI is the abbreviation for Universal Resource Identifier which usually follows the format (and that matches the example given by the OP) protocol://[gebruiker:wachtwoord@]host(naam)[:poort]/path The mentioned function will instead return the Windows UNC (Universal Naming Convention) path to a network shareable path if it exists, which has the format: //servername/share/path Edited May 6, 2019 by Rolf Kalbermatter Quote Link to comment
0_o Posted May 6, 2019 Author Report Share Posted May 6, 2019 (edited) Thanks for the replies! Darin, I wasn't sure if I filled in the prototype correctly according to the help. LogMAN, this is the exact example I was working on. It used to work and now it gives me error 2250. Which brings me to what Rolf said... it is not compatible with Win 64bit. I moved the application from 32bit to 64bit. Rolf, I have MPR.dll in my Win10 64bit and I need the URI, not the UNC (I thought that code used to give the URI yet the last time it was used was before my time so...) What do I need to change in the code to make it compatible with 64bit, safe to use and that it will return the URI? Thanks in advance. Edited May 6, 2019 by 0_o Quote Link to comment
Rolf Kalbermatter Posted May 6, 2019 Report Share Posted May 6, 2019 This should be a 32/64 bit safe implementation. Network Path Name 2016.vi Quote Link to comment
0_o Posted May 6, 2019 Author Report Share Posted May 6, 2019 Thanks! That's a great example for me to learn how to handle DLL's correctly. However, I still get the 2250 error after choosing, for example, C:\ROI 123.bmp in the input. I was expecting to get file:///C:/ROI%20123.BMP Quote Link to comment
Darin Posted May 6, 2019 Report Share Posted May 6, 2019 I should have seen from the original post that you are using the wrong function. The function you described takes an existing share (mapped network drive for example) and resolves the mapping (server name from mapped drive letter, for example). You are looking for the URI for a local file, there is a simple .NET function to do that. 1 Quote Link to comment
Rolf Kalbermatter Posted May 6, 2019 Report Share Posted May 6, 2019 (edited) As I already mentioned in my first post (after an edit), this Windows API function does not convert to an URI but to UNC. And it does not work for a local path that you shared but only for a local path that was mapped from a network path. So assume you have a network share somewhere on your production server named PRODUCTION with a share TESTDATA then the UNC path to that is \\PRODUCTION\TESTDATA. If you map this path to a local drive P:\Production you can use above function to convert P:\Production\<some path> back into \\PRODUCTION\TESTDATA\<some path>. Nothing more and nothing less. These functions specifically do NOT deal with URI paths but only with UNC paths. Edited May 6, 2019 by Rolf Kalbermatter Quote Link to comment
Rolf Kalbermatter Posted May 6, 2019 Report Share Posted May 6, 2019 (edited) 6 minutes ago, Darin said: I should have seen from the original post that you are using the wrong function. The function you described takes an existing share (mapped network drive for example) and resolves the mapping (server name from mapped drive letter, for example). You are looking for the URI for a local file, there is a simple .NET function to do that. Check on stack overflow! These .Net functions can misbehave for certain paths as they do not properly escape all characters (specifically the % character) that should be escaped. But they might work for the OP's use case. https://stackoverflow.com/questions/1546419/convert-file-path-to-a-file-uri new Uri(@"C:\%51.txt").AbsoluteUri; This gives you "file:///C:/Q.txt" instead of "file:///C:/%2551.txt". Also you should probably close the .Net Refnum after use. Edited May 6, 2019 by Rolf Kalbermatter Quote Link to comment
ShaunR Posted May 6, 2019 Report Share Posted May 6, 2019 2 hours ago, 0_o said: Thanks! That's a great example for me to learn how to handle DLL's correctly. However, I still get the 2250 error after choosing, for example, C:\ROI 123.bmp in the input. I was expecting to get file:///C:/ROI%20123.BMP Error 2250 is the windows error code for "This network connection does not exist.". It seems consistent with what Rolf is saying about the function. Quote Link to comment
0_o Posted May 12, 2019 Author Report Share Posted May 12, 2019 Thanks for all the replies. The .net works just fine, maybe the guy in StackOverflow used an old .net version or something went wrong in his code. I attached the vi that demonstrates that the bug is not existing anymore. Issue solved URI.vi Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.