Jak usunąć informację, że plik został pobrany z Internetu?

przez | 2024-12-23

Jeśli pobieramy pliki z Internetu, to przeglądarka Internetowa zapisuje dodatkowy atrybut, że plik został pobrany z Internetu (dodatkowo gdy rozpakowujemy archiwum pobrane z Internetu to niektóre archiwizatory np. WinRAR, TotalCommander wszystkie rozpakowane pliki oznaczają jako pobrane z Internetu; aczkolwiek 7-zip nie dodaje tego atrybutu do rozpakowywanych plików). Mało tego takie oznaczenie stosuje też program Outlook gdy zapisujemy załącznik na dysku. Tutaj taka ciekawostka: ten atrybut jest zapisywany tylko na dyskach sformatowanych NTFS. Jeśli zapisujesz plik na nośniku sformatowanym w systemie FAT, FAT32, exFAT (np. pendrive są formatowane w tym systemie plików)

Czym to się objawia? Otóż jeśli pobieramy plik np. szablon.docx z Internetu to dodatkowo jest tworzony ADS (Alternate Data Streams) w pewnym uproszczeniu można powiedzieć że to jest to taki jakby dodatkowy mały plik o nazwie szablon.docx:Zone.Identifier. Normalnie go nie widać, eksplorator plików go nie widzi. Również jeśli w wierszu poleceń wpiszemy komendę dir to nie zostanie on wyświetlony.

Ale jeśli wpiszemy dir /r to taki „plik” zostanie wyświetlony

Dodatkowo wpisując polecenie more < szablon.docx:Zone.Identifier możemy zobaczyć jego zawartość (ponieważ plik o nazwie szablon.docx:Zone.Identifier tak naprawdę nie jest fizycznie plikiem a dodatkowym strumieniem danych zapisanym na dysku to wiele DOSowych poleceń np. type, copy nie radzi sobie z obsługą takich „plików”).

Pewnie wielokrotnie się spotkałeś z tym, że takie pliki pobrane z Internetu należało odblokować (bo np. w nowszych wersjach pakietu Office domyślnie była wyłączana obsługa makr dla plików pobranych z Internetu, z kolei zwykłe pliki docx otwierają się w widoku chronionym).

Sam pewnego razu padłem ofiarą tego rozwiązania. Otóż napisałem dla klienta proste makro generujące listę obecności. To makro pobierało dane z bazy danych (plik accdb) następnie otwierało plik szablon.docx i w odpowiednim miejscu w szablonie dodawało w tabeli kolejne wiersze z nazwiskami uczestników szkolenia.

Wszystko było fajnie do czasu aż nie wysłałem na maila poprawionego szablonu listy obecności. Klient zapisał załącznik (a wraz z nim zapisał się ten strumień danych informujących, że plik pochodzi z Internetu).

Podczas odpalenia mojego makra wyskoczył błąd: Application-defined or object-defined error.

Jak pozbyć się widoku chronionego? Otóż najprościej jest jeszcze przed otworzeniem pliku) sprawdzić czy istnieje ten alternatywny strumień danych (czyli „plik” o takiej samej nazwie jak nasz główny plik ale z doklejoną w nazwie końcówką :Zone.Identifier i go usunąć).

Oczywiście standardowa w VBA instrukcja Kill nie radzi sobie z takimi „plikami”. Również obiekt FSO nie potrafi ich usunąć (ale potrafi sprawdzić czy istnieje plik o takiej nazwie). Tutaj musiałem skorzystać z Windowsowej funkcji API DeleteFile, która potrafi usuwać takie „pliki”.

Poniżej przedstawiam listing przykładowego makra (mocno uproszczone, bo chcę przedstawić koncepcję mojego rozwiązania a nie profesjonalne makro do generowania list obecności), które otwiera szablon z listą obecności i w miejscu gdzie jest „znacznik” [Imie_nazwisko] wstawia tekst  Jan Kowalski.

Uruchom procedurę TestListyObecnosci pamiętając aby podmienić odpowiednio ścieżkę do otwieranego pliku.

Option Explicit

#If VBA7 Then
Public Declare PtrSafe Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
#Else
public Declare  Function DeleteFile Lib "kernel32" Alias "DeleteFileA" (ByVal lpFileName As String) As Long
#End If

Public Function FileExists(fname) As Boolean
    Dim FSO As Object
    Set FSO = CreateObject("Scripting.FileSystemObject")
    FileExists = FSO.FileExists(fname)
End Function


Sub GenerujListeObecnosci(Plik As String)
    Dim appWord As Object
    Dim docWord As Object
    Dim a As Long
    Dim tbl As Object
    Dim newRow As Object
    Dim Licznik As Long
    
    On Error GoTo Err
    
    If FileExists(Plik + ":Zone.Identifier") Then
        DeleteFile (Plik + ":Zone.Identifier")
        MsgBox "Usunąłem atrybut wymuszający otwieranie pliku w widoku chronionym", vbInformation
    End If

    Set appWord = CreateObject("Word.Application")
    Set docWord = appWord.Documents.Add(Plik)

    'Bardzo uproszczona funkcja wstawiania
    With docWord.Content.Find
        .Text = "[Imie_nazwisko]"
        .Replacement.Text = "Jan Kowlaski"
        .Execute Replace:=2
    End With
    
    appWord.Visible = True
    appWord.Activate


    Set docWord = Nothing
    Set appWord = Nothing
    
    MsgBox "Wygenerowałem listę obecności", vbInformation
Err2:
    Exit Sub
Err:
    MsgBox Err.Description, vbExclamation, "GenerujListeObecnosci"
    Resume Err2
End Sub


Sub TestListyObecnosci()
    'Tu wstaw odpowiednią ścieżkę do pliku
    GenerujListeObecnosci ("v:\szablony\szablon.docx")
End Sub

W skrócie w procedurze GenerujListeObecnosci sprawdzamy czy istnieje zapisany alternatywny strumień danych (czyli „plik” z końcówką :Zone.Identifier) i jeśli istnieje to go kasujemy a dopiero później otwieramy szablon i na jego bazie generujemy listę obecności.

2 komentarze do „Jak usunąć informację, że plik został pobrany z Internetu?

  1. LS

    Ciekawy artykuł. Mam dwa pytania:

    I. Jak sprawdzić ile takich ukrytych 'plików’ mam na dysku?

    II. Czy da się te wszystkie 'pliki’ hurtowo usunąć?

    Odpowiedz

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.