PDA

View Full Version : Checking the existence of a symbolic link file



ofer88
14th July 2012, 00:27
Hi guys,

Maybe I'm missing something here, but it appears there is no way to check the existence of a file that is a symbolic link (a shortcut in windows).

I am using windows. Suppose I have the full file name : "C:/test/a.lnk", and I want to check whether the file "a.lnk" exists or not (and not whether the file it is pointing to exists or not!).
How can I do this??
Both QFile::exists() and QFileInfo::exists() methods don't check for the existence of 'a.lnk', but for the existence of the pointed file (bad idea if you ask me).
Any insights?

Thanks!
Ofer

wysota
15th July 2012, 10:26
A Windows shortcut is not a link. Qt does not offer any API for manipulating Windows shortcuts. Use native API for that.

HellStorm
15th July 2012, 13:02
Hi,

I have the same problem and need to check the existence of a *.lnk file, not the target.

Apparently QFile::exists(), QFileInfo::exists() and QDir::exists() all check the *.lnk target. I also think that its a bad idea how the existence check was implemented.


A Windows shortcut is not a link. Qt does not offer any API for manipulating Windows shortcuts. Use native API for that.
ofer88 did not ask how to manipulate Windows shortcuts.

Perhaps it would be appropriate to file a bug report? Any help is welcome.

Thanks

wysota
15th July 2012, 13:36
ofer88 did not ask how to manipulate Windows shortcuts.
Yes, he did. So did you.

http://en.wikipedia.org/wiki/File_shortcut
http://en.wikipedia.org/wiki/Soft_link

HellStorm
15th July 2012, 14:57
Yes, he did. So did you.

http://en.wikipedia.org/wiki/File_shortcut
http://en.wikipedia.org/wiki/Soft_link

Thanks for replying. This might be offtopic but here we go. I have read those articles and am still not understanding how we are asking for shortcut manipulation.
Shortcuts (not symbolic links) are files like any other file in Windows. Checking if a file exists is manipulating that file?

In the meantime I am using native APIs:


bool fileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);

return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

For reasons why I am using GetFileAttributes() and not FindFirstFile(), resort to the following post:
http://blogs.msdn.com/b/oldnewthing/archive/2007/10/23/5612082.aspx

wysota
15th July 2012, 15:19
You can try with QFileInfo. QFileInfo::isSymLink() docs seem to suggest the class can differentiate between a shortcut and its target. However QFileInfo::exists() will again work on the link target.

You should be able to do this:


bool shortcutExists(const QString &filePath) {
return !QFileInfo(filePath).symLinkTarget().isEmpty();
}

Note, if the file is a real symlink (as in NTFS symlink), you might get a false positive.

HellStorm
15th July 2012, 15:51
You should be able to do this:


bool shortcutExists(const QString &filePath) {
return !QFileInfo(filePath).symLinkTarget().isEmpty();
}


That is a nice idea which led to this:



bool fileExists(const QString &path)
{
QFileInfo fileInfo(path);
return fileInfo.exists() || fileInfo.isSymLink();
}


I can't use QFileInfo::symLinkTarget() in a 64bit Windows environment because QtCreator only compiles to 32bit. Win x64 redirects target resolving of links from x86 programs to x86 directories even if they point to the x64 version ("Program Files" vs "Program Files (x86)"). The native Windows functions do this, so there is no workaround apart from writing a small x64 translation program and using IPC for example, which I did but thats another topic.

ofer88
15th July 2012, 21:17
Thank you all! That was very helpful.
And I agree with HellStorm, perhaps it is appropriate to file a bug report regarding the behavior of QFileInfo::exists() etc.