Apparently, there is a bug in the cache design of smb client after updating a binary on a UNC path by using the trick of moving the old binary and copying the new one.
--- HERE IS THE REPRODUCIBLE TEST CASE ---
First, you can compile two console c++ applications:
test-old.exe displays "Old binary" and wait for an input character:
// test-old.cpp
#include <iostream>
int main ()
{
std::cout << "Old binary" << std::endl;
getchar ();
return 0;
}
test-new.exe displays "New binary" and wait for an input character:
// test-new.cpp
#include <iostream>
int main ()
{
std::cout << "New binary" << std::endl;
getchar ();
return 0;
}
Then, you need to open a cmd.exe on two computers (like Windows 10 or Windows Server 2019):
1) From computer 1, create a share on a test directory:
net share test=<path>\test /GRANT:Everyone,FULL /CACHE:None
2) From computer 1, copy the old binary as test.exe:
copy /Y test-old.exe <path>\test\test.exe
3) From computer 2, run test.exe from the UNC share:
start \<computer 1>\test\test.exe
It displays "Old binary". Don't close the window.
4) From computer 1, move test.exe to test.exe.bak:
move /Y <path>\test\test.exe <path>\test\test.exe.bak
5) From computer 1, copy the new binary as test.exe:
copy /Y test-new.exe <path>\test\test.exe
6) From computer 2, run test.exe from the UNC share:
start \<computer 1>\test\test.exe
*It displays "Old binary". This is wrong as the binary has been updated. It should display "New binary". Notice, run again and again the command, it will display "Old binary" for ever as long as you don't close the first window. *
7) From computer 2, close all the windows of test.exe, wait 10 seconds and run again the command:
start \<computer 1>\test\test.exe
*It displays "New binary". *
There is a LanmanWorkstation registry parameter called CacheFileTimeout. In the documentation, it says: The default is 10 seconds. This setting controls the length of time (in seconds) that the redirector will hold on to cached data for a file after the last handle to the file is closed by an application.
https://learn.microsoft.com/en-us/windows-server/administration/performance-tuning/role/file-server/
After step 4), the handle that is still opened should be on \<computer 1>\test\test.exe.bak. At step 5), as there is no handle opened on \<computer 1>\test\test.exe, the execution should not find the file in the cache and should display: "New binary".
It would be good that UNC behavior works the same way as local behavior.
Here is the local behavior:
1) Copy the old binary as test.exe:
copy /Y test-old.exe test.exe
2) Run test.exe from the local directory:
start test.exe
It displays "Old binary". Don't close the window.
3) Move test.exe to test.exe.bak:
move /Y test.exe test.exe.bak
4) Copy the new binary as test.exe:
copy /Y test-new.exe test.exe
5) Run test.exe from the local directory:
start test.exe
It displays "New binary".
Could this smb client behavior be fixed?
The workaround is to close all the instances of test.exe. But, if you are working on a Windows Server with multiple user sessions, you cannot ask to all users to close the applications...
PS:
This question has been asked in microsoft community forum which redirects me here:
https://answers.microsoft.com/en-us/windows/forum/windows_10-networking/bug-in-client-smb-cache/af6f10d6-d92f-4fc4-b3ab-1a3b6df656e0