I am developing an app for Mac and Windows with Qt. I am monitoring changes to Folder X. When a file is copied from somewhere to Folder X, I read its lastModified() date. On Windows it shows the original file's last modified date of the file, which is expected. However, on Mac it returns the Current DateTime. When I rename the file, after it has been copied to Folder X, I get the original file's last Modified date on both Windows and Mac.
So why does Qt on Mac return current DateTime when the file is copied, and returns original file's modified time after I rename the file?
date timestamps are not reliable enough to implement a folder monitoring system, as you've implied above.
i've have spent a few months writing a reliable folder monitoring system on both mac and windows. turned out each required completely different strategies.
on mac: each file and folder can be uniquely identified with an inode number (look in <sys/stat.h>), this number can then used for diff'ing a folder structure to determine changes.
on win: windows also has stat, however this number does not persist and thus cannot be used. i created a solution that uses ReadDirectoryChanges which is a part of the windows api.
Related
I have a compiled program which runs great after being compressed, copied to another computer using a USB key, extracted and ran.
However, if I upload the compressed file to Google Drive or Dropbox, download it and extract it, the program will not run. It gives me an error "program.exe has stopped working".
Using a tool called WinMerge, I compared the program that was extracted from a USB drive with the program that was extracted after being downloaded. Every file, both binary and text, was identical.
Next I used attrib -r -a -s -h on every program file in both folders, thinking perhaps one of the file attributes was incorrect. I still had the same problem; the copied program works, the downloaded one does not.
I also tried changing the name and location of the folders the program was in but it had no effect.
The only thing I can think of is some additional attribute that Windows gives files which were downloaded from the internet, to possibly trigger an additional UAC check which is interfering with the program. Does this exist?
This is on Windows 7.
Found the problem. Windows adds an Alternate Data Stream (ADS) to every file downloaded off the internet. For some reason, these streams were preventing the program from running. Stripping the ADS from each file allows it to run.
I used a Windows Sysinternals program called Streams to strip the ADS data.
I have a 32-bit windows old application (with the C/Win32 source) that creates its data file in the same folder where the executable is.
Because the application has no installation program and the user can place the executable wherever he/she wants, the application has a dialog to inform the user where its data is located.
But under Microsoft Vista/Seven if the user puts the application in the Program Files or any other system-protected folder the data file gets virtualized and moved to a virtual-store.
If, under Vista/Seven, I still want to inform the user where the data file is located:
(without preventing virtualization in the manifest file)
How can I know (programatically) if the data file is virtualized? Or if the folder where the executable is located implies that data file will be virtualized?
Assuming I know the data file is virtualized, how can I know (programatically) the location of the virtual folder, to show it in the information dialog?
I have found the following question very close to what I'm asking but it doesn't show the solution (if any) of knowing when virtualization is taking place for a file, and where it gets virtualized.
How to detect file redirection to the Windows VirtualStore?
Virtualization is transparent to the app. The only way to know whether it is being virtualized is to ask the OS, per the answer in the question you linked to (use GetTokenInformation() with the TokenVirtualizationEnabled flag), but there is no way (that I know of) of asking the OS where the virtualized items are actually stored, as it may be different from one OS version to the next. You will have to do some research and then hard-code the paths for each given OS that your app detects at runtime.
If you are going to update your code to detect virtualization, then you are better off updating the code to play nicer with UAC instead. Stop storing your files where they do not belong, and start storing them where Microsoft wants you to store them. In this case, within the user's profile instead. Use SHGetFolderPath() or related function to locate the user's CSIDL_LOCAL_APPDATA folder (or SHGetKnownFolderPath() on Vista+ to locate the FOLDERID_LocalAppData folder), then create a subfolder underneath it for your app to store its data files in.
I am using Qt and Ruby in an application where I have to manipulate some directories and rename/move files. However, prior to the actual manipulation I need to show a "preview", ie, simulation of the changes. What I've done on OS X and Linux is a collection of mkdir and touch commands, in a writable tmp space, to build my said "directory tree", fed that to Qt's QFileSystemModel widget and QTreeView, and I'd get my expected results.
However, I can not do that on Windows, because I have found no native counterpart to touch and thus I could not show the files. One suggestion that came to mind is to create my directory tree in memory, but then I can not feed it to QFileSystemModel anymore.
How can I do this?
Windows comes with a tool called fsutil, which can be used to create dummy files similar to Unix touch command:
fsutil file createnew PathName length
I am not sure if fsutil exist per default on the Home editions of Windows, but at least it is in the professional versions of XP through Windows 7.
See the full documentation for fsutil.
Windows lets you develop a filter driver to catch file I/O's on VFS. But I can't seem to find something similar for Mac. It does have something called Filter Schemes, but those are for HFS+. Anyone know if there is a way for me to intercept file I/O's on Mac without using programs like MacFUSE?
I found out that Mac OS X does not allow filter drivers at all.
“A stacking file system (sometimes called a filter file system) sits on top of another file system and modifies its behavior in some way. The canonical example of a stacking file system is an encryption file system. You could stack this file system on top of any existing file system to provide encryption support. Apple does not support the development of stacking VFS plug-ins on Mac OS X” (http://developer.apple.com/mac/library/qa/qa2001/qa1242.html)
kauth (introduced in OS X 10.4) is the closest thing to FS filter drivers.
Here is a nice write-up on the various APIs present on Mac OS X. It should be a good starting point.
Link
I'm not at all familier with the Windows technologies that you mention, but it sounds like you might be looking for FSEvents.
http://developer.apple.com/mac/library/documentation/Darwin/Conceptual/FSEvents_ProgGuide/Introduction/Introduction.html
The file system events API provides a
way for your application to ask for
notification when the contents of a
directory hierarchy are modified. For
example, your application can use this
to quickly detect when the user
modifies a file within a project
bundle using another application.
It also provides a lightweight way to
determine whether the contents of a
directory hierarchy have changed since
your application last examined them.
For example, a backup application can
use this to determine what files have
changed since a given time stamp or a
given event ID.
You should read this document if your
application works with a large number
of files—particularly if your
application works with large
hierarchies of files.
I have a VB6 desktop application that is deployed on well over 1200 desktops. The devices throughout are a mix of Windows XP SP2 and SP3 systems. All but one of these PCs (XP SP2) is able to successfully decipher the DOS 8.3 path (ie C:\PROGRA~1\DATFOL~1\Config\) that is used in an .ini file related to this application. This particular PC errors out with a message: "Run-time error '76': Path not found".
The string is obtained from the .ini file using the
GetPrivateProfileString function. (The string is not hard-coded into the application - it is obtained from an ini file).
Since there is only one machine having the problem, I'm looking towards some configuration value on that device as being the root cause. I looked at the NtfsDisable8dot3NameCreation setting in the registry to see if this might cause the issue, but I have been unable to reproduce the problem on any other machine when changing this setting.
Anybody have any thoughts or perhaps another direction I could take?
Don't use hard-coded paths or short filenames. The Program Files folder might not be on the C: drive, might not be named Program Files, and even if it is, might not have a short filename of PROGRA~1 (and the same for DATAFOL~1). Write the install path to an INI file or the registry during installation and read+use that in your program.
If someone was gimping around and made a temp/backup/testing \DataFolder_Temp, deleted the original then renamed, the short path would be DATAFOL~2.
Delete the directory and recreate it.
check the PC. The PROGRA~1 or DATFOL~1 might actually be ~2 instead. Put the 8.3 name used in your code into explorer and see what IT tells you.