Jump to content
0_o

converting local path to URI

Recommended Posts

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.

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
5 hours ago, LogMAN said:

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 by Rolf Kalbermatter

Share this post


Link to post
Share on other sites

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 by 0_o

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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.

 

 

WindowsURI.png

  • Thanks 1

Share this post


Link to post
Share on other sites

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 by Rolf Kalbermatter

Share this post


Link to post
Share on other sites
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.

 

 

WindowsURI.png

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 by Rolf Kalbermatter

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.