Visual Studio, Bir sürü proje ve referans hataları : Find Missing References

Son 1 haftadır ilginç bir deployment projesi ile uğraşıyorum. Olay bildiğiniz MSI hazırlamak ama bu işi içinde 100 küsür proje olan bir çözümde yaparsanız çok ilginç hatalar alabiliyorsunuz. En sinir bozucu ve bu yazının bu çözümün sebebi olan hata da 80004005 hatası. Komik bir şekilde bu hata eğer projelerinizden birinin içindeki bir referans hatalı ise (Sarı ünlem işaretli ise) çıkıyor. hani iki üç projeden oluşan çözümlerde (solution) bunu bulmak kolay oluyor da benim gibi 50 üzeri projede tek tek bakmanında imkanı yok.
İşin en vahim yanı ise, Sizin A, B ve C projeleriniz var diyelim. A ilk önce B den referans almış, Sonra gitmiş bir de C yi almış. Kod içerisinden B ile ilgili satırları kaldırmışsınız, B ile işiniz kalmamış, C ile yola devam ediyorsunuz. B yi doğal olarak diskten de silmişsiniz (en azından referans aldığınız dll dosyasını), ama References bölümünden kaldırmamışsınız. Sık olabilen bir durumdur bu, çok proje ile çalıştığınız zamanlar, emin olmadan eklediğimiz sonrada sildiğimiz yada hiç build edip ,çıktısını almadığımız projeler olur (Özellikle sıfırdan alıyorsanız projeyi çok daha fazla başınıza gelir bu tip detay hatalar). Bu proje Build olur, Hata vermez güzel de çalışır. Gel görki Deployment projesi böyle bir hatayı affetmez, yukarda yazdığım 80004005 hatasını pat diye verir size. Ayrıca yüzsüz bir şekilde projenin çözüm içinde olmasını bile isteyebilir bazen (her zaman değil onun tam mantığını bulamadım.)
Proje Build oluyor ama deployment olmuyor. İşte bu anda bir çok insan araştırmaya başlar internette..
İnternet dediğimiz arkadaşımızda çözüm için, hangi proje hatalı bulamıyorsanız, Deployment a tek tek ekleyin, her seferinde Deployment ı build alın, böylece hata çıkınca hangi projedenmiş görürsünüz diyor (Elle gezmekten farkı nedir bilemedim.)
Bende üşenmedim, araştırdım, VS Macro okudum, öğrendim. Bir şekilde hatalı olan referansları nasıl buluruz diye uğraştım ve çözümü buldum.
Aşağıdaki Macro aslen Path bilgisine göre kontrol yapmakta. İkinci olarka eğer referansı içerdeki projeden eklemişseniz, SourceProject bilgisinden de yapabilirsiniz kontrolü. Böylece o referansın projesinin çözüm içinde olup olmadığını kontrol edebilirsiniz.
İlginçtir hızlı çalışıyor, 100 küsür projelik çözümde ya hata yoktu (Elle düzeltmiştim) yada çalışmadı ama yaptığım diğer testlerde (4 farklı durum ve çözümde) her zaman sonuç verdi. Ben eklemeyi unuttum, hata çıkmayınca, herşey güzel diye bir mesaj yazdırmak isteyebilirsiniz.
Option Strict Off Option Explicit Off Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports System.Diagnostics Imports System.Windows.Forms Imports VSLangProj Public Module FindMissingReferences Sub FindMissingReferencesbyPath() Dim objProject As EnvDTE.Project Try If Not DTE.Solution.IsOpen Then MessageBox.Show("Please load or create a solution") Else CheckReferenceByPath(objProject) End If Catch End Try End Sub Sub FindMissingReferencesbySourceProject() Dim objProject As EnvDTE.Project Try If Not DTE.Solution.IsOpen Then MessageBox.Show("Please load or create a solution") Else CheckReferenceBySourceProject(objProject) End If Catch End Try End Sub Private Sub CheckReferenceByPath(ByVal objProject As Project) Dim ProjCount As Integer Dim myRef As VSLangProj.Reference Dim RefCount As Integer Dim InfoText As String InfoText = "Reference Error : " & ControlChars.CrLf For ProjCount = 1 To DTE.Solution.Projects.Count prjVSProject = DTE.Solution.Projects.Item(ProjCount).Object For RefCount = 1 To prjVSProject.References.Count myRef = prjVSProject.References.Item(RefCount) If (myRef.Path Is Nothing) Or (myRef.Path = "") Then InfoText &= "Project Name : " & DTE.Solution.Projects.Item(ProjCount).Name.ToString() & ControlChars.CrLf InfoText &= "Reference Name : " & myRef.Name.ToString() MessageBox.Show(InfoText, "Reference Error (by Path)", MessageBoxButtons.OK, MessageBoxIcon.Error) End If Next Next End Sub Private Sub CheckReferenceBySourceProject(ByVal objProject As Project) Dim ProjCount As Integer Dim myRef As VSLangProj.Reference Dim RefCount As Integer Dim InfoText As String InfoText = "Reference Error : " & ControlChars.CrLf For ProjCount = 1 To DTE.Solution.Projects.Count prjVSProject = DTE.Solution.Projects.Item(ProjCount).Object For RefCount = 1 To prjVSProject.References.Count myRef = prjVSProject.References.Item(RefCount) If CheckForProjectNames(myRef) Then InfoText &= "Project Name : " & DTE.Solution.Projects.Item(ProjCount).Name.ToString() & ControlChars.CrLf InfoText &= "Reference Name : " & myRef.Name.ToString() MessageBox.Show(InfoText, "Reference Error (by Path)", MessageBoxButtons.OK, MessageBoxIcon.Error) End If Next Next End Sub Function CheckForProjectNames(ByVal ref As Reference) As Boolean Dim sourceProject As EnvDTE.Project Dim ProjCount As Integer sourceProject = ref.SourceProject If Not sourceProject Is Nothing Then For ProjCount = 1 To DTE.Solution.Projects.Count If sourceProject.Name = DTE.Solution.Projects.Item(ProjCount).Name.ToString() Then Return True End If Next End If Return False End Function End Module
Dosyayı txt olarak ekliyorum, herhangi bir ulaşım sorunu yaşamayın diye..
Bir Visual Studio macerasının sonuna geldiğimizde, dileklerimiz VS 2010 da bu işlerin daha iyi olmasından yanadır. (Beta yı çektim de hiç denemedim aslen)
[...] referansları bulmak.. Az uğraştırmadı beni bu deployment projeleri.. http://bit.ly/5ZcGpx , http://bit.ly/5yiwh2Hint Usulü Matrix Görünümlü TerminatörServing Guinness – [...]