caradh
Goto Top

Bitte um Ideen für ein Script zum Bereinigen von Verknüpfungen

Hintergrund:
In unserem Unternehmen wurden einige Fileserver umgezogen. Technisch gesehen, befinden sich nun alle Dateien auf einem anderen Server. Somit würden die Verknüpfungen die auf diese Dateien verweisen nicht mehr funktionieren. Da wir dies vermeiden wollen, haben wir das Problem vorläufig mit einer "Umleitung" behoben.

Diese Lösung soll aber nur für den Übergang sein. Deshalb habe ich ein Script geschrieben, welches alle Verknüpfungen in einem angegebenen Ordner und deren Unterordner bereinigen soll. Hierfür werden die zu ändernden Zielpfade und die neuen Pfade aus einer Textdatei ausgelesen. In der Textdatei sind alle Ordner der ersten Ebene enthalten. (Siehe Beispiel)

\\altserver1\Ordner1 \\neuserver\data\Alt1\Ordner1 
\\altserver1\Ordner2 \\neuserver\data\Alt1\Ordner2 
\\altserver1\Ordner3 \\neuserver\data\Alt1\Ordner3 
\\altserver2\Ordner1 \\neuserver\data\Alt2\Ordner1 
\\altserver2\Ordner6 \\neuserver\data\Alt2\Ordner6 
Dies soll nur ein Beispiel zur Veranschaulichung sein. Letztendlich soll der Zielpfad einer Verknüpfung angepasst werden, sofern dieser einen String der linken Spalte enthält. Wenn dem so ist, wird der Zielpfad der rechten Spalte verwendet.

Problem:
Das Script ist fertig gestellt und funktioniert.
Leider ist es nur so, dass in vielen Verknüpfungen (ca. 80%) der Laufwerksbuchstabe enthalten ist und nicht der vollständige Serverpfad.

Beispiel:
Statt \\altserver1\Ordner1\Mustermann\Doku.doc
S:\Mustermann\Doku.doc
Somit wird diese Verknüpfung in meinem Script nicht berücksichtigt.

Lösungsversuch:
Mit dem Notepad++ kann man die lnk-Datei auslesen. Dort steht der vollständige Serverpfad auch drin. (Siehe Anhang) Wenn ich die Möglichkeit hätte die lnk Dateien mit vbs auszulesen, wäre das Problem gelöst. Doch leider ist mir dies nicht möglich. Ich bekomme immer nur "L" zurück. (Siehe Quellcode)

86b6a63fbeb3cfee076f3a97201a8045

Private Sub readShortcutFile() 
Dim fso,f, line, strPath 
strPath = "C:\Test\Test.doc.lnk"   
Const ForReading = 1 

set fso = CreateObject ("Scripting.FileSystemObject")   
set f = fso.opentextfile(strPath,ForReading,true) 
do while not f.AtEndOfStream 
line = f.readLine() 
MsgBox line 
loop 
End Sub 


Für Ideen bin ich sehr dankbar.

Viele Grüße
Caradh

Content-Key: 132768

Url: https://administrator.de/contentid/132768

Printed on: April 24, 2024 at 14:04 o'clock

Member: dog
dog Jan 05, 2010 at 14:09:04 (UTC)
Goto Top
.lnk Dateien sind binäre Dateien und ein textbasierter Reader wie FileSystemObject wird deshalb immer beim ersten NUL-Zeichen abbrechen (NUL = Hier nach kommt nix mehr).

http://blogs.msdn.com/ericlippert/archive/2005/04/20/binary-files-and-t ...
http://www.motobit.com/tips/detpg_read-write-binary-files/

Grüße

Max
Member: manuel-r
manuel-r Jan 05, 2010 at 14:15:08 (UTC)
Goto Top
Warum heißen die neuen Server nicht einfach so wie die alten? Das spart jede Menge Gefrickel...
Member: bastla
bastla Jan 05, 2010, updated at Oct 18, 2012 at 16:40:47 (UTC)
Goto Top
Hallo Caradh und willkommen im Forum!

Das Auslesen von Verknüpfungen hatten wir mal hier (siehe Zeile 19) ...
Noch eine Anmerkung zu
Leider ist es nur so, dass in vielen Verknüpfungen (ca. 80%) der Laufwerksbuchstabe enthalten ist und nicht der vollständige Serverpfad.
Das "Leider" ist eigentlich nicht ganz nachvollziehbar - wenn die Freigabe auf einen Laufwerksbuchstaben gemapt wurde, muss ja nur diese Zuweisung angepasst werden und der Link funktioniert weiterhin ...

Grüße
bastla
Member: bakero3010
bakero3010 Jan 05, 2010 at 15:48:25 (UTC)
Goto Top
Hallo,
was machtn der wen du das nicht als textfile sondern als kA octetstream oder etwas ähnlichem einliest? Also dann Zeichenweise z.B ?
Member: mayho33
mayho33 Jan 05, 2010 at 15:54:41 (UTC)
Goto Top
Hallo!

Du könntest die Vollen Pfade z-B. so feststellen. Musst sie dann nur noch ersetzen.


Set oShell = WScript.CreateObject("WScript.Shell")
Set oFso = WScript.CreateObject("Scripting.FileSystemObject")

FullPath = ofso.getparentfoldername(wscript.scriptfullname)

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NetworkConnection",,48)
Set objNetwork = WScript.CreateObject("WScript.Network")

For Each item in colitems
LWName = LWName & item.localname & "|"
LWPath = lwpath & item.RemotePath & "|"
Next


arrLWPath = Split(lwpath, "|")
arrLWName = Split(lwname, "|")

MsgBox "Fertig"

Grüße

Mayho
Member: bastla
bastla Jan 05, 2010 at 16:05:44 (UTC)
Goto Top
@bakero3010
... als kA octetstream oder etwas ähnlichem ...
Wenn die im oben von mir verlinkten Beitrag dargestellte Vorgangsweise nach dem Schema
Set objShell= WScript.CreateObject("Wscript.Shell")  
Set objShortcut = objShell.CreateShortcut("C:\Test\Test.doc.lnk")  
WScript.Echo objShortcut.TargetPath
zu einfach ist ...

Grüße
bastla
Member: mayho33
mayho33 Jan 06, 2010 at 09:48:41 (UTC)
Goto Top
@ Bastla

Dein Script in dem Link ist super!!. Hab auch mal sowas kreiert, aber wesentlich umständlicher. Danke für die tolle Anregung!!!

Mayho
Member: Caradh
Caradh Jan 06, 2010 at 11:53:34 (UTC)
Goto Top
Hallo Max,

vielen Dank für die Hilfe. So gehts.

Viele Grüße
Caradh
Member: Caradh
Caradh Jan 06, 2010 at 12:20:58 (UTC)
Goto Top
Hallo bastla,

vielen Dank für die Willkommenheißung und Deine Vorschläge.

Das Auslesen von Verknüpfungen hatten wir mal hier (siehe Zeile 19) ...

Das Auslesen des Pfades stellt an sich kein Problem dar. Es ist nur so dass ich Pfade mit Laufwerksbuchstaben nicht mit meiner "Liste" matchen" kann. Dafür benötige den vollständigen Pfad. Dieser steht in der lnk-Datei. (Siehe Abbildung "Notepad").

Das "Leider" ist eigentlich nicht ganz nachvollziehbar - wenn die Freigabe auf einen Laufwerksbuchstaben gemapt wurde, muss ja nur diese Zuweisung angepasst werden und der Link funktioniert weiterhin ...

Auch das habe ich ausprobiert. Selbst wenn ich die Zuweisung anpasse, hat sich die Verknüpfung immer noch die alte Herkunft gemerkt. In diesem Fall würde das Betriebssystem automatisch ein neue Netzwerkverbindung anlegen und den Laufwerksbuchstaben im TargetPath entsprechend anpassen.

Viele Grüße
Caradh
Member: Caradh
Caradh Jan 06, 2010 at 12:26:12 (UTC)
Goto Top
Hallo Mayho,

vielen Dank für Deine Hilfe.

Das bringt mich schon mal ein gutes Stück näher. Allerdings ist die im lnk-Datei enthaltene Information bezüglich des Zielpfades nicht immer identisch mit den Netwerkfreigaben.

Selbst wenn ich die Zuweisung anpasse, hat sich die Verknüpfung immer noch die alte Herkunft gemerkt. In diesem Fall würde das Betriebssystem automatisch ein neue Netzwerkverbindung anlegen und den Laufwerksbuchstaben im TargetPath entsprechend anpassen.

Leider komme ich nicht drum rum die lnk-Datei auszulesen. Aber mittlerweile habe ich das zum Glück auch geschafft.

Viele Grüße
Member: bastla
bastla Jan 06, 2010 at 13:27:11 (UTC)
Goto Top
@mayho33
Dein Script in dem Link ist super!!.
Danke für die Blumen - allerdings würde ich das heute etwas anders schreiben (und zumindest die Methoden "GetBaseName" und "GetExtensionName" verwenden) ...

Grüße
bastla
Member: bastla
bastla Jan 06, 2010 at 13:58:03 (UTC)
Goto Top
Hallo Caradh!
Selbst wenn ich die Zuweisung anpasse, hat sich die Verknüpfung immer noch die alte Herkunft gemerkt. In diesem Fall würde das Betriebssystem automatisch ein neue Netzwerkverbindung anlegen und den Laufwerksbuchstaben im TargetPath entsprechend anpassen.
Kann ich nicht nachvollziehen - wenn die Verknüpfung auf "S:\Dein Doument.doc" zeigt und "S:" auf "\\altserver1\Ordner3" gemapt ist, funktioniert die Verknüpfung bei mir weiterhin, wenn zwischenzeitlich "S:" mit "\\neuserver\data\Alt1\Ordner3" (getestet natürlich mit anderen Rechnernamen / Pfaden) verbunden wird (obwohl in der Verknüpfung der ursprüngliche UNC-Pfad gespeichert ist) - oder verstehe ich Dich falsch?

Grüße
bastla
Member: Caradh
Caradh Jan 06, 2010 at 14:23:46 (UTC)
Goto Top
Hallo bastla,

mein Szenario sieht wie folgt aus:

Ausgangssituation:
- Ich habe eine Verknüpfung die auf "S:\Dein Doument.doc" zeigt.
- Mein Laufwerk S: ist mit "\\altserver1\Ordner3" verbunden.

Vorgehen:
- Ich trenne die Verbindung von "S:" und verbinde diese neu mit "S:" mit "\\neuserver\data\Alt1\Ordner3".
- Ich öffne die Verknüpfung (Doppelklick)

Ergebnis
- Es wird eine neue Netzlaufwerksverbindung " X" angelegt, die auf "\\altserver1\Ordner3" verweist.
- Der Targetpath der Verknüpfung verweist nun auf "X:\Dein Doument.doc"
- In der lnk-Datei steht nach wie vor noch "\\altserver1\Ordner3"

Meine Lösung
Bei Verknüpfungen die keinen volllständigen Zielpfad enthalten lese ich den vollständigen Pfad aus der lnk-Datei aus.
Diesen vergleiche ich mit meiner "Text Datei" und passe gegebenenfalls den Zielpfad des Verknüpfung an.

Viele Grüße
Caradh
Member: bastla
bastla Jan 06, 2010 at 14:35:11 (UTC)
Goto Top
Hallo Caradh!

Welches BS verwendest Du? Bei mir liegt die Verknüpfung auf einem XP Pro SP3 und es wird nach dem Neuverbinden des Laufwerkes auf die andere Freigabe zugegriffen - lediglich nach einem Umbenennen/Löschen der Datei am neuen Ort wird tatsächlich die Verknüpfung wieder auf den alten Speicherort "umgebogen" (und entsprechend in der .lnk-Datei auch gespeichert) ...

Grüße
bastla
Member: mayho33
mayho33 Jan 06, 2010 at 15:00:13 (UTC)
Goto Top
Hallo Caradh!

Super! Die Lösungen die man selbst findet sind die aus denen man lernt!

Kannst du uns trotzdem noch sagen wie du's gelöst hast?

Grüße!

Mayho
Member: Caradh
Caradh Jan 06, 2010 at 16:22:19 (UTC)
Goto Top
Hallo Mayho,

ich habe in den Urls die dog gepostet hat, meine Lösung gefunden.

Ich schreibe den Inhalt der lnk-Datei in einen String. Diesen vergleiche ich dann mit meiner Txt Datei, in der alle alten und neue Serverpfade drinstehen.

Der BeispielCode liest eine binärische Datei in einen String und schreibt diesen in eine neue Textdatei.

saveBinaryFileToString()

Private Sub saveBinaryFileToString()

    Dim byteArray

    byteArray = ReadByteArray("C:\Doku.doc.lnk")  
    SaveBinaryDataTextStream "String.txt", byteArray  

End Sub

Function ReadByteArray(strFileName)
    Const adTypeBinary = 1
    Dim bin
    Set bin = CreateObject("ADODB.Stream")  
    bin.Type = adTypeBinary
    bin.Open
    bin.LoadFromFile strFileName
    ReadByteArray = bin.Read
End Function

Sub SaveBinaryDataTextStream(FileName, ByteArray)
  'Create FileSystemObject object  
  Dim FS: Set FS = CreateObject("Scripting.FileSystemObject")  
  
  'Create text stream object  
  Dim TextStream
  Set TextStream = FS.CreateTextFile(FileName)
  
  'Convert binary data To text And write them To the file  
  TextStream.Write BinaryToString(ByteArray)
End Sub

Function BinaryToString(Binary)
  'Antonin Foller, http://www.motobit.com  
  'Optimized version of a simple BinaryToString algorithm.  
  
  Dim cl1, cl2, cl3, pl1, pl2, pl3
  Dim L
  cl1 = 1
  cl2 = 1
  cl3 = 1
  L = LenB(Binary)
  
  Do While cl1<=L
    pl3 = pl3 & Chr(AscB(MidB(Binary,cl1,1)))
    cl1 = cl1 + 1
    cl3 = cl3 + 1
    If cl3>300 Then
      pl2 = pl2 & pl3
      pl3 = ""  
      cl3 = 1
      cl2 = cl2 + 1
      If cl2>200 Then
        pl1 = pl1 & pl2
        pl2 = ""  
        cl2 = 1
      End If
    End If
  Loop
  BinaryToString = pl1 & pl2 & pl3
End Function

Viele Grüße
Caradh
Member: Caradh
Caradh Jan 06, 2010 at 16:26:57 (UTC)
Goto Top
Hi bastla,

ich habe auch Microsoft Windows XP Pro mit SP 3.

Viele Grüße
Caradh