Add the moment my less and handlebar files get recompiled every time I check out another branch. Is there a way to run the watcher only when file was saved and not when it was changed in cause of checking out a branch.
Not possible at the moment, unless you disable all file watchers before such VCS operations and then re-enable them again (which is not convenient: any of these steps you can easily forget next time).
https://youtrack.jetbrains.com/issue/WEB-7912 -- watch this ticket (star/vote/comment) to get notified on progress.
Related
I'm having a hard time understanding how to properly install and uninstall custom actions, and what the purpose of rollback is. I have a custom action called CreateFSRegistryLink that creates a REG_LINK registry entry (which cannot be created by MSI/InstallShield directly AFAIK). I think I have this running properly for the most part because if the link is already there, it just returns ERROR_FUNCTION_NOT_CALLED, which MSI seems to handle gracefully, proceeding with the rest of the install. This ensures that multiple instances of the product can be installed cleanly (we have a multi-instance product).
The problem comes during un-install. CreateFSRegistryLink appears to be running again in non-rollback mode. From the MSI log I can see that it's running as it should during an install and but it also runs during an uninstall:
I'm checking the mode with:
if (!MsiGetMode(hInstall, MSIRUNMODE_ROLLBACK))
When the condition is true I log a message, "CreateFSRegistryLink is running in non-rollback mode." When it is false, I log a message, "CreateFSRegistryLink is running in rollback mode, so was skipped." I have never seen the second message show up in the log.
I have CreateFSRegistryLink set up with In-Script execution of "Deferred Execution in System Context." I also have another custom action DeleteFSRegistryLink set up with In-Script execution of "Rollback Execution in System Context". I see it getting skipped during an install, but not during an un-install (I suspect it's running normally during an un-install, but have not added logging to confirm this).
I also have a custom action CountOtherFSSystems that sets FS_SystemCount to the number of systems (instances) besides the current instance. I set DeleteFSRegisryLink to have a condition to only run when FS_SystemCount<1 in the Exec sequence. This is how I can tell that it is being skipped during an install because MSI reports that the condition wasn't met and so DeleteFSRegistryLink was skipped. I expect this to help ensure that it only runs when the last instance is being un-installed. I think this condition is working based on log output, but I don't know how to get this DeleteFSRegistryLink custom action to run properly during un-install without the CreateFSRegistryLink action re-installing the link. The last reference to DeleteFSRegistryLink I see in the log is:
MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=DeleteFSRegistryLink,ActionType=3329,Source=BinaryData,Target=DeleteFSRegistryLink,)
I haven't added logging to this function yet, so I don't know if it ran, but when the un-install is done, the link in the registry is still there. This is not entirely surprising because immediately after that I see that CreateFSRegistryLink ran again:
MSI (s) (08:CC) [09:42:23:708]: Executing op: ActionStart(Name=CreateFSRegistryLink,,)
Action 9:42:23: CreateFSRegistryLink.
MSI (s) (08:CC) [09:42:23:708]: Executing op: CustomActionSchedule(Action=CreateFSRegistryLink,ActionType=3073,Source=BinaryData,Target=CreateFSRegistryLink,)
MSI (s) (08:0C) [09:42:23:739]: Invoking remote custom action. DLL: C:\windows\Installer\MSI37E1.tmp, Entrypoint: CreateFSRegistryLink
MSI (s) (08:70) [09:42:23:739]: Generating random cookie.
MSI (s) (08:70) [09:42:23:739]: Created Custom Action Server with PID 7640 (0x1DD8).
MSI (s) (08:18) [09:42:23:786]: Running as a service.
MSI (s) (08:18) [09:42:23:786]: Hello, I'm your 32bit Elevated custom action server.
CreateFSRegistryLink is running in non-rollback mode.
I followed the rule at https://msdn.microsoft.com/en-us/library/aa371369(v=vs.85).aspx of "A rollback custom action must always precede the deferred custom action it rolls back in the action sequence" which is still really not making sense to me seeing this log output and results. I think I'm missing a few key points here.
This is on my 'required reading' list for MSI and a good place to start:
Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer
The idea is that every change made by MSI should be transactional. You should be able to rollback the state change on failure during an install, upgrade, repair or uninstall.
Occasionally you'll come across an API where this is not possible. An example would be deleting a user account or interacting with the old IIS metabase API. If the API doesn't support a .commit() .rollback() ability then you have to just make the change in the commit phase execution. Considering that commit phase can be disabled by disabling rollback you have to do it early in those scenarios.
Read the white paper a few times, digest it a bit and then follow up with any other questions that you still have.
Edit: This is how I ended up setting up my custom actions:
CountOtherFSSystems runs with Immediate Execution after InstallInitialize under all circumstances to set FS_SystemCount to the number of other instances that are installed.
RollbackFSRegistryLink runs with Rollback Execution in System Context after CountOtherFSSystems under the condition FS_SystemCount<1 And $FSRegistry = 3 (When the FSRegistry component was being installed local). It calls the function to delete the registry link.
CreateFSRegistryLink runs with Deferred Execution in System Context after RollbackFSRegistryLink under the condition $FSRegistry=3. It calls the function to create the registry link.
A bunch of other functions in the sequence execute, and then we get to the standard action WriteRegistryValues.
RollbackDeleteFSRegistryLink runs with Rollback Execution in System Context after WriteRegistryValues under the condition $FSRegistry<>3 (when the FSRegistry component was being removed, but the rollback needs to put it back). It calls the function to create the registry link.
DeleteFSRegistryLink runs with Deferred Execution in System Context after RollbackDeleteFSRegistryLink under the condition FS_SystemCount<1 AND $FSRegistry <> 3. It calls the function to delete the registry link.
TestError runs with Deferred Execution in System Context after DeleteFSRegistryLink. It calls a test function that just returns an error condition if the user says it's OK (via MSIProcessMessage) to introduce an error for test purposes here. (This function will be disabled for the production builds.)
I tested the following cases:
Error during installation of first instance - no registry entries or links are created.
Error during installation of second instance - only the first instance's registry entries remain, and the link remains also.
Error during uninstall of second instance - both instances and the link remain in the registry.
Error during un-install of last remaining instance - While the error is still displayed (before rollback occurs) I can see that the registry entries and link are all gone, and after proceeding, I see the rollback has restored the registry entries and the link.
Successful un-install of second instance - link and first instance's registry entries remain.
Successful un-install of last remaining instance - link and all registry entries are removed.
Please comment if you see anything I missed here. It seems pretty comprehensive to me.
To throw in my 2 cents: The issue seems to be related to custom action conditions. Regarding your call to MsiGetMode to see if it's a rollback, why bother? You sequence a rollback custom action before your actual deferred CA, and by definition it will be called only if the original custom action was called, and it's defined as a rollback CA and it needs no conditions. It may be that your uninstall CA can be the same as the rollback CA, but strictly speaking an uninstall CA can assume that its counterpart install CA worked correctly if it is coded correctly and failure causes the install to fail, whereas a rollback CA may need to assume that the install CA may have only partially worked and needs to check more system state.
If CreateRegistryFSLink is being called on uninstall then your condfition on that CA is incorrect.
If your code did or did not do something then it's up to you to remember what it did and the rollback CA undoes it.
The rest of it appears to be about the conditions on your custom actions. If you want one to be called only on uninstall of the product, then use REMOVE="ALL". If you have CAs related specifically to feature or component uninstall then (as Chris says) use a component or feature condition, they are here:
https://msdn.microsoft.com/en-us/library/aa368012(v=vs.85).aspx
If you want an uninstall CA to run as long as the product is not being upgraded, then REMOVE="ALL" and NOT UPGRADINGPRODUCTCODE will work.
So if you're still stuck, it may help to post your definitions of the CAs, in particular the conditions and types.
Is there any configuration which helps in log4cplus picking dynamic changes? I am changing log4cplus properties on runtime and want log4cplus to pick those changes dynamically.
There is the ConfigureAndWatchThread class which you can instantiate. It will spawn a thread which will watch for modification time changes on given configuration file. When it notices the modification time change into the future of the last recorded modification time, it will remove all the previously instantiated loggers and appenders, etc., and will reconfigure everything.
However, it is not very sophisticated and there is no defence against catching the configuration file change mid air while it is still being written by your editor. If this danger is not important for you, use it. Otherwise, I would suggest you build some sort of manual trigger into your software that will make it re-read the logging configuration only on the trigger.
I want to make an C++ application that will monitor file changes in its directory or its sub-directories. I know inotify can monitor single level directory changes and i need to manually add a watch for each sub-directory to detect changes in the sub-directory.
I need to know if there is any other way to recursively monitor changes in a directory in Linux other than inotify.
To monitor recursively a directory you have to:
Create an inotify(7) object with inotify_init(2) or inotify_init2(2).
Descend recursively on your directory, using inotify_add_watch(2) for all the nodes you want to be notified on (add the watch for the directory itself before scanning, or you'll lose events ---se below).
Wait for events to come on the inotify descriptor you have received.
Take into account that directory creation forces you to possible rescan of directory contents, as you can get an event for a new subdirectory on a watched directory, but files can be created on it before you had a chance to add watches for the recently created directory, so you will not be informed of that files creation.
For this last reason, you'll need to consider putting all things in a subroutine and to call it each time a new directory gets created. This way perhaps you'll scan files for which you'll receive creation events, but the other side you can lost events.
Also, you must prepare yourshelf to do a complete tree rescan in case you lose some events (in a full queue overflow).
And believe me, this is by far more efficient than to do it the classic way. And you can bypass short lived files between rescans.
The reason there's not a recursive solution to this problem has been pointed above in one comment (You'll need the kernel to do the search for you, even if you are not interested on it)
Yes there is the old classic way: Simply check the directory (recursively) in intervals. Store a list of all files and directories and their modification dates. Then it's easy to see if you have a new file/directory, if one has been removed, or if otherwise modified.
It is time consuming though, and you need to store data about every file and directory, so if you try to do it on the root directory you will use a lot of memory or storage.
Probably you want to mix inotify and dnotify to achieve that.
Alright so to start this is strictly for Windows and I'd prefer to use C++ over .NET but I'm not opposed to boost::filesystem although if it can be avoided in favor of straight Windows API I'd prefer that.
Now the scenario is an application on another machine I can't change is going to create files in a particular directory on the machine that I need to make backups of and do some extra processing. Currently I've made a little application which will sit and listen for change notifications in a target directory using FindFirstChangeNotification and FindNextChangeNotification windows APIs.
The problem is that while I can get notified when new files are created in the directory, modified, size changes, etc it only notifies once and does not specifically tell me which files. I've looked at ReadDirectoryChangesW as well but it's the same story there except that I can get slightly more specific information.
Now I can scan the directory and try to acquire locks or open the files to determine what specifically changed from the last notification and whether they are available for further use but in the case of copying a large file I've found this isn't good enough as the file won't be ready to be manipulated and I won't get any other notifications after the first so there is no way to tell when it's actually done copying unless after the first notification I continually try to acquire locks until it succeeds.
The only other thing I can think of that would be less hackish would be to have some kind of end token file but since I don't have control over the application creating the files in the first place I don't see how I'd go about doing that and it's still not ideal.
Any suggestions?
This is a fairly common problem and one that doesn't have an easy answer. Acquiring locks is one of the best options when you cannot change the thing at the remote end. Another I have seen is to watch the file at intervals until the size doesn't change for an interval or two.
Other strategies include writing a no-byte file as a trigger when the main file is complete and writing to a temp directory then moving the complete file to the real destination. But to be reliable, it must be the sender who controls this. As the receiver, you are constrained to watching the directory and waiting for the file to settle.
It looks like ReadDirectoryChangesW is going to be your best bet. For each file copy operation, you should be receiving FILE_ACTION_ADDED followed by a bunch of FILE_ACTION_MODIFIED notifications. On the last FILE_ACTION_MODIFIED notification, the file should no longer be locked by the copying process. So, if you try to acquire a lock after each FILE_ACTION_MODIFIED of the copy, it should fail until the copy completes. It's not a particularly elegant solution, but there doesn't seem to be any notifications available for when a file copy completes.
You can process the data once the file is closed, right? So the task is to track when the file is closed. This can be done using file system filter driver. You can write your own or you can use our CallbackFilter product.
Here is the problem: I monitor a directory using Win32 API ReadDirectoryChangesW function. And I need to distinguish between newly created files and modified files. But there are problems... as always :(
Cases:
I monitor directory for new/modify (FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE). Problem: After file creation, new file event + modify file event is triggered. But i need only one. How can I avoid that? When file is modified I get what I want :).
I monitor directory only for new file (FILE_NOTIFY_CHANGE_FILE_NAME) - NO PROBLEM.
I monitor directory only for modify file (FILE_NOTIFY_CHANGE_SIZE). Problem: When a new file is, modify action is fired along with file creation event. How can I avoid that?
Of course, I implemented some workarounds. But, I want to know if there any elegant way of handling the problems I described.
You should be catching FILE_NOTIFY_CHANGE_LAST_WRITE, not FILE_NOTIFY_CHANGE_SIZE, for a modified file. Files may be modified without the size changing.
You should also keep a queue of changes and the time they happened and only process the queue after there have been no changes in the past 1-2 seconds. Some applications can do very strange things when creating or modifying files, and you'll most likely want to special case for popular applications if you plan on using this code in the wild.
ReadDirectoryChanges isn't one of the friendliest winapi functions. You probably can't get around receiving two events on file creation; I'm not completely sure whether you'll get an extra modify for FILE_NOTIFY_CHANGE_LAST_WRITE on creation, but I think you probably will. Using the queue approach will allow you to easily throw out the extra event if it has the same time stamp as the creation event.