Convert UNC Path to its corresponding mapped Drive path? - delphi

On my test system (Windows 10 x64), the UNC PATH \\Mac\Home\Documents is mapped to Y:\Documents. Is there a Delphi function to generally convert a UNC Path to its corresponding mapped Drive path (if it has one)?
function ConvertUNCPathToDrivePath(const AUncPath: string): string;
This would convert \\Mac\Home\Documents to Y:\Documents.

AFAIK, there are no functions to convert a UNC path to a mapped-drive path.
However, there are Win32 API functions, such as WNetGetConnection() and WNetGetUniversalName(), which can be used to convert a mapped-drive path to its UNC path.
You can enumerate the local drive letters and see if any of them convert to the UNC you are interested in.

Related

Changing paths in Delphi

I am working on a project where I need to play a video from a file in Delphi. I often work from home and school, and I have the problem that at home, my USB is drive 'J' and at school my USB is drive 'D'.
I manually go and change it every time. Is there a way for Delphi to automatically get the video from where ever it is?
Each sector has an image component laid over it for selecting the sector.
*Note, I know I can search for a specific file's location in Delphi, but I have over 24 different places where I need to play different videos, so searching would probably be my last resort, unless I use a procedure and set constants for each sector to differenciate between them.
The code currently looks as follows:
procedure TtForm.imgSector1Click(Sender: TObject);
begin
//Variables,this is for initializing them when I create them later.
//Procedures
SectorDeselect; //Procedure to turn all sector borders white
// Video
WindowsMediaPlayer1.Controls.stop;
WindowsMediaPlayer1.URL := 'J:\IT\PAT\phase 2\Videos\Footage1.mp4'; //Where my problem lies
WindowsMediaPlayer1.Controls.Play;
// Sector Info. The memos and Rich edits
redSectorInfo.Lines.Clear;
redSectorInfo.Lines.Add('');
// Sector. Highlighting the sector borders surrounding the sector
SectorBordr1.Brush.Color := clGreen;
SectorBorder10.Brush.Color := clGreen;
end;
I would suggest adding a TEdit control in your app's UI to let you specify the base drive/path for the files on the machine the app is currently running on. Your code can then construct individual file paths at runtime that are relative to that base path. Don't use hard-code paths in your code.
You can then save that base path into the Windows Registry in a new key you create, ie HKEY_CURRENT_USER\Software\MyApp. Or, you can save the path in a configuration file (INI, XML, JSON, etc) created in a subfolder in your Windows user profile, like %APPDATA%\MyApp. Your code can then read in that base path each time the app is run.
If the files are stored on a USB drive, an alternative solution would be to simply enumerate the available drives at runtime, such as with GetLogicalDriveStrings(). For each drive, append a relative path for a given file onto the end of it, and then check if that file exists, such as with FileExists(). If so, you now know which drive to use for all of the files until the next time your app is run (you can save the drive path between runs, as described above). If the file is not found, move on to the next drive.
What about adding a parameter on the CommandLine?
Start
D:\myfolder\myfile D
OR
Start
J:\myfolder\myfile J
GUI files can accept a parameter. Capture it with code like:
DriveLetter := ParamStr(1);

resolving network shortcut

I added some FTP servers via network shortcuts to windows.
How can I get the FTP address via the WinAPI?
With SHGetFolderPath / CSIDL_NETHOOD, I can get the location of the target.lnk file. But how can I get the FTP URL of that file?
A "normal" .lnk file, I can resolve with this:
ShellLink := CreateComObject(CLSID_ShellLink) as IShellLink;
ShellLink.QueryInterface(IPersistFile, PersistFile);
PersistFile.Load('C:\Test.lnk', STGM_READ);
ShellLink.Resolve(WindowHandle, 0);
Filename[0] := #0;
ShellLink.GetPath(PChar(#Filename[0]), Length(Filename), pfd, 0);
... but this does not work for the Target.lnk files of the network shortcuts to ftp://host/ adresses.
IShellLink::GetPath is used to retrieve a file system path (only drive letter or UNC roots). This is not clear from the documentation but it uses SHGetPathFromIDListEx internally and MSDN has this to say about that function:
Converts an item identifier list to a file system path
If you want the raw shortcut target your best bet is usually IShellLink::GetIDList. You can get the parsing name by using SHGetNameFromIDList(..., SIGDN_DESKTOPABSOLUTEPARSING, ...) on the id-list.

Racket: How to retrieve the path of the running file?

I need a way to get the path of the running script (the directory that contains the source file), but
(current-directory)
never points there (in this case an external drive), but rather to some predefined location.
I created a file to try all the 'find-system-path's, but none of them are the running file! The Racket docs are not helping.
#lang web-server/insta
(define (start request)
(local [{define (build-ul items)
`(ul ,#(map itemize items))}
{define (itemize item)
`(li ,(some-system-path->string (find-system-path item)))}]
(response/xexpr
`(html
(head (title "Directories"))
(body (h1 ,"Some Paths")
(p ,(build-ul special-paths)))))))
(define special-paths (list 'home-dir
'pref-dir
'pref-file
'temp-dir
'init-dir
'init-file
;'links-file ; not available for Linux
'addon-dir
'doc-dir
'desk-dir
'sys-dir
'exec-file
'run-file
'collects-dir
'orig-dir))
The purpose is for a local web-server application (music server) that will modify sub-directories under the directory that contains the source file. I will be carrying the app on a USB stick, so it needs to be able to locate its own directory as I carry it between machines and operating systems with Racket installed.
Easy way: take the running script name, make it into a complete path,then take its directory:
(path-only (path->complete-path (find-system-path 'run-file)))
But you're more likely interested not in the file that was used to execute things (the web server), but in the actual source file that you're putting your code in. Ie, you want some resources to be close to your source. An older way of doing this is:
(require mzlib/etc)
(this-expression-source-directory)
A better way of doing this is to use `runtime-path', which is a way to define such resources:
(require racket/runtime-path)
(define-runtime-path my-picture "pic.png")
This is better since it also registers the path as something that your script depends on -- so if you were to package your code as an installer, for example, Racket would know to package up that png file too.
And finally, you can use it to point at a whole directory:
(define-runtime-path HERE ".")
... (build-path HERE "pic.png") ...
If you want the absolute path, then I think this should do it:
(build-path (find-system-path 'orig-dir)
(find-system-path 'run-file))

How to convert Path to 8.3 format with Inno Setup

I need to get 8.3 formatted path (in this case {app}) for registry entry.
Unfortunately this specific Delphi function does not work in Inno Setup
function ExtractShortPathName(const S: FullFileName): string;
Use the GetShortName function. From the reference:
Returns the short version of the specified long filename. If the short
version of the long filename is not found, the long filename is
returned.

How do I obtain the full path of an isolated storage file

How do I obtain the fully qualified path of an isolated storage file for a WPF application?
You can use reflection to do so, as shown in the linked forum post:
IsolatedStorageFileStream oStream =
new IsolatedStorageFileStream(ISOLATED_FILE_NAME, FileMode.Create, isoStore);
// Get the physical path using reflection
String filePath = oStream.GetType().GetField("m_FullPath",
BindingFlags.Instance | BindingFlags.NonPublic).GetValue(oStream).ToString();
Console.WriteLine(filePath);
On Windows 10 Mobile the isolated-storage-path is equal to Windows.Storage.ApplicationData.Current.LocalFolder.
If you know the relative file-path inside the isolated-storage you can use System.IO.Path.Combine() to create the full path.
You can use IsolatedStorageFile.GetUserStoreForApplication().GetFileNames() to list all files in the isolated-storage.

Resources