├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── Workflow.yml ├── .gitignore ├── .nuke ├── build.cmd ├── build.ps1 ├── build.schema.json └── parameters.json ├── .run ├── Nuke Clean.run.xml ├── Nuke Plan.run.xml └── Nuke.run.xml ├── AddInManager.sln ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CadAddinManager ├── App.cs ├── CadAddinManager.csproj ├── Command │ ├── AddInManagerCommand.cs │ ├── AddinManagerBase.cs │ ├── DockPanelCommand.cs │ └── ICadCommand.cs ├── Model │ ├── Addin.cs │ ├── AddinItem.cs │ ├── AddinItemComparer.cs │ ├── AddinType.cs │ ├── Addins.cs │ ├── AssemLoader.cs │ ├── AssemblyLoadContext.cs │ ├── BitmapSourceConverter.cs │ ├── CadAddin.cs │ ├── CodeListener.cs │ ├── DefaultSetting.cs │ ├── FileUtils.cs │ ├── FolderTooBigDialog.cs │ ├── IAddinNode.cs │ ├── IEConverter.cs │ ├── IniFile.cs │ ├── LogMessageString.cs │ ├── ManifestFile.cs │ ├── ProcessManager.cs │ ├── StaticUtil.cs │ ├── ViewModelBase.cs │ └── VisibilityMode.cs ├── PackageContents.xml ├── Properties │ ├── Settings.Designer.cs │ ├── Settings.settings │ └── launchSettings.json ├── Resource.Designer.cs ├── Resource.resx ├── Resources │ ├── dev.ico │ ├── dev.png │ ├── dev16x16.png │ ├── dev32x32.png │ ├── folder.png │ ├── lab16x16.png │ └── lab32x32.png ├── View │ ├── AssemblyLoader.xaml │ ├── AssemblyLoader.xaml.cs │ ├── Control │ │ ├── ExtendedTreeView.cs │ │ ├── LogControl.xaml │ │ ├── LogControl.xaml.cs │ │ ├── MouseDoubleClick.cs │ │ ├── RelayCommand.cs │ │ └── VirtualToggleButton.cs │ ├── FrmAddInManager.xaml │ └── FrmAddInManager.xaml.cs ├── ViewModel │ ├── AddInManagerViewModel.cs │ ├── AddinManager.cs │ ├── AddinModel.cs │ ├── AddinsApplication.cs │ ├── AddinsCommand.cs │ └── LogControlViewModel.cs └── postbuild.ps1 ├── Installer ├── Installer.cs ├── Installer.csproj └── Resources │ └── Icons │ ├── BackgroundImage.png │ ├── BannerImage.png │ └── ShellIcon.ico ├── License.md ├── Readme.MD ├── Test ├── AddHatch.cs ├── AddRegion.cs ├── ArcTest.cs ├── BreakPolyLine.cs ├── CreateBlockTest.cs ├── CreateComplexLinetype.cs ├── CreateMtext.cs ├── CreatePoint.cs ├── CreateSpline.cs ├── CreateTableSample.cs ├── DebugTraceTest.cs ├── EtittyPickPointTest.cs ├── ExportBlockCoordinate.cs ├── ExportBlockReferenceAttrs.cs ├── ExtractFileFromResources.cs ├── ExtractLocation.cs ├── FileSample │ ├── changecolor.lsp │ ├── hello.lsp │ └── sample_base.dwg ├── FunctionLispTest.cs ├── GetLayers.cs ├── LayerTest.cs ├── LispCommandTest.cs ├── RevCloudTest.cs ├── Selection │ ├── FilterRelate.cs │ ├── MergeSelection.cs │ ├── MultiFilterRule.cs │ ├── PickSelection.cs │ ├── QuickSelectFilter.cs │ ├── SelectCross.cs │ ├── SelectionFilters.cs │ └── SelectionOnScreen.cs ├── SetOrginHatch.cs ├── Test.csproj ├── TestCircle.cs ├── TestLine.cs ├── TestViewPort.cs └── ZoomToObject.cs ├── TestVB ├── CreateLineTest.vb ├── GetEntities.vb ├── TestSample.vb └── TestVB.vbproj ├── build ├── .editorconfig ├── Build.Clean.cs ├── Build.Compile.cs ├── Build.GitHubRelease.cs ├── Build.Installer.cs ├── Build.Properties.cs ├── Build.cs ├── Build.csproj ├── Build.csproj.DotSettings └── BuilderExtensions.cs └── pic ├── Addin.png ├── AddinManager.gif ├── AddinManager.png ├── CadAddinManager.png ├── CadAddinManagerBackground.png ├── DockPanelOutput.png └── jetbrains.png /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Purpose 2 | 3 | (FILL ME IN) This section describes why this PR is here. Usually it would include a reference 4 | to the tracking task that it is part or all of the solution for. 5 | 6 | ### Description 7 | 8 | (FILL ME IN) Brief description of the fix / enhancement. **Mandatory section** 9 | 10 | ### Declarations 11 | 12 | Check these if you believe they are true 13 | 14 | - [ ] This PR fix bug 15 | - [ ] This PR for new feature 16 | - [ ] The codebase is in a better state after this PR 17 | - [ ] The level of testing this PR includes is appropriate 18 | - [ ] User facing strings, if any, are extracted into `*.resx` files 19 | - [ ] Snapshot of UI changes, if any. 20 | - [ ] This PR modifies some build requirements and the readme is updated 21 | 22 | ### Reviewers 23 | 24 | (FILL ME IN) Reviewer 1 (If possible, assign the Reviewer for the PR) 25 | 26 | (FILL ME IN, optional) Any additional notes to reviewers or testers. 27 | 28 | ### FYIs 29 | 30 | (FILL ME IN, Optional) Names of anyone else you wish to be notified of 31 | -------------------------------------------------------------------------------- /.github/workflows/Workflow.yml: -------------------------------------------------------------------------------- 1 | name: Workflow 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | branches: 9 | - '!master' 10 | 11 | jobs: 12 | windows: 13 | name: windows-2022 14 | runs-on: windows-2022 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@v1 18 | - name: Run Nuke Build 19 | run: ./.nuke/build.cmd --GitHubToken ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Ignore thumbnails created by Windows 2 | Thumbs.db 3 | 4 | #Ignore files built by Visual Studio 5 | *.obj 6 | *.exe 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.cache 20 | *.ilk 21 | *.log 22 | *.iref 23 | *.db 24 | *.ide 25 | *.opendb 26 | *.lock 27 | *.ide-shm 28 | *.ide-wal 29 | *.dll 30 | *.suo 31 | *.dwl 32 | *.dwl2 33 | [Bb]in 34 | [Dd]ebug*/ 35 | *.lib 36 | *.sbr 37 | obj/ 38 | [Rr]elease*/ 39 | _ReSharper*/ 40 | [Tt]est[Rr]esult* 41 | .vs/ 42 | 43 | #Rider 44 | .idea 45 | 46 | #Installer 47 | output 48 | 49 | #Nuget packages folder 50 | packages/ 51 | *.html 52 | *.htm 53 | build 54 | -------------------------------------------------------------------------------- /.nuke/build.cmd: -------------------------------------------------------------------------------- 1 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0Build.ps1" %* -------------------------------------------------------------------------------- /.nuke/build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] 4 | [string[]]$BuildArguments 5 | ) 6 | 7 | Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" 8 | 9 | Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } 10 | 11 | ########################################################################### 12 | # CONFIGURATION 13 | ########################################################################### 14 | 15 | $SolutionDirectory = Split-Path $PSScriptRoot -Parent 16 | $BuildProjectFile = "$SolutionDirectory\Build\Build.csproj" 17 | $TempDirectory = "$SolutionDirectory\.nuke\temp" 18 | 19 | $DotNetGlobalFile = "$SolutionDirectory\global.json" 20 | $DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" 21 | $DotNetChannel = "Current" 22 | 23 | $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 24 | $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 25 | $env:DOTNET_MULTILEVEL_LOOKUP = 0 26 | 27 | ########################################################################### 28 | # EXECUTION 29 | ########################################################################### 30 | 31 | function ExecSafe([scriptblock] $cmd) { 32 | & $cmd 33 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 34 | } 35 | 36 | # If dotnet CLI is installed globally and it matches requested version, use for execution 37 | if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` 38 | $(dotnet --version) -and $LASTEXITCODE -eq 0) { 39 | $env:DOTNET_EXE = (Get-Command "dotnet").Path 40 | } 41 | else { 42 | # Download install script 43 | $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" 44 | New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null 45 | [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 46 | (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) 47 | 48 | # If global.json exists, load expected version 49 | if (Test-Path $DotNetGlobalFile) { 50 | $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) 51 | if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { 52 | $DotNetVersion = $DotNetGlobal.sdk.version 53 | } 54 | } 55 | 56 | # Install by channel or version 57 | $DotNetDirectory = "$TempDirectory\dotnet-win" 58 | if (!(Test-Path variable:DotNetVersion)) { 59 | ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } 60 | } else { 61 | ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } 62 | } 63 | $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" 64 | } 65 | 66 | Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" 67 | 68 | ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet } 69 | ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments } -------------------------------------------------------------------------------- /.nuke/build.schema.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json-schema.org/draft-04/schema#", 3 | "title": "Build Schema", 4 | "$ref": "#/definitions/build", 5 | "definitions": { 6 | "build": { 7 | "type": "object", 8 | "properties": { 9 | "Continue": { 10 | "type": "boolean", 11 | "description": "Indicates to continue a previously failed build attempt" 12 | }, 13 | "GitHubToken": { 14 | "type": "string" 15 | }, 16 | "Help": { 17 | "type": "boolean", 18 | "description": "Shows the help text for this build assembly" 19 | }, 20 | "Host": { 21 | "type": "string", 22 | "description": "Host for execution. Default is 'automatic'", 23 | "enum": [ 24 | "AppVeyor", 25 | "AzurePipelines", 26 | "Bamboo", 27 | "Bitrise", 28 | "GitHubActions", 29 | "GitLab", 30 | "Jenkins", 31 | "Rider", 32 | "SpaceAutomation", 33 | "TeamCity", 34 | "Terminal", 35 | "TravisCI", 36 | "VisualStudio", 37 | "VSCode" 38 | ] 39 | }, 40 | "NoLogo": { 41 | "type": "boolean", 42 | "description": "Disables displaying the NUKE logo" 43 | }, 44 | "Partition": { 45 | "type": "string", 46 | "description": "Partition to use on CI" 47 | }, 48 | "Plan": { 49 | "type": "boolean", 50 | "description": "Shows the execution plan (HTML)" 51 | }, 52 | "Profile": { 53 | "type": "array", 54 | "description": "Defines the profiles to load", 55 | "items": { 56 | "type": "string" 57 | } 58 | }, 59 | "Root": { 60 | "type": "string", 61 | "description": "Root directory during build execution" 62 | }, 63 | "Skip": { 64 | "type": "array", 65 | "description": "List of targets to be skipped. Empty list skips all dependencies", 66 | "items": { 67 | "type": "string", 68 | "enum": [ 69 | "Cleaning", 70 | "Compile", 71 | "CreateInstaller", 72 | "PublishGitHubRelease" 73 | ] 74 | } 75 | }, 76 | "Solution": { 77 | "type": "string", 78 | "description": "Path to a solution file that is automatically loaded" 79 | }, 80 | "Target": { 81 | "type": "array", 82 | "description": "List of targets to be invoked. Default is '{default_target}'", 83 | "items": { 84 | "type": "string", 85 | "enum": [ 86 | "Cleaning", 87 | "Compile", 88 | "CreateInstaller", 89 | "PublishGitHubRelease" 90 | ] 91 | } 92 | }, 93 | "Verbosity": { 94 | "type": "string", 95 | "description": "Logging verbosity during build execution. Default is 'Normal'", 96 | "enum": [ 97 | "Minimal", 98 | "Normal", 99 | "Quiet", 100 | "Verbose" 101 | ] 102 | } 103 | } 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /.nuke/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./build.schema.json", 3 | "Solution": "AddInManager.sln", 4 | "Verbosity": "Normal" 5 | } -------------------------------------------------------------------------------- /.run/Nuke Clean.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 25 | -------------------------------------------------------------------------------- /.run/Nuke Plan.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 22 | -------------------------------------------------------------------------------- /.run/Nuke.run.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 22 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | - 2025-05-18 **2.0.5** 3 | - Fixed command attribute flag with 4 type arguments 4 | - 2025-03-05 **2.0.4** 5 | - Fix issue assembly code loaded raised e duplicate message in AutoCAD 2025 6 | - 2025-03-04 **2.0.3** 7 | - Fix issue can't load dependencies into AutoCAD 2025 8 | - Allow use load assembly context and unload assembly A25 9 | - 2023-04-28 **2.0.2** 10 | - Add support Autocad 2025 11 | - Add support Civil3D 2025 12 | - 2023-05-24 **2.0.0** 13 | - Fixed conflict load assembly version 2022. 14 | - Separate load assembly for each version. 15 | - 2023-05-24 **2.0.0** 16 | - Add support Version 2024 17 | - Improvement user interface 18 | - 2023-03-29 **1.0.9** 19 | - Fixed issue load add-in out range exception parameter name [#2](https://github.com/chuongmep/CadAddinManager/issues/2) 20 | - Fixed issue load add-in use CAD MEP [#6](https://github.com/chuongmep/CadAddinManager/issues/6). 21 | - Fixed issue load Ribbon load with civil3d 2023. 22 | - 2022-12-21 **1.0.8** 23 | - Fix issue load relative path with window parallel macOS. 24 | - 2022-06-02 **1.0.7** 25 | - Support event ArrowKeyDown and ArrowKeyUp to move between items search and TreeView 26 | - Support press key Esc from keyboard to close Form. 27 | - 2022-05-29 **1.0.6** 28 | - Add tab lisp function and support reload update lisp function 29 | - 2022-05-22 **1.0.5** 30 | - Fix name string define attribute larger 64 character show eInvalidInput. 31 | - Add some example learning curve. 32 | - 2022-05-20 **1.0.4** 33 | - fix bug eDuplicateKey below commandline when load or execute assembly [#1](https://github.com/chuongmep/CadAddinManager/issues/1). 34 | - 2022-05-16 **1.0.3** 35 | - Support Copy Content Debug/Trace Output to Clipboard. 36 | - 2022-05-13 **1.0.2** 37 | - Add tab support show result trace/debug 38 | - Add DockPanel Support Show/Hide Debug/Trace result. 39 | - Support use Trace.Write() output in CadAddinManager and DockPanel **Debug/Trace Output** 40 | - Support use Trace.WriteLine() output in CadAddinManager and DockPanel **Debug/Trace Output** 41 | - Support use Debug.WriteLine() output in CadAddinManager and DockPanel **Debug/Trace Output** 42 | - Support use Debug.WriteLine() output in CadAddinManager and DockPanel **Debug/Trace Output** 43 | - Support show difference color type : Add,Modify,Warning,Error,Delete. 44 | - 2022-04-28 **1.0.1** 45 | - Fix small bug when execute command string reflect. 46 | - Add some test cases. 47 | - 2022-04-27 **1.0.0** 48 | - First Release. 49 | - Support CAD & Civil3D Version : 2020,2021,2022,2023 50 | 51 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | chuongpqvn@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | #### Contributions are more than welcome! Please work in the dev branch to do so: 4 | 5 | - Create or update your own fork of AddinManager under your GitHub account. 6 | - Checkout to the ``dev`` branch. 7 | - In the dev branch, implement and test you changes specific to the feature. 8 | - Build the project and make sure everything works. 9 | - Create well-documented commits of your changes. 10 | - Submit a pull request to the origin:dev branch. 11 | 12 | 13 | #### Build 14 | 15 | Debugging: 16 | 17 | - Run **Debug Profile** in Visual Studio or **Run Configuration** in JetBrains Rider. The required files have been added. All project files will be automatically copied to the Revit plugins folder. 18 | 19 | Creating a package: 20 | 21 | - Open the terminal of your IDE. 22 | - Install Nuke global tools `dotnet tool install Nuke.GlobalTool --global`. 23 | - Run `nuke` command. 24 | - The generated package will be in the **output** folder. 25 | 26 | For more information on building, see the [**RevitTemplates**](https://github.com/Nice3point/RevitTemplates) Wiki page. 27 | 28 | Please refer to the [CHANGELOG](CHANGELOG.md) for details. 29 | 30 | --- 31 | #### Please avoid: 32 | 33 | - Lots of unrelated changes in one commit. 34 | - Modifying files that are not directly related to the feature you implement. 35 | -------------------------------------------------------------------------------- /CadAddinManager/App.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Media.Imaging; 2 | using Autodesk.AutoCAD.Runtime; 3 | using Autodesk.Windows; 4 | using CadAddinManager.Command; 5 | using CadAddinManager.View.Control; 6 | using ImageSource = System.Windows.Media.ImageSource; 7 | using Orientation = System.Windows.Controls.Orientation; 8 | 9 | namespace CadAddinManager; 10 | 11 | public class App : ICadCommand 12 | { 13 | public const string RibbonTitle = "AddinManager"; 14 | public const string RibbonId = "AddinManager"; 15 | 16 | [CommandMethod("InitAddinManager")] 17 | public override void Execute() 18 | { 19 | CreateRibbon(); 20 | } 21 | 22 | private void CreateRibbon() 23 | { 24 | RibbonControl ribbon = ComponentManager.Ribbon; 25 | if (ribbon != null) 26 | { 27 | RibbonTab rtab = ribbon.FindTab(RibbonId); 28 | if (rtab != null) 29 | { 30 | ribbon.Tabs.Remove(rtab); 31 | } 32 | 33 | rtab = new RibbonTab(); 34 | rtab.Title = RibbonTitle; 35 | rtab.Id = RibbonId; 36 | ribbon.Tabs.Add(rtab); 37 | AddContentToTab(rtab); 38 | } 39 | } 40 | 41 | private void AddContentToTab(RibbonTab rtab) 42 | { 43 | rtab.Panels.Add(AddPanelOne()); 44 | } 45 | 46 | private static RibbonPanel AddPanelOne() 47 | { 48 | RibbonPanelSource rps = new RibbonPanelSource(); 49 | rps.Title = "Addin Manager"; 50 | RibbonPanel rp = new RibbonPanel(); 51 | rp.Source = rps; 52 | RibbonButton rci = new RibbonButton(); 53 | rci.Name = "Addin Manager"; 54 | rps.DialogLauncher = rci; 55 | //create button1 56 | var addinAssembly = typeof(App).Assembly; 57 | RibbonButton btnPythonShell = new RibbonButton 58 | { 59 | Orientation = Orientation.Vertical, 60 | AllowInStatusBar = true, 61 | Size = RibbonItemSize.Large, 62 | Name = "Addin Manager Manual", 63 | ShowText = true, 64 | Text = "Addin Manager \n Manual", 65 | Description = "Start Write Addin Manager Manual", 66 | Image = GetEmbeddedPng(addinAssembly, 67 | "CadAddinManager.Resources.dev16x16.png"), 68 | LargeImage = 69 | GetEmbeddedPng(addinAssembly, "CadAddinManager.Resources.dev32x32.png"), 70 | CommandHandler = new RelayCommand(new AddInManagerManual().Execute) 71 | }; 72 | rps.Items.Add(btnPythonShell); 73 | //create button2 74 | RibbonButton btnConfig = new RibbonButton 75 | { 76 | Orientation = Orientation.Vertical, 77 | AllowInStatusBar = true, 78 | Size = RibbonItemSize.Large, 79 | Name = "Addin Manager \n Faceless", 80 | ShowText = true, 81 | Text = "Addin Manager \n Faceless", 82 | Description = "Addin Manager Faceless", 83 | Image = GetEmbeddedPng(addinAssembly, 84 | "CadAddinManager.Resources.dev16x16.png"), 85 | LargeImage = 86 | GetEmbeddedPng(addinAssembly, "CadAddinManager.Resources.dev32x32.png"), 87 | CommandHandler = new RelayCommand(new AddInManagerFaceLess().Execute) 88 | }; 89 | rps.Items.Add(btnConfig); 90 | //Create button 3 91 | RibbonButton btnLogcontrol = new RibbonButton 92 | { 93 | Orientation = Orientation.Vertical, 94 | AllowInStatusBar = true, 95 | Size = RibbonItemSize.Large, 96 | Name = "Show/Hide \n Dock Debug/Trace", 97 | ShowText = true, 98 | Text = "Show/Hide \n Dock Debug/Trace", 99 | Description = "Show/Hide Dock Debug/Trace", 100 | Image = GetEmbeddedPng(addinAssembly, 101 | "CadAddinManager.Resources.dev16x16.png"), 102 | LargeImage = 103 | GetEmbeddedPng(addinAssembly, "CadAddinManager.Resources.dev32x32.png"), 104 | CommandHandler = new RelayCommand(new DockPanelCommand().Execute) 105 | }; 106 | rps.Items.Add(btnLogcontrol); 107 | return rp; 108 | } 109 | public static ImageSource GetEmbeddedPng(System.Reflection.Assembly app, string imageName) 110 | { 111 | var file = app.GetManifestResourceStream(imageName); 112 | var source = PngBitmapDecoder.Create(file, BitmapCreateOptions.None, BitmapCacheOption.None); 113 | return source.Frames[0]; 114 | } 115 | } -------------------------------------------------------------------------------- /CadAddinManager/Command/AddInManagerCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using Autodesk.AutoCAD.ApplicationServices.Core; 3 | using Autodesk.AutoCAD.Runtime; 4 | using CadAddinManager.Model; 5 | using Exception = System.Exception; 6 | 7 | namespace CadAddinManager.Command; 8 | 9 | 10 | public class AddInManagerManual : ICadCommand 11 | { 12 | 13 | [CommandMethod("AddInManagerManual",CommandFlags.Session)] 14 | public override void Execute() 15 | { 16 | Trace.Listeners.Clear(); 17 | Trace.Listeners.Clear(); 18 | CodeListener codeListener = new CodeListener(); 19 | Trace.Listeners.Add(codeListener); 20 | AddinManagerBase.Instance.ExecuteCommand(false); 21 | } 22 | } 23 | 24 | public class AddInManagerFaceLess : ICadCommand 25 | { 26 | [Autodesk.AutoCAD.Runtime.CommandMethod("AddInManagerFaceLess",CommandFlags.Session)] 27 | public override void Execute() 28 | { 29 | try 30 | { 31 | AddinManagerBase.Instance.ExecuteCommand(true); 32 | } 33 | catch (Exception e) 34 | { 35 | MessageBox.Show(e.ToString()); 36 | Trace.WriteLine(e.Message); 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /CadAddinManager/Command/DockPanelCommand.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using System.Windows.Forms.Integration; 3 | using Autodesk.AutoCAD.Runtime; 4 | using Autodesk.AutoCAD.Windows; 5 | using CadAddinManager.View.Control; 6 | 7 | namespace CadAddinManager.Command; 8 | 9 | public class DockPanelCommand : ICadCommand 10 | { 11 | static PaletteSet pLogControl = null; 12 | [CommandMethod("AddinManagerDockPanel")] 13 | public override void Execute() 14 | { 15 | if(pLogControl == null) 16 | { 17 | pLogControl = new PaletteSet("Trace/Debug Output"); 18 | pLogControl.MinimumSize = new System.Drawing.Size(300, 300); 19 | pLogControl.DockEnabled = (DockSides)((int)DockSides.Left + (int)DockSides.Right); 20 | pLogControl.Style = PaletteSetStyles.ShowAutoHideButton 21 | | PaletteSetStyles.ShowCloseButton 22 | | PaletteSetStyles.ShowPropertiesMenu 23 | | PaletteSetStyles.Snappable; 24 | LogControl Lib = new LogControl(); 25 | ElementHost host = new ElementHost(); 26 | host.AutoSize = true; 27 | host.Dock = DockStyle.Right; 28 | host.Child = Lib; 29 | pLogControl.Add("LogControl", host); 30 | } 31 | 32 | pLogControl.KeepFocus = true; 33 | pLogControl.Visible = !pLogControl.Visible; 34 | } 35 | } -------------------------------------------------------------------------------- /CadAddinManager/Command/ICadCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Command; 2 | 3 | public abstract class ICadCommand 4 | { 5 | /// 6 | /// Execute a function in cad application 7 | /// 8 | public abstract void Execute(); 9 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/Addin.cs: -------------------------------------------------------------------------------- 1 | using CadAddinManager.Command; 2 | 3 | namespace CadAddinManager.Model; 4 | 5 | public class Addin : IAddinNode 6 | { 7 | public List ItemList 8 | { 9 | get => itemList; 10 | set => itemList = value; 11 | } 12 | 13 | public string FilePath 14 | { 15 | get => filePath; 16 | set => filePath = value; 17 | } 18 | 19 | public bool Save 20 | { 21 | get => save; 22 | set => save = value; 23 | } 24 | 25 | public bool Hidden 26 | { 27 | get => hidden; 28 | set => hidden = value; 29 | } 30 | 31 | public Addin(string filePath) 32 | { 33 | itemList = new List(); 34 | this.filePath = filePath; 35 | save = true; 36 | } 37 | 38 | public Addin(string filePath, List itemList) 39 | { 40 | this.itemList = itemList; 41 | this.filePath = filePath; 42 | SortAddinItem(); 43 | save = true; 44 | } 45 | 46 | public void SortAddinItem() 47 | { 48 | itemList.Sort(new AddinItemComparer()); 49 | } 50 | 51 | public void RemoveItem(AddinItem item) 52 | { 53 | itemList.Remove(item); 54 | if (itemList.Count == 0) 55 | { 56 | AddinManagerBase.Instance.AddinManager.RemoveAddin(this); 57 | } 58 | } 59 | 60 | public void SaveToLocalIni(IniFile file) 61 | { 62 | if (itemList == null || itemList.Count == 0) 63 | { 64 | return; 65 | } 66 | file.WriteSection("ExternalCommands"); 67 | file.Write("ExternalCommands", "ECCount", 0); 68 | var num = 0; 69 | foreach (var addinItem in itemList) 70 | { 71 | if (addinItem.Save) 72 | { 73 | WriteExternalCommand(file, addinItem, ++num); 74 | } 75 | } 76 | 77 | file.Write("ExternalCommands", "ECCount", num); 78 | } 79 | 80 | private void WriteExternalCommand(IniFile file, AddinItem item, int number) 81 | { 82 | file.Write("ExternalCommands", "ECName" + number, item.Name); 83 | file.Write("ExternalCommands", "ECClassName" + number, item.FullClassName); 84 | file.Write("ExternalCommands", "ECAssembly" + number, item.AssemblyName); 85 | file.Write("ExternalCommands", "ECDescription" + number, item.Description); 86 | } 87 | 88 | private List itemList; 89 | 90 | private string filePath; 91 | 92 | private bool save; 93 | 94 | private bool hidden; 95 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/AddinItem.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using Autodesk.AutoCAD.Runtime; 4 | 5 | namespace CadAddinManager.Model; 6 | 7 | public class AddinItem : IAddinNode 8 | { 9 | public AddinItem(AddinType type) 10 | { 11 | AddinType = type; 12 | clientId = Guid.NewGuid(); 13 | ClientIdString = clientId.ToString(); 14 | assemblyPath = string.Empty; 15 | AssemblyName = string.Empty; 16 | FullClassName = string.Empty; 17 | name = string.Empty; 18 | Save = true; 19 | VisibilityMode = VisibilityMode.AlwaysVisible; 20 | } 21 | 22 | public AddinItem(string assemblyPath, Guid clientId, string fullClassName, AddinType type) 23 | { 24 | 25 | AddinType = type; 26 | this.assemblyPath = assemblyPath; 27 | AssemblyName = Path.GetFileName(this.assemblyPath); 28 | this.clientId = clientId; 29 | ClientIdString = clientId.ToString(); 30 | FullClassName = fullClassName; 31 | var num = fullClassName.LastIndexOf(".", StringComparison.Ordinal); 32 | name = fullClassName.Substring(num + 1); 33 | Save = true; 34 | VisibilityMode = VisibilityMode.AlwaysVisible; 35 | } 36 | public void SaveToManifest() 37 | { 38 | var manifestFile = new ManifestFile(name + DefaultSetting.FormatExAddin); 39 | if (AddinType == AddinType.LispFunction) 40 | { 41 | manifestFile.Applications.Add(this); 42 | } 43 | else if (AddinType == AddinType.Command) 44 | { 45 | manifestFile.Commands.Add(this); 46 | } 47 | manifestFile.Save(); 48 | } 49 | 50 | 51 | public AddinType AddinType { get; set; } 52 | 53 | public string AssemblyPath 54 | { 55 | get => assemblyPath; 56 | set 57 | { 58 | assemblyPath = value; 59 | AssemblyName = Path.GetFileName(assemblyPath); 60 | } 61 | } 62 | 63 | public string AssemblyName { get; set; } 64 | 65 | public Guid ClientId 66 | { 67 | get => clientId; 68 | set 69 | { 70 | clientId = value; 71 | ClientIdString = clientId.ToString(); 72 | } 73 | } 74 | 75 | protected internal string ClientIdString { get; set; } 76 | 77 | public string FullClassName { get; set; } 78 | public MethodInfo MethodInfo { get; set; } 79 | public CommandMethodAttribute Command { get; set; } 80 | public LispFunctionAttribute LispFunction { get; set; } 81 | public string Name 82 | { 83 | get 84 | { 85 | if (string.IsNullOrEmpty(name)) 86 | { 87 | return "External Tool"; 88 | } 89 | return name; 90 | } 91 | set 92 | { 93 | if (!string.IsNullOrEmpty(value)) 94 | { 95 | name = value; 96 | return; 97 | } 98 | name = "External Tool"; 99 | } 100 | } 101 | 102 | public string Description 103 | { 104 | get 105 | { 106 | if (string.IsNullOrEmpty(description)) 107 | { 108 | return string.Empty; 109 | } 110 | return description; 111 | } 112 | set 113 | { 114 | if (string.IsNullOrEmpty(value)) 115 | { 116 | description = string.Empty; 117 | return; 118 | } 119 | description = value; 120 | } 121 | } 122 | 123 | public VisibilityMode VisibilityMode { get; set; } 124 | 125 | public bool Save { get; set; } 126 | 127 | public bool Hidden { get; set; } 128 | 129 | public override string ToString() 130 | { 131 | return name; 132 | } 133 | 134 | protected string assemblyPath; 135 | 136 | protected Guid clientId; 137 | 138 | private string name; 139 | 140 | private string description; 141 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/AddinItemComparer.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Model; 2 | 3 | /// 4 | /// Compare Sort By Full Class Name Method 5 | /// 6 | public class AddinItemComparer : IComparer 7 | { 8 | public int Compare(AddinItem x, AddinItem y) 9 | { 10 | return string.Compare(x.FullClassName, y.FullClassName, StringComparison.Ordinal); 11 | } 12 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/AddinType.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Model; 2 | 3 | [Flags] 4 | public enum AddinType 5 | { 6 | Invalid = 0, 7 | Command = 1, 8 | LispFunction = 2, 9 | Mixed = 3 10 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/Addins.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Reflection; 3 | using Autodesk.AutoCAD.Runtime; 4 | using Exception = System.Exception; 5 | 6 | namespace CadAddinManager.Model; 7 | 8 | public abstract class Addins 9 | { 10 | public SortedDictionary AddinDict 11 | { 12 | get => addinDict; 13 | set => addinDict = value; 14 | } 15 | 16 | public int Count => addinDict.Count; 17 | 18 | public Addins() 19 | { 20 | addinDict = new SortedDictionary(); 21 | } 22 | 23 | public void SortAddin() 24 | { 25 | foreach (var addin in addinDict.Values) 26 | { 27 | addin.SortAddinItem(); 28 | } 29 | } 30 | 31 | public void AddAddIn(Addin addin) 32 | { 33 | var fileName = Path.GetFileName(addin.FilePath); 34 | if (addinDict.ContainsKey(fileName)) 35 | { 36 | addinDict.Remove(fileName); 37 | } 38 | addinDict[fileName] = addin; 39 | } 40 | 41 | public bool RemoveAddIn(Addin addin) 42 | { 43 | var fileName = Path.GetFileName(addin.FilePath); 44 | if (addinDict.ContainsKey(fileName)) 45 | { 46 | addinDict.Remove(fileName); 47 | return true; 48 | } 49 | return false; 50 | } 51 | 52 | public void AddItem(AddinItem item) 53 | { 54 | var assemblyName = item.AssemblyName; 55 | if (!addinDict.ContainsKey(assemblyName)) 56 | { 57 | addinDict[assemblyName] = new Addin(item.AssemblyPath); 58 | } 59 | addinDict[assemblyName].ItemList.Add(item); 60 | } 61 | 62 | public List LoadItems(Assembly assembly, string originalAssemblyFilePath, AddinType type) 63 | { 64 | 65 | List list = new List(); 66 | if (assembly == null) return list; 67 | Type[] array; 68 | try 69 | { 70 | array = assembly.GetTypes(); 71 | } 72 | catch (ReflectionTypeLoadException ex) 73 | { 74 | array = ex.Types; 75 | if (array == null) 76 | { 77 | return list; 78 | } 79 | } 80 | foreach (var type2 in array) 81 | { 82 | try 83 | { 84 | List methodInfos = type2.GetMethods().ToList(); 85 | foreach (MethodInfo methodInfo in methodInfos) 86 | { 87 | switch (type) 88 | { 89 | case AddinType.Invalid: 90 | break; 91 | case AddinType.Command: 92 | var commandAtt = methodInfo.GetCustomAttributes(typeof(CommandMethodAttribute), false).FirstOrDefault(); 93 | if (commandAtt != null) 94 | { 95 | CommandMethodAttribute attribute = commandAtt as CommandMethodAttribute; 96 | string name = $"{methodInfo.DeclaringType.Name}.{methodInfo.Name}"; 97 | AddinItem item = new AddinItem(originalAssemblyFilePath, Guid.NewGuid(), name, type) 98 | { 99 | MethodInfo = methodInfo, 100 | Command = attribute, 101 | }; 102 | list.Add(item); 103 | } 104 | if(list.Count>0) list= list.OrderBy(x=>x.Command.GlobalName).ToList(); 105 | break; 106 | case AddinType.LispFunction: 107 | var lispFuncAtt = methodInfo.GetCustomAttributes(typeof(LispFunctionAttribute), false).FirstOrDefault(); 108 | if (lispFuncAtt != null) 109 | { 110 | LispFunctionAttribute attribute = lispFuncAtt as LispFunctionAttribute; 111 | string name = $"{methodInfo.DeclaringType.Name}.{methodInfo.Name}"; 112 | AddinItem item = new AddinItem(originalAssemblyFilePath, Guid.NewGuid(), name, type) 113 | { 114 | MethodInfo = methodInfo, 115 | LispFunction = attribute, 116 | }; 117 | list.Add(item); 118 | } 119 | if(list.Count>0) list = list.OrderBy(x=>x.LispFunction.GlobalName).ToList(); 120 | break; 121 | case AddinType.Mixed: 122 | break; 123 | default: 124 | throw new ArgumentOutOfRangeException(nameof(type), type, null); 125 | } 126 | 127 | } 128 | } 129 | catch (Exception e) 130 | { 131 | throw new ArgumentException(e.ToString()); 132 | } 133 | } 134 | return list; 135 | } 136 | 137 | protected SortedDictionary addinDict; 138 | 139 | protected int maxCount = 100; 140 | 141 | protected int count; 142 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/AssemblyLoadContext.cs: -------------------------------------------------------------------------------- 1 | #if A25 2 | using System.IO; 3 | using System.Reflection; 4 | using System.Runtime.Loader; 5 | 6 | namespace CadAddinManager.Model; 7 | 8 | class AssemblyLoadContext : System.Runtime.Loader.AssemblyLoadContext 9 | { 10 | public AssemblyLoadContext() : base(isCollectible: true) 11 | { 12 | } 13 | private AssemblyDependencyResolver _resolver; 14 | 15 | public AssemblyLoadContext(string pluginPath): base(isCollectible: true) 16 | { 17 | _resolver = new AssemblyDependencyResolver(pluginPath); 18 | } 19 | 20 | protected override Assembly Load(AssemblyName assemblyName) 21 | { 22 | string assemblyPath = _resolver.ResolveAssemblyToPath(assemblyName); 23 | if (assemblyPath != null) 24 | { 25 | if(assemblyPath.Contains("mgd")) 26 | { 27 | return null; 28 | } 29 | var stream = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read); 30 | return LoadFromStream(stream); 31 | } 32 | 33 | return null; 34 | } 35 | 36 | protected override IntPtr LoadUnmanagedDll(string unmanagedDllName) 37 | { 38 | string libraryPath = _resolver.ResolveUnmanagedDllToPath(unmanagedDllName); 39 | if (libraryPath != null) 40 | { 41 | return LoadUnmanagedDllFromPath(libraryPath); 42 | } 43 | 44 | return IntPtr.Zero; 45 | } 46 | 47 | } 48 | #endif -------------------------------------------------------------------------------- /CadAddinManager/Model/BitmapSourceConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Drawing; 2 | using System.Drawing.Imaging; 3 | using System.IO; 4 | using System.Windows; 5 | using System.Windows.Media; 6 | using System.Windows.Media.Imaging; 7 | 8 | namespace CadAddinManager.Model; 9 | 10 | public static class BitmapSourceConverter 11 | { 12 | public enum ImageType 13 | { 14 | Small, 15 | Large 16 | } 17 | 18 | public static ImageSource ToImageSource(Bitmap bitmap, ImageType imageType) 19 | { 20 | switch (imageType) 21 | { 22 | case ImageType.Small: 23 | return ToImageSource(bitmap).Resize(16); 24 | 25 | case ImageType.Large: 26 | return ToImageSource(bitmap).Resize(32); 27 | 28 | default: 29 | throw new ArgumentOutOfRangeException(nameof(imageType), imageType, null); 30 | } 31 | } 32 | 33 | public static BitmapImage ToImageSource(Bitmap bitmap) 34 | { 35 | var ms = new MemoryStream(); 36 | bitmap.Save(ms, ImageFormat.Png); 37 | var image = new BitmapImage(); 38 | image.BeginInit(); 39 | ms.Seek(0, SeekOrigin.Begin); 40 | image.StreamSource = ms; 41 | image.EndInit(); 42 | return image; 43 | } 44 | 45 | /// 46 | /// Resize ImageResource 47 | /// 48 | /// 49 | /// 50 | /// 51 | public static ImageSource Resize(this ImageSource imageSource, int size) 52 | { 53 | return Thumbnail(imageSource, size); 54 | } 55 | 56 | private static ImageSource Thumbnail(ImageSource source, int size) 57 | { 58 | var rect = new Rect(0, 0, size, size); 59 | var drawingVisual = new DrawingVisual(); 60 | using (var drawingContext = drawingVisual.RenderOpen()) 61 | { 62 | drawingContext.DrawImage(source, rect); 63 | } 64 | var resizedImage = new RenderTargetBitmap((int)rect.Width, (int)rect.Height, 96, 96, PixelFormats.Default); 65 | resizedImage.Render(drawingVisual); 66 | 67 | return resizedImage; 68 | } 69 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/CadAddin.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Model; 2 | 3 | public class CadAddin : ViewModelBase 4 | { 5 | public bool IsReadOnly { get; set; } 6 | public VisibleModel State { get; set; } 7 | public string FilePath { get; set; } 8 | public string Assembly { get; set; } 9 | public string ClientId { get; set; } 10 | public string Name { get; set; } 11 | public string NameNotEx { get; set; } 12 | public string FullClassName { get; set; } 13 | public string Text { get; set; } 14 | public string VisibilityMode { get; set; } 15 | public string LanguageType { get; set; } 16 | public string VendorId { get; set; } 17 | public string VendorDescription { get; set; } 18 | public AddinType AddinType { get; set; } 19 | 20 | private bool _IsChecked; 21 | 22 | public bool IsChecked 23 | { 24 | get => _IsChecked; 25 | set => OnPropertyChanged(ref _IsChecked, value); 26 | } 27 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/CodeListener.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.IO; 3 | 4 | namespace CadAddinManager.Model; 5 | 6 | public class CodeListener : TraceListener 7 | { 8 | public override void Write(string message) 9 | { 10 | WriteMessage(message); 11 | } 12 | 13 | public override void WriteLine(string message) 14 | { 15 | WriteMessage(message); 16 | } 17 | 18 | void WriteMessage(string message) 19 | { 20 | using (StreamWriter st = new StreamWriter(DefaultSetting.PathLogFile, true)) 21 | { 22 | string join = String.Join(": ", $"{DateTime.Now}", message); 23 | st.WriteLine(join); 24 | st.Close(); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/DefaultSetting.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace CadAddinManager.Model; 4 | 5 | /// 6 | /// All setting name default for addin 7 | /// 8 | public static class DefaultSetting 9 | { 10 | public static string AppName = "Cad Addin Manager"; 11 | public static string FileName = "ExternalTool"; 12 | public static string FormatExAddin = ".addin"; 13 | public static string FormatDisable = ".disable"; 14 | 15 | public static string IniName = "Acad.ini"; 16 | 17 | public static string TempFolderName = "AcadAddins"; 18 | 19 | public static string AimInternalName = "AimInternalAcad.ini"; 20 | public static string DirLogFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), 21 | "AppData", 22 | "Local", 23 | "Temp",TempFolderName); 24 | 25 | private static string pathLogFile; 26 | public static string PathLogFile 27 | { 28 | get 29 | { 30 | 31 | bool flag = Directory.Exists(DirLogFile); 32 | if (!flag) Directory.CreateDirectory(DirLogFile); 33 | DirectoryInfo directoryInfo = new DirectoryInfo(DirLogFile); 34 | FileInfo fileInfo = directoryInfo.GetFiles("*.txt",SearchOption.TopDirectoryOnly).OrderBy(x=>x.LastWriteTime).LastOrDefault(); 35 | if (fileInfo==null) 36 | { 37 | pathLogFile = Path.Combine(DirLogFile, $"{Guid.NewGuid()}.txt"); 38 | File.Create(pathLogFile).Close(); 39 | return pathLogFile; 40 | } 41 | else 42 | { 43 | pathLogFile = fileInfo.FullName; 44 | } 45 | return fileInfo.FullName; 46 | } 47 | set => pathLogFile = value; 48 | } 49 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/FolderTooBigDialog.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Windows; 3 | using MessageBox = System.Windows.MessageBox; 4 | 5 | namespace CadAddinManager.Model; 6 | 7 | internal static class FolderTooBigDialog 8 | { 9 | /// 10 | /// Show a waring if file dll too large 11 | /// 12 | /// folder contains file resource 13 | /// limit of dll size 14 | /// 15 | public static MessageBoxResult Show(string folderPath, long sizeInMB) 16 | { 17 | var stringBuilder = new StringBuilder(); 18 | stringBuilder.AppendLine("Folder [" + folderPath + "]"); 19 | stringBuilder.AppendLine("is " + sizeInMB + "MB large."); 20 | stringBuilder.AppendLine("AddinManager will attempt to copy all the files to temp folder"); 21 | stringBuilder.AppendLine("Select [Yes] to copy all the files to temp folder"); 22 | stringBuilder.AppendLine("Select [No] to only copy test script DLL"); 23 | var text = stringBuilder.ToString(); 24 | return MessageBox.Show(text, DefaultSetting.AppName, MessageBoxButton.YesNoCancel, MessageBoxImage.Asterisk); 25 | } 26 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/IAddinNode.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Model; 2 | 3 | public interface IAddinNode 4 | { 5 | bool Save { get; set; } 6 | 7 | bool Hidden { get; set; } 8 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/IEConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.ObjectModel; 2 | 3 | namespace CadAddinManager.Model; 4 | 5 | /// 6 | /// Quick convert collection 7 | /// 8 | public static class IEConverter 9 | { 10 | /// 11 | /// Convert IEnumerableUtils To ObservableCollection 12 | /// 13 | /// 14 | /// 15 | /// 16 | public static ObservableCollection ToObservableCollection(this IEnumerable source) 17 | { 18 | var newSource = new ObservableCollection(); 19 | foreach (var t in source) 20 | { 21 | newSource.Add(t); 22 | } 23 | return newSource; 24 | } 25 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/IniFile.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Runtime.InteropServices; 3 | using System.Text; 4 | 5 | namespace CadAddinManager.Model; 6 | 7 | public class IniFile 8 | { 9 | public string FilePath => filePath; 10 | 11 | public IniFile(string filePath) 12 | { 13 | this.filePath = filePath; 14 | if (!File.Exists(this.filePath)) 15 | { 16 | FileUtils.CreateFile(this.filePath); 17 | FileUtils.SetWriteable(this.filePath); 18 | } 19 | } 20 | 21 | public void WriteSection(string iniSection) 22 | { 23 | WritePrivateProfileSection(iniSection, null, filePath); 24 | } 25 | 26 | public void Write(string iniSection, string iniKey, object iniValue) 27 | { 28 | WritePrivateProfileString(iniSection, iniKey, iniValue.ToString(), filePath); 29 | } 30 | 31 | public string ReadString(string iniSection, string iniKey) 32 | { 33 | var stringBuilder = new StringBuilder(255); 34 | GetPrivateProfileString(iniSection, iniKey, "", stringBuilder, 255, filePath); 35 | return stringBuilder.ToString(); 36 | } 37 | 38 | public int ReadInt(string iniSection, string iniKey) 39 | { 40 | return GetPrivateProfileInt(iniSection, iniKey, 0, filePath); 41 | } 42 | 43 | [DllImport("kernel32.dll")] 44 | private static extern int WritePrivateProfileSection(string lpAppName, string lpString, string lpFileName); 45 | 46 | [DllImport("kernel32", CharSet = CharSet.Auto)] 47 | private static extern int WritePrivateProfileString(string section, string key, string val, string filePath); 48 | 49 | [DllImport("kernel32")] 50 | private static extern int GetPrivateProfileInt(string section, string key, int def, string filePath); 51 | 52 | [DllImport("kernel32", CharSet = CharSet.Auto)] 53 | private static extern int GetPrivateProfileString(string section, string key, string defaultValue, StringBuilder retVal, int size, string filePath); 54 | 55 | private readonly string filePath; 56 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/LogMessageString.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | 3 | namespace CadAddinManager.Model; 4 | 5 | public class LogMessageString 6 | { 7 | private int DEFAULD_FONT_SIZE = 12; 8 | public string Message { get; set; } 9 | public System.Windows.Media.Brush MessageColor { get; set; } 10 | public FontWeight FontWeight { get; set; } 11 | public int FontSize { get; set; } 12 | public LogMessageString(string message, System.Windows.Media.Brush colore) 13 | { 14 | Message = message; 15 | MessageColor = colore; 16 | FontWeight = FontWeights.Normal; 17 | FontSize = DEFAULD_FONT_SIZE; 18 | } 19 | public LogMessageString(string message, System.Windows.Media.Brush colore, FontWeight fontWeight) 20 | { 21 | Message = message; 22 | MessageColor = colore; 23 | FontWeight = fontWeight; 24 | FontSize = DEFAULD_FONT_SIZE; 25 | } 26 | public LogMessageString(string message, System.Windows.Media.Brush colore, FontWeight fontWeight, int fontSize) 27 | { 28 | Message = message; 29 | MessageColor = colore; 30 | FontWeight = fontWeight; 31 | FontSize = fontSize; 32 | } 33 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/ProcessManager.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Diagnostics; 3 | using System.Runtime.InteropServices; 4 | using System.Windows; 5 | using System.Windows.Interop; 6 | 7 | namespace CadAddinManager.Model 8 | { 9 | public static class ProcessManager 10 | { 11 | 12 | [DllImport("user32.dll")] 13 | [return: MarshalAs(UnmanagedType.Bool)] 14 | private static extern bool SetForegroundWindow(IntPtr hWnd); 15 | 16 | public static void SetCadAsWindowOwner(this Window window) 17 | { 18 | if (null == window) { return; } 19 | window.WindowStartupLocation = WindowStartupLocation.CenterScreen; 20 | WindowInteropHelper helper = new WindowInteropHelper(window); 21 | helper.Owner = GetActivateWindow(); 22 | window.Closing += SetActivateWindow; 23 | } 24 | 25 | private static void SetActivateWindow(object sender, CancelEventArgs e) 26 | { 27 | SetActivateWindow(); 28 | } 29 | 30 | /// 31 | /// Set process revert use revit 32 | /// 33 | /// 34 | public static bool SetActivateWindow() 35 | { 36 | IntPtr ptr = GetActivateWindow(); 37 | if (ptr != IntPtr.Zero) 38 | { 39 | return SetForegroundWindow(ptr); 40 | } 41 | return false; 42 | } 43 | 44 | /// 45 | /// return active windows is active 46 | /// 47 | /// 48 | public static IntPtr GetActivateWindow() 49 | { 50 | return Process.GetCurrentProcess().MainWindowHandle; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/StaticUtil.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using MessageBox = System.Windows.MessageBox; 3 | 4 | namespace CadAddinManager.Model; 5 | 6 | public static class StaticUtil 7 | { 8 | public static void ShowWarning(string msg) 9 | { 10 | MessageBox.Show(msg, DefaultSetting.AppName, MessageBoxButton.OK, MessageBoxImage.Exclamation); 11 | } 12 | /// 13 | /// CaseInsensitiveContains 14 | /// 15 | /// 16 | /// 17 | /// 18 | /// 19 | public static bool CaseInsensitiveContains(this string text, string value, StringComparison stringComparison = StringComparison.CurrentCultureIgnoreCase) 20 | { 21 | return text.IndexOf(value, stringComparison) >= 0; 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/ViewModelBase.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using System.Diagnostics; 3 | using System.Globalization; 4 | using System.Reflection; 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace CadAddinManager.Model; 8 | 9 | public class ViewModelBase : INotifyPropertyChanged 10 | { 11 | public event PropertyChangedEventHandler PropertyChanged; 12 | 13 | public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 14 | { 15 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 16 | } 17 | 18 | protected virtual void OnPropertyChanged(string propertyName, object oldValue, object newValue) 19 | { 20 | OnPropertyChanged(propertyName); 21 | } 22 | 23 | public void OnPropertyChanged(ref T property, T value, [CallerMemberName] string propertyName = "") 24 | { 25 | property = value; 26 | var handler = PropertyChanged; 27 | if (handler != null) 28 | { 29 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 30 | } 31 | } 32 | 33 | /// 34 | /// Sets the property value. 35 | /// 36 | /// The type of the property. 37 | /// The field. 38 | /// The value. 39 | /// Name of the property. 40 | /// 41 | /// True if the property was set. 42 | /// 43 | /// This method uses the CallerMemberNameAttribute to determine the property name. 44 | protected bool SetValue(ref T field, T value, [CallerMemberName] string propertyName = "") 45 | { 46 | // ReSharper disable once RedundantNameQualifier 47 | if (object.Equals(field, value)) 48 | { 49 | return false; 50 | } 51 | VerifyProperty(propertyName); 52 | //// this.OnPropertyChanging(propertyName, field, value); 53 | var oldValue = field; 54 | field = value; 55 | OnPropertyChanged(propertyName, oldValue, value); 56 | return true; 57 | } 58 | 59 | /// 60 | /// Verifies the property name. 61 | /// 62 | /// Name of the property. 63 | [Conditional("DEBUG")] 64 | private void VerifyProperty(string propertyName) 65 | { 66 | var type = GetType(); 67 | 68 | // Look for a public property with the specified name. 69 | var propertyInfo = type.GetTypeInfo().GetDeclaredProperty(propertyName); 70 | 71 | Debug.Assert(propertyInfo != null, string.Format(CultureInfo.InvariantCulture, "{0} is not a property of {1}", propertyName, type.FullName)); 72 | } 73 | } -------------------------------------------------------------------------------- /CadAddinManager/Model/VisibilityMode.cs: -------------------------------------------------------------------------------- 1 | namespace CadAddinManager.Model; 2 | 3 | [Flags] 4 | public enum VisibilityMode 5 | { 6 | AlwaysVisible = 0, 7 | NotVisibleInProject = 1, 8 | NotVisibleInFamily = 2, 9 | NotVisibleWhenNoActiveDocument = 4, 10 | NotVisibleInArchitecture = 8, 11 | NotVisibleInStructure = 16, 12 | NotVisibleInMechanical = 32, 13 | NotVisibleInElectrical = 64, 14 | NotVisibleInPlumbing = 128, 15 | NotVisibleInMEP = 224 16 | } 17 | 18 | public enum VisibleModel 19 | { 20 | Enable, 21 | Disable 22 | } -------------------------------------------------------------------------------- /CadAddinManager/PackageContents.xml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /CadAddinManager/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace NavisAddinManager.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /CadAddinManager/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /CadAddinManager/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Cad2022": { 4 | "commandName": "Executable", 5 | "executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2022\\acad.exe" 6 | }, 7 | "Cad2023": { 8 | "commandName": "Executable", 9 | "executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2023\\acad.exe" 10 | }, 11 | "Cad2024": { 12 | "commandName": "Executable", 13 | "executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2024\\acad.exe" 14 | }, 15 | "Cad2025": { 16 | "commandName": "Executable", 17 | "executablePath": "C:\\Program Files\\Autodesk\\AutoCAD 2025\\acad.exe" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /CadAddinManager/Resources/dev.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/dev.ico -------------------------------------------------------------------------------- /CadAddinManager/Resources/dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/dev.png -------------------------------------------------------------------------------- /CadAddinManager/Resources/dev16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/dev16x16.png -------------------------------------------------------------------------------- /CadAddinManager/Resources/dev32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/dev32x32.png -------------------------------------------------------------------------------- /CadAddinManager/Resources/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/folder.png -------------------------------------------------------------------------------- /CadAddinManager/Resources/lab16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/lab16x16.png -------------------------------------------------------------------------------- /CadAddinManager/Resources/lab32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chuongmep/CadAddinManager/7c680102cb327c6ca4d510e2b41dcb9b94058120/CadAddinManager/Resources/lab32x32.png -------------------------------------------------------------------------------- /CadAddinManager/View/AssemblyLoader.xaml: -------------------------------------------------------------------------------- 1 |  15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |