目录

1. 背景

2. 入手

2.1 分析sln文件

2.2 给出正则表达式

3 程序

4. demo

5. 补充 - 另外一种情况

6. 补充 - 完整代码


1. 背景

初次接手一个大工程时, 往往因为复杂的项目依赖而遇到各种编译问题, 同时如果能图形化其中的依赖关系对理解整个项目有莫大的帮助, 就像能从山顶俯瞰大陆的感觉. 本文即着重于实现此功能.

2. 入手

2.1 分析sln文件

下面给出了两个Project, 其中project1的GUID为E37ACEB3-9187-43F7-AA78-000000000001

project2的GUID为E37ACEB3-9187-43F7-AA78-000000000002,

postProject部分给出了依赖关系: project2依赖于project1

Project("{2150E333-AAAA-42A3-9474-1A3956D46DE9}") = "project1", "project1.vcxproj", "{E37ACEB3-9187-43F7-AA78-000000000001}"
EndProjectProject("{2150E333-AAAA-42A3-9474-1A3956D46DE9}") = "project2", "project2.vcxproj", "{E37ACEB3-9187-43F7-AA78-000000000002}"ProjectSection(ProjectDependencies) = postProject{E37ACEB3-9187-43F7-AA78-000000000001} = {E37ACEB3-9187-43F7-AA78-000000000001}EndProjectSection
EndProject

2.2 给出正则表达式

Python正则表达式解析project: r'Project[^=]+=\s*"([^"]+)"\s*,\s*"([^"]+)"\s*,\s*"\{([^"]+)\}"'

group(1)为project_name, group(2)为project_vcproj, group(3)为GUID

Python正则表达式解析postProject: r'\{([\w-]+)\}\s=\s\{([\w-]+)\}'

group(1)应该等于group(2), 都是依赖的项目的GUID.

3 程序

请见visual_Project_dependency-Python工具类资源-CSDN下载

4. demo

5. 补充 - 另外一种情况

还有一种依赖关系保存在project文件里,形式如下:

<ProjectReference Include="..\MsgCreator\MsgCreator.vcxproj"><Project>{d3eada85-50f9-4a1d-a2f7-18612358b436}</Project><ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>

表示当前工程依赖MsgCreator. vcxproj其实是个XML文件,直接用BeautifulSoup打开查找<Project>项即可。

6. 补充 - 完整代码

#!/usr/bin/python
# -*- coding: gb2312 -*-#########################################################################
#2022-09-24 support case 2: denpendency in vcxproj.
#2018-08-01 born
########################################################################import sys,refrom bs4 import BeautifulSoup
import os
#import os for opening project file to search below kind of dependencies(case 2).
#<ProjectReference Include="..\MsgCreator\MsgCreator.vcxproj">
#      <Project>{d3eada85-50f9-4a1d-a2f7-18612358b436}</Project>
#      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
#</ProjectReference>projectsCommentMap = {'project1':'comment1','project2': r'comment2: <BR/>aaa'
}class Project:def __init__(self, projectStr, slnpath):self.comments = ''projectNameGUIDpattern = r'Project[^=]+=\s*"([^"]+)"\s*,\s*"([^"]+)"\s*,\s*"\{([^"]+)\}"'m = re.search(projectNameGUIDpattern,projectStr)self.name = m.group(1)self.GUID = m.group(3).upper()self._fullpath = os.path.join(slnpath,m.group(2))#case 1: dependency specified in solution file.projectDependenciesPattern = r'\{([\w-]+)\}\s=\s\{([\w-]+)\}'m = re.findall(projectDependenciesPattern,projectStr)self.dependencyList = []for match in m:if(match[0]==match[1]):upperDep = match[0].upper()self.dependencyList.append(upperDep)#case 2: denpendency specified in specific project file.# <ProjectReference Include="..\MsgCreator\MsgCreator.vcxproj">#      <Project>{d3eada85-50f9-4a1d-a2f7-18612358b436}</Project>#      <ReferenceOutputAssembly>false</ReferenceOutputAssembly># </ProjectReference>with open(self._fullpath, "r") as file:contents = file.read()projxml = BeautifulSoup(contents, "xml")find_depen = projxml.find_all('Project')for dep in find_depen:if dep.parent and dep.parent.name=='ProjectReference':parentProjGUID = dep.text.strip('{}')self.dependencyList.append(parentProjGUID.upper())self.dependencyProjects = []def __hash__(self):return hash(self.GUID)def __eq__(self,other):if(self.name==other.name and  self.GUID==other.GUID):return Truereturn Falsenew_node_nocomment = '''%d [shape=none label=<<table border="0" cellspacing="0"><tr><td port="port1" border="1" color="red"><B>%s</B></td></tr></table>>]\n'''
new_node_withcomment = '''%d [shape=none label=<<table border="0" cellspacing="0"><tr><td port="port1" border="1" bgcolor="green"><B>%s</B></td></tr><tr><td port="port2" border="1">%s</td></tr></table>>]\n'''
if __name__ == '__main__':'''Usage: this_file 2010_sln_file'''slnFileName = sys.argv[1]#slnFileName = r'C:\cpp\xalan-c-Xalan-C_1_11_0\Projects\Win32\VC15\Xalan.sln'import osslnpath = os.path.dirname(slnFileName)slnFile = open(slnFileName,'r')slnStr = slnFile.read()print(len(slnStr))projectStartPos = 0projectEndPos = 0PROJECT_START_CONSTANT = 'Project("{'PROJECT_END_CONSTANT = 'EndProject'project_list = []while(1):projectStartPos = slnStr.find(PROJECT_START_CONSTANT,projectStartPos)if(projectStartPos<0):break;projectEndPos = slnStr.find(PROJECT_END_CONSTANT,projectStartPos)if(projectEndPos<0):print('NO EndProject closes the project')break;project_string = slnStr[projectStartPos:projectEndPos]project_list.append(Project(project_string, slnpath))projectStartPos = projectEndPosprint("Total# of projects: %d"%(len(project_list)))guid2ProjectMap = {}for project in project_list:guid2ProjectMap[project.GUID] = project#update dependencyProjectsfor project in project_list:for dependGuid in project.dependencyList:if dependGuid in guid2ProjectMap:project.dependencyProjects.append(guid2ProjectMap[dependGuid])else:print('project %s depend on a project not in solution:%s'%(project.name, dependGuid))#generate DOT filedot_file_name = 'temp.dot'dot = open(dot_file_name,'w+')dot.write("digraph Tree {\n")#dot.write('node [shape=record color=blue fontname="bold"] ;\n')#generate ID for projectproject2IDMap = {}refProjectList = set([])i = 0for project in project_list:project2IDMap[project]=ii+=1;for project in project_list:if(len(project.dependencyProjects)>0):refProjectList.add(project)for dependProject in project.dependencyProjects:refProjectList.add(dependProject)singlefile = open('single.txt','w+')for project in project_list:if(project in refProjectList):if(project.name in projectsCommentMap):projectcomments = projectsCommentMap[project.name]dot.write(new_node_withcomment%(project2IDMap[project], project.name,projectcomments))else:dot.write(new_node_nocomment%(project2IDMap[project], project.name))if(len(project.dependencyProjects)>0):for depend_project in project.dependencyProjects:dot.write("%d -> %d ;\n"%(project2IDMap[depend_project],project2IDMap[project]))else:singlefile.write(project.name)singlefile.write('\n')dot.write("}")dot.close()singlefile.close()

最后附一张开源库Xalan的项目依赖关系图:

图形化VS201x工程中的项目依赖关系相关推荐

  1. 如何在SQL Server中创建SQL依赖关系图

    Deleting or changing objects may affect other database objects like views or procedures that depends ...

  2. 图形化桌面环境中的shell脚本编程

    图形化桌面环境中的脚本编程 2.1 创建文本菜单 创建交互式 shell 脚本最常用的方法是使用菜单.提供各种选项可以帮助脚本用户了解脚本能做什么和不能做什么. 通常菜单脚本会清空显示区域,然后显示可 ...

  3. 项目依赖关系分析中的数据结构

    项目中常见问题 源码依赖可能导致相互直接或间接依赖形成环,对此应该如何快速检测呢? 源码依赖对于如commonLib大版本升级需要放开依赖该commonLib的其他aar源码验证,我们如何快速获取呢? ...

  4. 居然还有人不知道如何在 IDEA 中生成 Maven 依赖关系图?

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 每天 14:00 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java ...

  5. gradle 查看依赖类库版本_使用Gradle命令查看项目中库的依赖关系

    在Terminal中,可以通过 gradle 的命令查看项目中所使用库的版本,并且可以更加直观看到库之间的依赖关系.同时它们可以帮助您跟踪并解决与库版本冲突有关的任何问题.Building Andro ...

  6. 《Linux命令行与shell脚本编程大全》第十八章 图形化桌面环境中的脚本编程

    18.1 创建文本菜单 直接上例子吧:   1 #!/bin/bash   2 function menu   3 {   4         clear   5         echo   6   ...

  7. android两个项目依赖关系图,关于android:Android组件化项目搭建遇到的问题记录

    1. ARouter 的依赖问题 What went wrong: Execution failed for task ':app:kaptDebugKotlin'. A failure occurr ...

  8. Maven中父子项目依赖传递详解

    父子项目依赖传递实现方式 首先创建父项目 先创建一个项目example-trains-father. 添加父项目打包方式,直接在URL下面添加,即是<project></projec ...

  9. Android注解使用之Dagger2实现项目依赖关系解耦

    Dagger2 一句话:一款快速的注解框架,应用于Android.Java,由 Google 开发和维护,是 Square 的 Dagger 项目的分支. gitHub:https://github. ...

  10. 巧用 Lazy 解决.NET Core中的循环依赖关系

    原文作者: Thomas Levesque 原文链接:https://thomaslevesque.com/2020/03/18/lazily-resolving-services-to-fix-ci ...

最新文章

  1. 编码方式 / Base 64
  2. 使用Maven管理Eclipse Java项目
  3. Greenplum 添加或删除standby master节点
  4. 只工作不玩耍_不玩耍:独立游戏开发商的经验教训
  5. python process返回值_如何恢复传递给multiprocessing.Process的函数的返回值?
  6. Q137:PBRT-V3,各种采样(Sampling)之间的逻辑
  7. 命令行编译并运行JAVA
  8. fiddler过滤配置
  9. 物联网学习之旅:微信小程序控制STM32(二)--ESP8266连接mqtt服务端
  10. 《统计学》(贾俊平)考研初试完整学习笔记1~5章
  11. c语言中输出以e为底的指数,C语言中 ln(以自然对数e为底) lg(以十为底) 以及logab(以a为底,b为真数)的相关知识...
  12. JSP统计网站访问人数
  13. bilibil网站采集 返回视频下载地址【代码】
  14. lm曲线公式推导_宏观经济学 - LM曲线
  15. 关于一张出库单开具了多张发票的错误处理
  16. 网页鼠标点击特效案例收集(直播间红心同理)
  17. Linux 查看最耗费资源的几个进程
  18. 微信小程序--JavaScript实现指定数字的精度输出
  19. 绝对的开怀大笑-轻松一下
  20. ZYNQ学习笔记——高速ADDA实验

热门文章

  1. 《统计会犯错——如何避免数据分析中的统计陷阱》导读
  2. 微软私有云服务器,微软私有云
  3. Java软件开发基础入门之工作流
  4. [转]Ribbon界面介绍(1)
  5. 冰点还原无法修改计算机时间,系统还原后无法更改系统时间?这个方法必须会...
  6. 五子棋软件测试自学,初学者如何从零开始自学五子棋
  7. Kali Linux 暴力破解 Excel密码
  8. 思科、华为等四大厂商网络工程师面试题汇总+解析(第1期)
  9. adobe软件卸载不了怎么办?那就使用dobe官方清理工具吧!
  10. python外包凹多边形生成_用Opencv python裁剪图像中的凹多边形