| 

.NET C# Java Javascript Exception

7
Ich habe hier folgende Funktion:

public void CleanGAC()
{
IAssemblyName an;
// get all GAC components
IAssemblyEnum ae = AssemblyCache.CreateGACEnum();
// [...]

while (AssemblyCache.GetNextAssembly(ae, out an) == 0)
{
// get name
string l_strName = AssemblyCache.GetName(an).ToUpper();

// [...]

try
{
// delete an assembly from the GAC
new System.EnterpriseServices.Internal.Publish().GacRemove(l_strName);
//[...]
}
catch (Exception ex)
{
throw new Exception(String.Format("CleanMain.CleanGAC: Error removing {0}. {1}", l_strName, ex.Message));
}
}
}


Bei jedem Löschversuch wird eine Variable hochgezählt, die mir dann am Schluss mitteilt, wieviele Dll's gelöscht worden sind. Es werden auch nicht irgendwelche Dll's gelöscht, sondern nur welche mit bestimmten Parametern.

Nur, funktioniert das Ganze nicht so wie es sollte. Es löscht keine Dll's. Ich habe mittlerweile herausgefunden, dass es wahrscheinlich daran liegt, dass die Funktion GacRemove nicht einfach einen Assembly-Namen braucht, sondern einen ganzen Pfad.

Wie bekomme ich nun den Pfad einer Dll aus dem GAC heraus, so dass ich sie löschen kann?
News:
02.01.2012
starki 603 1 8
3 Antworten
6
Es ist nicht möglich eine DLL direkt über das GAC-Verzeichnis zu löschen. Mit direkt mein ich dabei das du den Pfad aus dem GAC-Verzeichnis als Parameter für GacRemove verwendest.

Du musst die DLL aus dem GAC-Verzeichnis z.B. ins Temp-Verzeichnis kopieren und dann GacRemove mit dem Pfad der DLL aus dem Tempverzeichnis aufrufen.

Beispiel:

string original = "C:\WINDOWS\assembly\GAC_32\System.Data\2.0.0.0__b77a5c561934e089\System.Data.dll";
string target = "C:\temp\System.Data.dll"

//Kopie erstellen
File.Copy(original , target);

//Aus dem GAC entfernen
new System.EnterpriseServices.Internal.Publish().GacRemove(target);

//Kopie löschen
File.Delete(target);


Nachtrag

Selbstverständlich geht auch jede andere Kopie der DLL der selben Version.

Nachtrag 2

How to search a File recursively from subfolder using LINQ.

string gacDirectoryPath = 
Path.Combine(
System.Environment.GetFolderPath(Environment.SpecialFolder.Windows),
@"assembly\GAC"
);
DirectoryInfo gacDirectory = new DirectoryInfo(gacDirectoryPath);

IEnumerable<FileInfo> matches =
gacDirectory
//Alle dlls aus allen Unterverzeichnissen abrufen
.GetFiles("*.dll", SearchOption.AllDirectories)
//die gewünschte Datei suchen
.Where(c => c.Name == "adodb.dll")
;


Nachtrag 3

Nachdem die Frage aufkam, warum nur Assamblys gelistet werden, bei denen Any-CPU als Prozessorarchitektur ausgewählt ist und keine mit x86 or MSIL:
Das liegt daran das diese jeweils in eigenen Verzeichnissen im GAC verwaltet werden.

@"..\assembly\" //Basisverzeichnis mit diveresen Unterverzeichnissen wie temp, NativImage_..., etc.

@"..\assembly\GAC" //Any-CPU
@"..\assembly\GAC_32" //x86
@"..\assembly\GAC_MSIL" //MSIL
02.01.2012
Floyd 14,6k 3 9
Floyd 14,6k 3 9
Ja, aber wie bekomme ich nun den Pfad von original?
starki 02.01.2012
2
Siehe Nachtrag 2 ;)
Floyd 03.01.2012
2
Also noch bin ich nicht ganz zufrieden, auch wenn wir der Sache näher kommen. Ich habe jetzt folgende Funktion:

public void RemoveDllsFromGAC()
{
string gacDirectoryPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.System), @"..\assembly\GAC");

string[] files = Directory.GetFiles(gacDirectoryPath, "*.dll", SearchOption.AllDirectories);

foreach (var file in files)
{
FileInfo fi = new FileInfo(file);

if(...)
{
try
{
//[...]
}
catch (Exception ex)
{
// [...]
}
}
}
}


Die Funktion findet ein paar Dll's (126 um genau zu sein, aber dafür mit vollständigen Pfaden), jedoch keine einzige, die ich jedoch haben will. In der Variablen files[] sind längst nicht alle Dll's drin (allein im GAC gibt 491 Einträge).

Noch ein paar Informationen vorweg: Ich arbeite hier mit .NET 2.0, da gab es die Version Environment.SpecialFolder.Windows nicht, deswegen habe ich die obige Variante genommen.

Woran hapert es jetzt?
04.01.2012
starki 603 1 8
Das habe ich in meinem Test auch festgestellt. Die Frameworkeigenenen DLLs tauchen darin nicht auf. Die von mir registrieren DLLs jedoch schon. Warum die von dir registrieren nicht auftauchen kann ich mir aber auch nicht erklären.
Floyd 04.01.2012
Ich kanns glaub ich erklären. Ich hab mal die Einträge im GAC mit denen aus der Liste verglichen. Ich hab nicht alle durchsucht, sondern die ersten. Mir ist dabei aufgefallen, dass nur diejenigen DLL's angezeigt worden sind, bei denen im GAC in der Spalte Prozessorarchitektur nichts stand. Wenn aber dort steht MSIL oder x86 oder sonst was, dann wird die DLL nicht mit in die Liste aufgenommen.

Was kann man in so einem Fall machen?
starki 04.01.2012
2
Achso, dann musst du in den Verzeichnissen "GAC_32" oder "GAC_MSIL" suchen. Oder du lässt das Unterverzeichnis GAC ganz weg.

z.B.:
@"..\assembly\"
@"..\assembly\GAC_32"
@"..\assembly\GAC_MSIL"
Floyd 04.01.2012
Yuppie, es funktioniert :)
starki 04.01.2012
0
Ich weiß nicht, wie du den Pfad herausbekommst. Aber hilft dir das weiter?
02.01.2012
KN 1,7k 1 8
Wieso falsch, unpassend, störend oder spam?
LiRo 02.01.2012
Ka, aber in der Regel äußern sich die Leute dann auch nicht.
Floyd 02.01.2012
1
Ne, der Link hilft leider nicht. Er war einer der vielen die ich schon besucht hatte ...
starki 02.01.2012

Stelle deine Datei-Frage jetzt!