Jak skopiować plik, który jest używany?

0

Witajcie,

Wrzucam w delphi bo co prawda wywołuję WinAPI ale jednak z delphi.

Słuchajcie mam dość trywialny problem ale jednak nie mam pomysłu na jego obejście. Potrzebuję z lokalizacji sieciowej A przekopiować plik (BPL) do lokalizacji B. Obie lokalizacje są udostępnione, obie są w jednej sieci LAN i wszystko działa bez problemu DOPÓKI ktoś fizycznie nie używa aplikacji. Lokalizacja A to miejsce gdzie automaty (w tym przypadku jenkins) generują nowe wersje plików BPL. Lokalizacja B to udział sieciowy, z którego użytkownicy uruchamiają aplikację i z niej korzystają. Nie ja to wymyśliłem ale tak już jest i muszę z tym żyć. Teraz w momencie gdy jenkins zbuilduje nowe wersje bpl chciałbym je podmienić na lokalizacji B. Niestety gdy ktoś nie zamknie aplikacji u siebie to mam komunikat, że plik zajęty. W 99% przypadków udaje mi się zmienić w lokalizacji B nazwę tego bpl na nazwa_data.bpl i wtedy z A kopiuję bezpośrednio na B nowy nazwa.bpl.

Niestety istnieje ten 1% przypadków gdy taka operacja nie jest możliwa bo np na tym pliku coś robi administrator z wyższymi uprawnieniami AD i zwykły użytkownik JENKINS nie jest w stanie nawet tej nazwy zmienić. Tu pytanie do was jak byście rozwiązali ten problem? Myślałem aby wykonywać kopiowanie w pętli w oczekiwaniu na "zwolnienie" pliku ale w dniu wczorajszym okazało się, że plik trzyma konto admina, który od tygodnia jest na urlopie więc ... odpada.

Gdzieś czytałem (choć teraz nie mogę znaleźć), że jest jakieś api w windows, które pozwala ustawić czas po jakim kopiowanie ma zostać przerwane (właśnie na takie sytuacje) ale nie mogę teraz tego znaleźć

3

Trochę dziwna sytuacja. Czy ty na pewno jedynie chcesz ten plik skopiować? Bo z tego co kojarzę to jak plik jest otwarty to nie da się go modyfikować, ale odczyt powinien być dopuszczony :/

1

jest takie oprogramowanie do backupu danych pisane w delphi Cobian Backup. Co prawda ta wersja jest nierozwijana i autor zaczął pisać to samo już w VS ale stary program działa raczej idealnie (używam na dużej ilości komputerów od lat).

Oprogramowanie to ma taką funkcję jak kopia otwartych plików (używam właśnie tego do baz danych access które są prawie cały czas otwarte).

Oczywiście zdaję sobie sprawę że dane po skopiowaniu mogą być niespójne ale w większości przypadków tak nie jest, pliki są tylko otwarte.
Jako ciekawostkę dodam że takie podejście kiedyś uratowało dupę klientowi gdy zapuścił sobie program szyfrujący dane. Bazy nie ruszył bo była blokada.

Anyway, program w czasie instalacji instaluje usługę która nazywa się Volume Shadow Copy. To coś całkowicie rozwiązuje sprawę kopiowania danych używanych przez innych.

W twoim przypadku jest coś całkowicie niezrozumiałego. Możesz zmienić nazwę używanego pliku a nie możesz go skopiować? I to przez sieć? Ja tego nie rozumiem.

Ale wracając do sedna.
Zainstaluj coś w stylu Cobian Backup (lub nawet dokładnie to) na komputerze na którym są tworzone pliki, Utwórz zadanie i uruchamiaj co określony czas. W zadaniu tym rób kopie interesujących cię plików w inne miejsce z którego bez problemu je sobie pobierzesz.

4

Ale to nie chodzi o to, że nie da się odczytać ale o to, że nie da się PODMIENIĆ otwartego pliku, co jest zrozumiałe i tego nie przeskoczysz. Jedynie próbowanie do skutku albo wyświetlanie userom jakiegoś info z prośbą o restart aplikacji, żeby zwolnić plik.

1

@abrakadaber:

Dodajmy: pliku wykonywalnego

4

Nie pliku wykonywalnego, a każdego pliku, bo każdy plik można otworzyć i trzymać otwarty na wyłączność procesu — wtedy inny proces nie może otworzyć takiego pliku nawet do odczytu. Po to właśnie istnieje flaga fmShareExclusive, aby inne aplikacje się nie wtrącały.

I to też nie jest tak, że nie da się nic z tym zrobić — da się odpiąć plik od procesu, który go otworzył, ale to może mieć fatalne konsekwencje (co raczej nie powinno dziwić). Są programy, które to potrafią, np. dawniej (pod WinXP) używałem do tego programu Unlocker, natomiast jest sporo innych. Przy czym pod Win10 zdarzyło mi się, że takie uwolnienie pliku skończyło się BSoD-em, więc trzeba uważać na to co się robi i za bardzo nie kombinować.

0

Tak najprościej rzecz ujmując chce wgrać na serwer nowe wersje ale nie mogę np odłączyć udziału sieciowego aby rozlaczyc userow i musze czekać aż zwolnią plik i szukam alternatywy

1

Ja bym to ugryzł od drugiej strony - zmienić aplikację tak żeby kopiowała się lokalnie lub do pamięci i stamtąd uruchamiała. Wtedy plik będzie zajęty tylko przez krótką chwilę. W dotnecie wystarczy włączyć "shadow copy"
https://learn.microsoft.com/en-us/dotnet/framework/app-domains/shadow-copy-assemblies ale możesz to sobie zaimplementować samemu

1

Nie jestem architektem, ale tak teoretyzując, to chyba można byłoby wszystko przez coś pośredniego puszczać - coś typu cache, żeby użytkownicy nie korzystali bezpośrednio, tylko pośrednio.
Inny sposób - dwie kopie i przełączany ruch. Jak chcesz sobie powiedzmy o 21:00 coś wrzucać nowego, to od 20tej przerzucasz cały ruch na kopię, a potem z powrotem.

1

znaczy chcesz użytkownikom wrzucić nową wersję aplikacji bez powiadomienia ich i nawet administratora?

0
Miang napisał(a):

znaczy chcesz użytkownikom wrzucić nową wersję aplikacji bez powiadomienia ich i nawet administratora?

Jak raz padła zła decyzja archikatedralna oraz organizacyjna, zwyczaj to zabetonował, to już tylko konserwacja prowizorki, słupek do deseczki, klin do słupka, a klin poprawiac jak sie chyli.

2
ZrobieDobrze napisał(a):
Miang napisał(a):

znaczy chcesz użytkownikom wrzucić nową wersję aplikacji bez powiadomienia ich i nawet administratora?

Jak raz padła zła decyzja archikatedralna oraz organizacyjna, zwyczaj to zabetonował, to już tylko konserwacja prowizorki, słupek do deseczki, klin do słupka, a klin poprawiac jak sie chyli.

No bez przesady. Wiele aplikacji działa tak że jest tylko jeden serwer, pisze się do użytkowników "Nie będzie działać przez godzinę" i się robi podmiankę. A potem się pisze "już działa". Widziałem takie zachowanie nawet w wielkiej unijnej ważnej istytucji. Niby były tam serwery zapasowe, ale przełączenie się na nie też trwało czas

BTW jak już oftopuje to:

  1. @woolfik chyba źle nazwałeś wątek, bo bardziej powinno być Jak podmienić plik, który jest używany? z tego co rozczytano powyżej
  2. Jesli dobrze rozumiem to jest to problem windowsa, bo na linuksie z tego co pamiętam, można kasować używane przez innych pliki i nie ma pojęcia "blokowania pliku". Na macu pewnie podobnie jak to Unix
0
KamilAdam napisał(a):
ZrobieDobrze napisał(a):
Miang napisał(a):

znaczy chcesz użytkownikom wrzucić nową wersję aplikacji bez powiadomienia ich i nawet administratora?

Jak raz padła zła decyzja archikatedralna oraz organizacyjna, zwyczaj to zabetonował, to już tylko konserwacja prowizorki, słupek do deseczki, klin do słupka, a klin poprawiac jak sie chyli.

No bez przesady. Wiele aplikacji działa tak że jest tylko jeden serwer, pisze się do użytkowników "Nie będzie działać przez godzinę" i się robi podmiankę. A potem się pisze "już działa". Widziałem takie zachowanie nawet w wielkiej unijnej ważnej istytucji. Niby były tam serwery zapasowe, ale przełączenie się na nie też trwało czas

BTW jak już oftopuje to:

  1. @woolfik chyba źle nazwałeś wątek, bo bardziej powinno być Jak podmienić plik, który jest używany? z tego co rozczytano powyżej
  2. Jesli dobrze rozumiem to jest to problem windowsa, bo na linuksie z tego co pamiętam, można kasować używane przez innych pliki i nie ma pojęcia "blokowania pliku". Na macu pewnie podobnie jak to Unix

Ogólnie na serwerze produkcyjnym zajmują się tym admini i oni mają odpowiednie narzędzia do wywalania użytkowników "na chama" i podmianę na właściwe BPL natomiast ja próbuję to zatomatyzować że jak nowa wersja BPL jest utworzona przez JEKNINSA na maszynie jekninsowej to się samo przekopiuje na serwer zespołu testerów / użytkowników biznesowych gdzie robią swoje testy i sprawdzenia. No i tu jest problem bo tak jak mówię użytkownik otworzy dany moduł i pójdzie do domu, a ja nie mam uprawnień do tego serwera aby tam np wykopać połączonego użytkownika i kończy się na manualnym procesie niestety.

1

To jest specyfika Windows i jego systemu plików i tego nie przeskoczysz. Na Linuksach np działa to już zupełnie inaczej:
https://unix.stackexchange.com/questions/223573/does-linux-have-file-locking-protection-when-trying-to-rename-deleting-files

Dlatego wymagane jest coś w stylu shadow copy w tle, pewnie to się podpina pod system plików i cały czas robi dodatkową kopię w locie wszytkich zapisywanych danych i to później z niej korzysta, a nie fizycznie z tego pliku, który chce skopiować

3

Śledzę ten wątek i mam nieodparte wrażenie próby rozwiązania problemu wygenerowanego przez nie odpowiednie praktyki. Uważam że to w pierwszej kolejności powinno zostać poprawione.

1 użytkowników online, w tym zalogowanych: 0, gości: 1