From 34895d5494b2421ae9757392f70b548847e0ad3a Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 14:02:57 +0100 Subject: [PATCH 01/29] Update actions in `labels.yml` workflow --- .github/workflows/labels.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 52591f7cc..75892cade 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -14,7 +14,7 @@ jobs: labels: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - uses: gitlabels/gitlabels@v1 + - uses: actions/checkout@v5 + - uses: gitlabels/gitlabels@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 322f5f2bad7bae8d07d6ff735dc4b737e1ae1f87 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 14:16:11 +0100 Subject: [PATCH 02/29] Update actions in `tests.yml` workflow --- .github/workflows/tests.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 410d98c15..1156561d9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,18 +31,18 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v5 - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v5 with: dotnet-version: '7.0.201' - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1.1 + uses: microsoft/setup-msbuild@v2 - name: Cache packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.nuget/packages key: NetOffice-nuget-${{ hashFiles('**/packages.lock.json') }} @@ -66,7 +66,7 @@ jobs: VersionSuffix: ${{ steps.build.outputs.app_version_suffix }} - name: Archive NetOffice binaries - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: NetOffice_binaries_v${{ steps.build.outputs.app_version_full }}_${{ matrix.configuration }} path: '${{ github.workspace }}\Source\ClientApplication\bin\${{ matrix.configuration }}' From 7e7a68ba123469c526d8f665faf2d2ff5ec0528e Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 14:16:25 +0100 Subject: [PATCH 03/29] Update actions in `release.yml` workflow --- .github/workflows/release.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a4f15552..99b397d2d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,18 +28,18 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v5 - name: Setup dotnet - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v5 with: dotnet-version: '7.0.201' - name: Setup MSBuild - uses: microsoft/setup-msbuild@v1.1 + uses: microsoft/setup-msbuild@v2 - name: Cache dotnet tools - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache-dotnettools with: path: ~/.dotnet/tools @@ -54,7 +54,7 @@ jobs: run: dotnet tool install --verbosity minimal --global NuGetKeyVaultSignTool --version 3.2.2 - name: Cache packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.nuget/packages key: NetOffice-nuget-${{ hashFiles('**/packages.lock.json') }} @@ -93,7 +93,7 @@ jobs: timestamp-digest: SHA256 - name: Archive NetOffice binaries - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: NetOffice_binaries_v${{ steps.build.outputs.app_version_full }}_${{ matrix.configuration }} path: '${{ github.workspace }}\Source\ClientApplication\bin\${{ matrix.configuration }}' @@ -129,7 +129,7 @@ jobs: - name: Archive NetOffice packages if: success() && steps.build.outputs.publish_nuget == 'true' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v5 with: name: NetOffice_packages_v${{ steps.build.outputs.app_version_full }} path: '${{ github.workspace }}\dist' From 8014f93dcb981f11e14937df5434c6c32ac81a15 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 14:18:56 +0100 Subject: [PATCH 04/29] Use .NET 8 SDK to run build --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 99b397d2d..390f04f30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v5 with: - dotnet-version: '7.0.201' + dotnet-version: 8 - name: Setup MSBuild uses: microsoft/setup-msbuild@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1156561d9..ef6b8ec58 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -36,7 +36,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v5 with: - dotnet-version: '7.0.201' + dotnet-version: 8 - name: Setup MSBuild uses: microsoft/setup-msbuild@v2 From 87842a9e01e8a9385c75cc9c91a43466ddb78e53 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 14:17:57 +0100 Subject: [PATCH 05/29] Update code singing tools --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 390f04f30..ed8b750d2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -47,11 +47,11 @@ jobs: - name: Setup AzureSignTool if: steps.cache-dotnettools.outputs.cache-hit != 'true' - run: dotnet tool install --verbosity minimal --global azuresigntool --version 3.0.0 + run: dotnet tool install --verbosity minimal --global azuresigntool --version 6.0.1 - name: Setup NuGetKeyVaultSignTool if: steps.cache-dotnettools.outputs.cache-hit != 'true' - run: dotnet tool install --verbosity minimal --global NuGetKeyVaultSignTool --version 3.2.2 + run: dotnet tool install --verbosity minimal --global NuGetKeyVaultSignTool --version 3.2.3 - name: Cache packages uses: actions/cache@v4 From 25dc0f2648cb29ae70578a910ce69ceb1b8471ce Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Thu, 12 Dec 2024 21:41:54 +0100 Subject: [PATCH 06/29] Use the `win-x86` platform as the `win7-x86` is no longer supported Fixed the `error NU1004: The project's runtime identifiers have changed from. Project's runtime identifiers: win-x86, lock file's runtime identifiers win7-x86.` --- Source/ClientApplication/packages.lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/ClientApplication/packages.lock.json b/Source/ClientApplication/packages.lock.json index d26077df7..8845b5b34 100644 --- a/Source/ClientApplication/packages.lock.json +++ b/Source/ClientApplication/packages.lock.json @@ -167,6 +167,6 @@ } } }, - ".NETFramework,Version=v4.6.2/win7-x86": {} + ".NETFramework,Version=v4.6.2/win-x86": {} } } \ No newline at end of file From f4dc2357c95da2deeff40e5c13a24ee84f41f1ca Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 22:43:56 +0100 Subject: [PATCH 07/29] Use Azure Trusted Signing service to digitally sign NetOffice libraries --- .github/workflows/release.yml | 37 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ed8b750d2..c1912c019 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,10 +6,13 @@ on: - 'v*.*.*' permissions: + id-token: write contents: read jobs: release: + environment: production + runs-on: windows-2022 strategy: @@ -45,13 +48,13 @@ jobs: path: ~/.dotnet/tools key: dotnettools - - name: Setup AzureSignTool + - name: Setup dotnet sign tool if: steps.cache-dotnettools.outputs.cache-hit != 'true' - run: dotnet tool install --verbosity minimal --global azuresigntool --version 6.0.1 + run: dotnet tool install --verbosity minimal --global sign --version 0.9.1-beta.25379.1 - - name: Setup NuGetKeyVaultSignTool + - name: Setup Knapcode.CertificateExtractor tool if: steps.cache-dotnettools.outputs.cache-hit != 'true' - run: dotnet tool install --verbosity minimal --global NuGetKeyVaultSignTool --version 3.2.3 + run: dotnet tool install --verbosity minimal --global Knapcode.CertificateExtractor --version 0.1.1 - name: Cache packages uses: actions/cache@v4 @@ -77,20 +80,24 @@ jobs: $content = $content.Replace('${{ github.workspace }}', '..') $content | Set-Content obj/signlist.txt + - name: azure login + uses: azure/login@v2 + with: + client-id: ${{ secrets.TRUSTED_SIGNING_CLIENT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + - name: Sign NetOffice libraries if: success() && steps.build.outputs.sign_binaries == 'true' - uses: azure/trusted-signing-action@v0.3.19 + uses: azure/trusted-signing-action@v0.5.10 with: - azure-tenant-id: ${{ secrets.KEYVAULT_TENANT_ID }} - azure-client-id: ${{ secrets.KEYVAULT_CLIENT_ID }} - azure-client-secret: ${{ secrets.KEYVAULT_CLIENT_SECRET }} - endpoint: ${{ vars.KEYVAULT_ENDPOINT }} - trusted-signing-account-name: ${{ vars.KEYVAULT_ACCOUNT_NAME }} - certificate-profile-name: ${{ secrets.KEYVAULT_CERTIFICATE_PROFILE }} - files-catalog: '${{ github.workspace }}/obj/signlist.txt' - file-digest: SHA256 - timestamp-rfc3161: http://timestamp.acs.microsoft.com - timestamp-digest: SHA256 + endpoint: ${{ secrets.TRUSTED_SIGNING_ENDPOINT }} + trusted-signing-account-name: ${{ secrets.TRUSTED_SIGNING_ACCOUNT_NAME }} + certificate-profile-name: ${{ secrets.TRUSTED_SIGNING_CERTIFICATE_PROFILE }} + files-catalog: '${{ github.workspace }}/obj/signlist.txt' + file-digest: SHA256 + timestamp-rfc3161: http://timestamp.acs.microsoft.com + timestamp-digest: SHA256 - name: Archive NetOffice binaries uses: actions/upload-artifact@v5 From 46558dc627eabe9eb04d023f135f05dbd39547e6 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 1 Nov 2025 21:40:12 +0100 Subject: [PATCH 08/29] Use Azure Trusted Signing service to digitally sign NetOffice nuget packages --- .github/workflows/release.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c1912c019..8ba3d9464 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -106,28 +106,28 @@ jobs: path: '${{ github.workspace }}\Source\ClientApplication\bin\${{ matrix.configuration }}' - name: Pack NetOffice - if: steps.build.outputs.publish_nuget == 'true' run: | dotnet pack --no-build --no-restore Source\NetOffice.sln -c ${{ matrix.configuration }} -o dist env: VersionSuffix: ${{ steps.build.outputs.app_version_suffix }} - # - name: Sign NetOffice packages - # if: success() && steps.build.outputs.publish_nuget == 'true' && steps.build.outputs.sign_binaries == 'true' - # working-directory: '${{ github.workspace}}\dist' - # run: | - # NuGetKeyVaultSignTool.exe sign *.nupkg ` - # --file-digest sha256 ` - # --timestamp-rfc3161 http://timestamp.digicert.com ` - # --timestamp-digest sha256 ` - # --azure-key-vault-url https://opensourcesigning.vault.azure.net ` - # --azure-key-vault-tenant-id "${{ secrets.KEYVAULT_TENANT_ID }}" ` - # --azure-key-vault-client-id "${{ secrets.KEYVAULT_CLIENT_ID }}" ` - # --azure-key-vault-client-secret "${{ secrets.KEYVAULT_CLIENT_SECRET }}" ` - # --azure-key-vault-certificate "goITSolutions-until-2024-01" + - name: Sign NetOffice packages + if: success() && steps.build.outputs.sign_binaries == 'true' + working-directory: '${{ github.workspace}}\dist' + run: | + sign code trusted-signing *.nupkg ` + --publisher-name "NetOffice" ` + --description "NetOffice" ` + --description-url "https://github.com/NetOfficeFw/NetOffice" ` + --trusted-signing-endpoint "${{ secrets.TRUSTED_SIGNING_ENDPOINT }}" ` + --trusted-signing-account "${{ secrets.TRUSTED_SIGNING_ACCOUNT_NAME }}" ` + --trusted-signing-certificate-profile "${{ secrets.TRUSTED_SIGNING_CERTIFICATE_PROFILE }}" ` + --file-digest SHA256 ` + --timestamp-url http://timestamp.acs.microsoft.com ` + --timestamp-digest SHA256 - name: Publish packages - if: success() && steps.build.outputs.publish_nuget == 'true' + if: success() && steps.build.outputs.publish_nuget == 'true' working-directory: '${{ github.workspace}}\dist' run: | dotnet nuget push *.nupkg --api-key $env:NUGET_TOKEN --source https://api.nuget.org/v3/index.json @@ -135,7 +135,7 @@ jobs: NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} - name: Archive NetOffice packages - if: success() && steps.build.outputs.publish_nuget == 'true' + if: success() uses: actions/upload-artifact@v5 with: name: NetOffice_packages_v${{ steps.build.outputs.app_version_full }} From 50b60dd82ec2ca15d32a84f3231b5c405bf9b895 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sun, 2 Nov 2025 14:30:12 +0000 Subject: [PATCH 09/29] Explicitly sign NetOffice assemblies which are archived into legacy package --- .github/workflows/release.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8ba3d9464..8423f2187 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -95,6 +95,21 @@ jobs: trusted-signing-account-name: ${{ secrets.TRUSTED_SIGNING_ACCOUNT_NAME }} certificate-profile-name: ${{ secrets.TRUSTED_SIGNING_CERTIFICATE_PROFILE }} files-catalog: '${{ github.workspace }}/obj/signlist.txt' + files: | + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/AccessApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/ADODBApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/DAOApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/ExcelApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/MSComctlLibApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/MSDATASRCApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/NetOffice.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/OfficeApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/OfficeApi.Extensions.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/OutlookApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/OWC10Api.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/PowerPointApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/VBIDEApi.dll + ${{ github.workspace }}/Source/ClientApplication/bin/${{ matrix.configuration }}/WordApi.dll file-digest: SHA256 timestamp-rfc3161: http://timestamp.acs.microsoft.com timestamp-digest: SHA256 From 0cc1573bea23b49682f824d2dcc51179b745042c Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sun, 2 Nov 2025 19:27:09 +0100 Subject: [PATCH 10/29] Extract trusted signing certificate --- .github/workflows/release.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8423f2187..525a9ca46 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -141,6 +141,12 @@ jobs: --timestamp-url http://timestamp.acs.microsoft.com ` --timestamp-digest SHA256 + - name: Extract trusted signing certificate + if: success() && steps.build.outputs.sign_binaries == 'true' + run: | + $nupkg = Get-ChildItem -Path '${{ github.workspace}}\dist' -Filter '*.nupkg' | Select-Object -First 1 + nuget-cert-extractor --file $nupkg --output '${{ github.workspace}}\dist' --code-signing --author --leaf + - name: Publish packages if: success() && steps.build.outputs.publish_nuget == 'true' working-directory: '${{ github.workspace}}\dist' From 22addc1e6a93900b05895d90a49d53d26a02b4f6 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sun, 2 Nov 2025 22:02:16 +0100 Subject: [PATCH 11/29] Rewrite nuget packages publishing to individual gated job --- .github/Get-BuildInfo.ps1 | 1 + .github/workflows/release.yml | 56 +++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/.github/Get-BuildInfo.ps1 b/.github/Get-BuildInfo.ps1 index 879a4e3c7..76e32b4bd 100644 --- a/.github/Get-BuildInfo.ps1 +++ b/.github/Get-BuildInfo.ps1 @@ -58,3 +58,4 @@ Write-GitHubVariable "app_version_suffix" $app_version_suffix Write-GitHubVariable "app_version_full" $app_version_full Write-GitHubVariable "sign_binaries" $sign_binaries Write-GitHubVariable "publish_nuget" $publish_nuget +Write-GitHubVariable "nuget_packages_artifact_name" "NetOffice_packages_v$app_version_full" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 525a9ca46..abd22187b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,9 @@ jobs: RepositoryCommit: '${{ github.sha }}' Configuration: '${{ matrix.configuration }}' + outputs: + nuget_packages_artifact_name: ${{ steps.build.outputs.nuget_packages_artifact_name }} + steps: - name: Checkout uses: actions/checkout@v5 @@ -147,17 +150,52 @@ jobs: $nupkg = Get-ChildItem -Path '${{ github.workspace}}\dist' -Filter '*.nupkg' | Select-Object -First 1 nuget-cert-extractor --file $nupkg --output '${{ github.workspace}}\dist' --code-signing --author --leaf - - name: Publish packages - if: success() && steps.build.outputs.publish_nuget == 'true' - working-directory: '${{ github.workspace}}\dist' - run: | - dotnet nuget push *.nupkg --api-key $env:NUGET_TOKEN --source https://api.nuget.org/v3/index.json - env: - NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} - - name: Archive NetOffice packages if: success() uses: actions/upload-artifact@v5 with: - name: NetOffice_packages_v${{ steps.build.outputs.app_version_full }} + name: ${{ steps.build.outputs.nuget_packages_artifact_name }} path: '${{ github.workspace }}\dist' + + - name: Archive code signing certificate + if: success() && matrix.configuration == 'Release' + uses: actions/upload-artifact@v5 + with: + name: certificate + path: '${{ github.workspace }}/dist/*.cer' + + - name: Release documentation + if: matrix.configuration == 'Release' + run: | + 'To release the NuGet package, upload the signing certificate to NuGet Gallery via Account Settings: . ' >> $env:GITHUB_STEP_SUMMARY + 'See the `certificate` artifact for the signing certificate file.' >> $env:GITHUB_STEP_SUMMARY + '' >> $env:GITHUB_STEP_SUMMARY + 'Approve the `publish` job deployment to the `nuget-gallery` environment when the certificate was added to NuGet Gallery.' >> $env:GITHUB_STEP_SUMMARY + + publish: + environment: nuget-gallery + + permissions: + id-token: write + + needs: release + + runs-on: ubuntu-latest + + steps: + - name: Download NetOffice packages + uses: actions/download-artifact@v5 + with: + name: ${{ needs.release.outputs.nuget_packages_artifact_name }} + + - name: Authenticate Nuget Gallery + uses: NuGet/login@v1 + id: nuget + with: + user: ${{ secrets.NUGET_TRUSTED_PUBLISHING_USER }} + + - name: Publish packages + run: | + dotnet nuget push "*.nupkg" --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json + env: + NUGET_API_KEY: ${{ steps.nuget.outputs.NUGET_API_KEY }} From 4a43cd5de6c4fc40470507b0813df1b1ef487a52 Mon Sep 17 00:00:00 2001 From: kev-is-coding-for-adn <89839929+kev-is-coding-for-adn@users.noreply.github.com> Date: Mon, 14 Apr 2025 11:56:46 +0000 Subject: [PATCH 12/29] Implement Presentation.AutoSaveOn property in PowerPointApi --- .../DispatchInterfaces/_Presentation.cs | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/Source/PowerPoint/DispatchInterfaces/_Presentation.cs b/Source/PowerPoint/DispatchInterfaces/_Presentation.cs index b80b61b6b..0eeeca0f1 100644 --- a/Source/PowerPoint/DispatchInterfaces/_Presentation.cs +++ b/Source/PowerPoint/DispatchInterfaces/_Presentation.cs @@ -1272,6 +1272,28 @@ public NetOffice.PowerPointApi.Guides Guides return Factory.ExecuteKnownReferencePropertyGet(this, "Guides", NetOffice.PowerPointApi.Guides.LateBindingApiWrapperType); } } + + /// + /// True if the edits in the Presentation are automatically saved. Read/write Boolean. + /// + /// SupportByVersion PowerPoint 16 + /// Get/Set + /// + /// Docs: + [SupportByVersion("PowerPoint", 16)] + public bool AutoSaveOn + { + get + { + return Factory.ExecuteBoolPropertyGet(this, "AutoSaveOn"); + } + set + { + Factory.ExecuteValuePropertySet(this, "AutoSaveOn", value); + } + } + + #endregion From b86beceeac38d07e677a1e1136bc8672744e075e Mon Sep 17 00:00:00 2001 From: kev-is-coding-for-adn <89839929+kev-is-coding-for-adn@users.noreply.github.com> Date: Tue, 15 Apr 2025 10:50:55 +0200 Subject: [PATCH 13/29] Use English documentation link --- Source/PowerPoint/DispatchInterfaces/_Presentation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/PowerPoint/DispatchInterfaces/_Presentation.cs b/Source/PowerPoint/DispatchInterfaces/_Presentation.cs index 0eeeca0f1..2ca77c897 100644 --- a/Source/PowerPoint/DispatchInterfaces/_Presentation.cs +++ b/Source/PowerPoint/DispatchInterfaces/_Presentation.cs @@ -1279,7 +1279,7 @@ public NetOffice.PowerPointApi.Guides Guides /// SupportByVersion PowerPoint 16 /// Get/Set /// - /// Docs: + /// Docs: [SupportByVersion("PowerPoint", 16)] public bool AutoSaveOn { From a731860d10113db2feb867d3cfd520eec1cfe2e9 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sun, 2 Nov 2025 22:21:22 +0100 Subject: [PATCH 14/29] Add integration test for presentation saved locally and with Auto Save feature disabled --- Source/NetOffice.Tests/NetOffice.Tests.csproj | 8 +++ ...tionSavedLocally_FeatureAutoSaveIsOff.pptx | Bin 0 -> 36034 bytes .../PowerPointApi/PresentationTests.cs | 53 ++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 Source/NetOffice.Tests/PowerPointApi/Docs/AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff.pptx create mode 100644 Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs diff --git a/Source/NetOffice.Tests/NetOffice.Tests.csproj b/Source/NetOffice.Tests/NetOffice.Tests.csproj index a02334364..8c93ec14b 100644 --- a/Source/NetOffice.Tests/NetOffice.Tests.csproj +++ b/Source/NetOffice.Tests/NetOffice.Tests.csproj @@ -42,4 +42,12 @@ + + + + + + PreserveNewest + + diff --git a/Source/NetOffice.Tests/PowerPointApi/Docs/AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff.pptx b/Source/NetOffice.Tests/PowerPointApi/Docs/AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff.pptx new file mode 100644 index 0000000000000000000000000000000000000000..a17160352b69e1cf97615ce4124a83fd55612f4e GIT binary patch literal 36034 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 S?<)JckCe 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 literal 0 HcmV?d00001 diff --git a/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs b/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs new file mode 100644 index 000000000..a02017e7d --- /dev/null +++ b/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs @@ -0,0 +1,53 @@ +using System; +using NUnit.Framework; +using NetOffice.PowerPointApi; +using System.IO; + +namespace NetOffice.Tests.PowerPointApi +{ + [TestFixture] + [Category("IntegrationTests")] + [Category("IntegrationTests_PowerPoint")] + public class PresentationTests + { + public Application PowerPointApp { get; set; } + public Documents Docs { get; set; } + + [SetUp] + public void SetUp() + { + this.PowerPointApp = new Application(); + this.Docs = new Documents(TestContext.CurrentContext); + } + + [TearDown] + public void TearDown() + { + this.PowerPointApp?.Quit(); + this.PowerPointApp?.Dispose(); + } + + [Test] + public void AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff_ReturnsFalse() + { + // Arrange + var presentation = PowerPointApp.Presentations.Open(this.Docs.AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff, false); + + // Act + var actualValue = presentation.AutoSaveOn; + + // Assert + Assert.IsFalse(actualValue); + } + + public class Documents + { + public string AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff { get; set; } + + public Documents(TestContext context) + { + this.AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff = Path.Combine(context.TestDirectory, @"PowerPointApi\Docs", "AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff.pptx"); + } + } + } +} From 0c2e33a0294ce6f18694a4bb6ba080a5635325b2 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sun, 2 Nov 2025 22:21:29 +0100 Subject: [PATCH 15/29] Add integration test for presentation saved in OneDrive and with Auto Save feature enabled --- .../PowerPointApi/PresentationTests.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs b/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs index a02017e7d..fe6a5a271 100644 --- a/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs +++ b/Source/NetOffice.Tests/PowerPointApi/PresentationTests.cs @@ -38,15 +38,38 @@ public void AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff_ReturnsFals // Assert Assert.IsFalse(actualValue); + + // Cleanup + presentation.Close(); + } + + [Test] + public void AutoSaveOn_PresentationSavedInOneDrive_FeatureAutoSaveIsOn_ReturnsTrue() + { + // Arrange + var presentation = PowerPointApp.Presentations.Open(this.Docs.AutoSaveOn_PresentationSavedInOneDrive_FeatureAutoSaveIsOn, false); + + // Act + var actualValue = presentation.AutoSaveOn; + + // Assert + Assert.IsTrue(actualValue); + + // Cleanup + presentation.Close(); } public class Documents { public string AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff { get; set; } + public string AutoSaveOn_PresentationSavedInOneDrive_FeatureAutoSaveIsOn { get; set; } public Documents(TestContext context) { this.AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff = Path.Combine(context.TestDirectory, @"PowerPointApi\Docs", "AutoSaveOn_PresentationSavedLocally_FeatureAutoSaveIsOff.pptx"); + + // Public link: https://1drv.ms/p/c/8cd14a64b99957bc/EVX1bUNmBtxDvfvg-aNQjKkBX35RJ3BJ6_2ey2Ox5gnIfA?e=DVyExX + this.AutoSaveOn_PresentationSavedInOneDrive_FeatureAutoSaveIsOn = @"https://d.docs.live.net/8CD14A64B99957BC/Developer/NetOfficeFw/PowerPoint/AutoSaveOn_PresentationSavedInOneDrive_FeatureAutoSaveIsOn.pptx"; } } } From d952fffa9693913e0013204a76b2311e07db692d Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 15 Nov 2025 18:09:17 +0100 Subject: [PATCH 16/29] Remove obsolete BuildTools folder The BuildTools folder contained utilities from the era of targeting multiple .NET Frameworks (2.0-4.5). These tools are no longer necessary as the project now uses modern SDK-style projects targeting .NET Framework 4.6.2. Removed tools: - VersionUpdater: Updated .NET Framework versions in project files - SourceUpdater: Bulk source file updates (referenced SVN) - SearchAndReplace: Text search and replace tool - ReferenceAnalyzer: Project reference analyzer These tools were last modified in 2013-2016 and are not referenced in any build scripts, CI/CD configuration, or documentation. Modern alternatives are built into Visual Studio and MSBuild. Fixes #446 Co-Authored-By: Claude Code Sonnet 4.5 --- BuildTools/Lib/HtmlAgilityPack.dll | Bin 134656 -> 0 bytes BuildTools/Lib/HtmlAgilityPack.pdb | Bin 271872 -> 0 bytes BuildTools/Lib/HtmlAgilityPack.xml | 2468 ----------------- BuildTools/NOBuildTools.sln | 66 - .../ReferenceAnalyzer/ExceptionDisplayer.cs | 34 - .../ReferenceAnalyzer/Form1.Designer.cs | 117 - BuildTools/ReferenceAnalyzer/Form1.cs | 74 - BuildTools/ReferenceAnalyzer/Form1.resx | 120 - .../NOBuildTools.ReferenceAnalyzer.csproj | 91 - BuildTools/ReferenceAnalyzer/Parser.cs | 1803 ------------ BuildTools/ReferenceAnalyzer/Program.cs | 21 - .../Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 71 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 30 - .../Properties/Settings.settings | 7 - BuildTools/SearchAndReplace/ConfigManager.cs | 63 - .../SearchAndReplace/ExceptionDisplayer.cs | 34 - BuildTools/SearchAndReplace/Form1.Designer.cs | 220 -- BuildTools/SearchAndReplace/Form1.cs | 112 - BuildTools/SearchAndReplace/Form1.resx | 120 - .../NOBuildTools.SearchAndReplace.csproj | 90 - BuildTools/SearchAndReplace/Program.cs | 21 - .../Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 63 - .../Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - .../SearchAndReplaceManager.cs | 256 -- BuildTools/SourceUpdater/Form1.Designer.cs | 158 -- BuildTools/SourceUpdater/Form1.cs | 104 - BuildTools/SourceUpdater/Form1.resx | 120 - .../NOBuildTools.SourceUpdater.csproj | 92 - BuildTools/SourceUpdater/Program.cs | 20 - .../SourceUpdater/Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 63 - .../SourceUpdater/Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - BuildTools/SourceUpdater/app.config | 3 - BuildTools/VersionUpdater/ConfigManager.cs | 71 - .../VersionUpdater/ExceptionDisplayer.cs | 35 - BuildTools/VersionUpdater/Form1.Designer.cs | 255 -- BuildTools/VersionUpdater/Form1.cs | 463 ---- BuildTools/VersionUpdater/Form1.resx | 120 - .../NOBuildTools.VersionUpdater.csproj | 124 - BuildTools/VersionUpdater/Program.cs | 20 - .../VersionUpdater/Properties/AssemblyInfo.cs | 36 - .../Properties/Resources.Designer.cs | 63 - .../VersionUpdater/Properties/Resources.resx | 117 - .../Properties/Settings.Designer.cs | 26 - .../Properties/Settings.settings | 7 - BuildTools/VersionUpdater/app.config | 3 - 53 files changed, 8306 deletions(-) delete mode 100644 BuildTools/Lib/HtmlAgilityPack.dll delete mode 100644 BuildTools/Lib/HtmlAgilityPack.pdb delete mode 100644 BuildTools/Lib/HtmlAgilityPack.xml delete mode 100644 BuildTools/NOBuildTools.sln delete mode 100644 BuildTools/ReferenceAnalyzer/ExceptionDisplayer.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Form1.Designer.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Form1.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Form1.resx delete mode 100644 BuildTools/ReferenceAnalyzer/NOBuildTools.ReferenceAnalyzer.csproj delete mode 100644 BuildTools/ReferenceAnalyzer/Parser.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Program.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Properties/AssemblyInfo.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Properties/Resources.Designer.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Properties/Resources.resx delete mode 100644 BuildTools/ReferenceAnalyzer/Properties/Settings.Designer.cs delete mode 100644 BuildTools/ReferenceAnalyzer/Properties/Settings.settings delete mode 100644 BuildTools/SearchAndReplace/ConfigManager.cs delete mode 100644 BuildTools/SearchAndReplace/ExceptionDisplayer.cs delete mode 100644 BuildTools/SearchAndReplace/Form1.Designer.cs delete mode 100644 BuildTools/SearchAndReplace/Form1.cs delete mode 100644 BuildTools/SearchAndReplace/Form1.resx delete mode 100644 BuildTools/SearchAndReplace/NOBuildTools.SearchAndReplace.csproj delete mode 100644 BuildTools/SearchAndReplace/Program.cs delete mode 100644 BuildTools/SearchAndReplace/Properties/AssemblyInfo.cs delete mode 100644 BuildTools/SearchAndReplace/Properties/Resources.Designer.cs delete mode 100644 BuildTools/SearchAndReplace/Properties/Resources.resx delete mode 100644 BuildTools/SearchAndReplace/Properties/Settings.Designer.cs delete mode 100644 BuildTools/SearchAndReplace/Properties/Settings.settings delete mode 100644 BuildTools/SearchAndReplace/SearchAndReplaceManager.cs delete mode 100644 BuildTools/SourceUpdater/Form1.Designer.cs delete mode 100644 BuildTools/SourceUpdater/Form1.cs delete mode 100644 BuildTools/SourceUpdater/Form1.resx delete mode 100644 BuildTools/SourceUpdater/NOBuildTools.SourceUpdater.csproj delete mode 100644 BuildTools/SourceUpdater/Program.cs delete mode 100644 BuildTools/SourceUpdater/Properties/AssemblyInfo.cs delete mode 100644 BuildTools/SourceUpdater/Properties/Resources.Designer.cs delete mode 100644 BuildTools/SourceUpdater/Properties/Resources.resx delete mode 100644 BuildTools/SourceUpdater/Properties/Settings.Designer.cs delete mode 100644 BuildTools/SourceUpdater/Properties/Settings.settings delete mode 100644 BuildTools/SourceUpdater/app.config delete mode 100644 BuildTools/VersionUpdater/ConfigManager.cs delete mode 100644 BuildTools/VersionUpdater/ExceptionDisplayer.cs delete mode 100644 BuildTools/VersionUpdater/Form1.Designer.cs delete mode 100644 BuildTools/VersionUpdater/Form1.cs delete mode 100644 BuildTools/VersionUpdater/Form1.resx delete mode 100644 BuildTools/VersionUpdater/NOBuildTools.VersionUpdater.csproj delete mode 100644 BuildTools/VersionUpdater/Program.cs delete mode 100644 BuildTools/VersionUpdater/Properties/AssemblyInfo.cs delete mode 100644 BuildTools/VersionUpdater/Properties/Resources.Designer.cs delete mode 100644 BuildTools/VersionUpdater/Properties/Resources.resx delete mode 100644 BuildTools/VersionUpdater/Properties/Settings.Designer.cs delete mode 100644 BuildTools/VersionUpdater/Properties/Settings.settings delete mode 100644 BuildTools/VersionUpdater/app.config diff --git a/BuildTools/Lib/HtmlAgilityPack.dll b/BuildTools/Lib/HtmlAgilityPack.dll deleted file mode 100644 index 3d96d71af9c50d3c2ca92633286c8fa06bb184ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134656 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

UQ8i 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 diff --git a/BuildTools/Lib/HtmlAgilityPack.pdb b/BuildTools/Lib/HtmlAgilityPack.pdb deleted file mode 100644 index c2e6bca23393cf8277a36596a833072dd050e899..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 271872 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
$7IR2UjBROYVw`%#p7OX?Ri@+ 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�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

YLt|V0 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 Ee^2)^8~^|S diff --git a/BuildTools/Lib/HtmlAgilityPack.xml b/BuildTools/Lib/HtmlAgilityPack.xml deleted file mode 100644 index f47566cfc..000000000 --- a/BuildTools/Lib/HtmlAgilityPack.xml +++ /dev/null @@ -1,2468 +0,0 @@ - - - - HtmlAgilityPack - - - -

- Represents a fragment of code in a mixed code document. - - - - - Represents a base class for fragments in a mixed code document. - - - - - Gets the fragement text. - - - - - Gets the type of fragment. - - - - - Gets the line number of the fragment. - - - - - Gets the line position (column) of the fragment. - - - - - Gets the fragment position in the document's stream. - - - - - Gets the fragment code text. - - - - - A utility class to get HTML document from HTTP. - - - - - Occurs after an HTTP request has been executed. - - - - - Occurs before an HTML document is handled. - - - - - Occurs before an HTTP request is executed. - - - - - Gets the MIME content type for a given path extension. - - The input path extension. - The default content type to return if any error occurs. - The path extension's MIME content type. - - - - Gets the path extension for a given MIME content type. - - The input MIME content type. - The default path extension to return if any error occurs. - The MIME content type's path extension. - - - - Creates an instance of the given type from the specified Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The requested type. - An newly created instance. - - - - Gets an HTML document from an Internet resource and saves it to the specified file. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The location of the file where you want to save the document. - - - - Gets an HTML document from an Internet resource and saves it to the specified file. - Proxy aware - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The location of the file where you want to save the document. - - - - - - Gets an HTML document from an Internet resource and saves it to the specified file. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The location of the file where you want to save the document. - The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. - - - - Gets an HTML document from an Internet resource and saves it to the specified file. Understands Proxies - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The location of the file where you want to save the document. - - The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. - - - - - Gets the cache file path for a specified url. - - The url fo which to retrieve the cache path. May not be null. - The cache file path. - - - - Gets an HTML document from an Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - A new HTML document. - - - - Gets an HTML document from an Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - Host to use for Proxy - Port the Proxy is on - User Id for Authentication - Password for Authentication - A new HTML document. - - - - Loads an HTML document from an Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. - A new HTML document. - - - - Loads an HTML document from an Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The HTTP method used to open the connection, such as GET, POST, PUT, or PROPFIND. - Proxy to use with this request - Credentials to use when authenticating - A new HTML document. - - - - Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The XmlTextWriter to which you want to save to. - - - - Creates an instance of the given type from the specified Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The URL that specifies the XSLT stylesheet to load. - An containing the namespace-qualified arguments used as input to the transform. - The requested type. - An newly created instance. - - - - Creates an instance of the given type from the specified Internet resource. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The URL that specifies the XSLT stylesheet to load. - An containing the namespace-qualified arguments used as input to the transform. - The requested type. - A file path where the temporary XML before transformation will be saved. Mostly used for debugging purposes. - An newly created instance. - - - - Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter, after an XSLT transformation. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". - The URL that specifies the XSLT stylesheet to load. - An XsltArgumentList containing the namespace-qualified arguments used as input to the transform. - The XmlTextWriter to which you want to save. - - - - Loads an HTML document from an Internet resource and saves it to the specified XmlTextWriter, after an XSLT transformation. - - The requested URL, such as "http://Myserver/Mypath/Myfile.asp". May not be null. - The URL that specifies the XSLT stylesheet to load. - An XsltArgumentList containing the namespace-qualified arguments used as input to the transform. - The XmlTextWriter to which you want to save. - A file path where the temporary XML before transformation will be saved. Mostly used for debugging purposes. - - - - Gets or Sets a value indicating if document encoding must be automatically detected. - - - - - Gets or sets the Encoding used to override the response stream from any web request - - - - - Gets or Sets a value indicating whether to get document only from the cache. - If this is set to true and document is not found in the cache, nothing will be loaded. - - - - - Gets or Sets the cache path. If null, no caching mechanism will be used. - - - - - Gets a value indicating if the last document was retrieved from the cache. - - - - - Gets the last request duration in milliseconds. - - - - - Gets the URI of the Internet resource that actually responded to the request. - - - - - Gets the last request status. - - - - - Gets or Sets the size of the buffer used for memory operations. - - - - - Gets or Sets a value indicating if cookies will be stored. - - - - - Gets or Sets the User Agent HTTP 1.1 header sent on any webrequest - - - - - Gets or Sets a value indicating whether the caching mechanisms should be used or not. - - - - - Represents the method that will handle the PostResponse event. - - - - - Represents the method that will handle the PreHandleDocument event. - - - - - Represents the method that will handle the PreRequest event. - - - - - Wraps getting AppDomain permissions - - - - - An interface for getting permissions of the running application - - - - - Checks to see if Registry access is available to the caller - - - - - - Checks to see if DNS information is available to the caller - - - - - - Checks to see if Registry access is available to the caller - - - - - - Checks to see if DNS information is available to the caller - - - - - - Represents a document with mixed code and text. ASP, ASPX, JSP, are good example of such documents. - - - - - Gets or sets the token representing code end. - - - - - Gets or sets the token representing code start. - - - - - Gets or sets the token representing code directive. - - - - - Gets or sets the token representing response write directive. - - - - - Creates a mixed code document instance. - - - - - Create a code fragment instances. - - The newly created code fragment instance. - - - - Create a text fragment instances. - - The newly created text fragment instance. - - - - Loads a mixed code document from a stream. - - The input stream. - - - - Loads a mixed code document from a stream. - - The input stream. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads a mixed code document from a stream. - - The input stream. - The character encoding to use. - - - - Loads a mixed code document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads a mixed code document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - The minimum buffer size. - - - - Loads a mixed code document from a file. - - The complete file path to be read. - - - - Loads a mixed code document from a file. - - The complete file path to be read. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads a mixed code document from a file. - - The complete file path to be read. - The character encoding to use. - - - - Loads a mixed code document from a file. - - The complete file path to be read. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads a mixed code document from a file. - - The complete file path to be read. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - The minimum buffer size. - - - - Loads the mixed code document from the specified TextReader. - - The TextReader used to feed the HTML data into the document. - - - - Loads a mixed document from a text - - The text to load. - - - - Saves the mixed document to the specified stream. - - The stream to which you want to save. - - - - Saves the mixed document to the specified stream. - - The stream to which you want to save. - The character encoding to use. - - - - Saves the mixed document to the specified file. - - The location of the file where you want to save the document. - - - - Saves the mixed document to the specified file. - - The location of the file where you want to save the document. - The character encoding to use. - - - - Saves the mixed document to the specified StreamWriter. - - The StreamWriter to which you want to save. - - - - Saves the mixed document to the specified TextWriter. - - The TextWriter to which you want to save. - - - - Gets the code represented by the mixed code document seen as a template. - - - - - Gets the list of code fragments in the document. - - - - - Gets the list of all fragments in the document. - - - - - Gets the encoding of the stream used to read the document. - - - - - Gets the list of text fragments in the document. - - - - - Represents a list of mixed code fragments. - - - - - Gets an enumerator that can iterate through the fragment list. - - - - - Appends a fragment to the list of fragments. - - The fragment to append. May not be null. - - - - Gets an enumerator that can iterate through the fragment list. - - - - - Prepends a fragment to the list of fragments. - - The fragment to append. May not be null. - - - - Remove a fragment from the list of fragments. If this fragment was not in the list, an exception will be raised. - - The fragment to remove. May not be null. - - - - Remove all fragments from the list. - - - - - Remove a fragment from the list of fragments, using its index in the list. - - The index of the fragment to remove. - - - - Gets the Document - - - - - Gets the number of fragments contained in the list. - - - - - Gets a fragment from the list using its index. - - - - - Represents a fragment enumerator. - - - - - Advances the enumerator to the next element of the collection. - - true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. - - - - Sets the enumerator to its initial position, which is before the first element in the collection. - - - - - Gets the current element in the collection. - - - - - Gets the current element in the collection. - - - - - A utility class to replace special characters by entities and vice-versa. - Follows HTML 4.0 specification found at http://www.w3.org/TR/html4/sgml/entities.html - - - - - Replace known entities by characters. - - The source text. - The result text. - - - - Clone and entitize an HtmlNode. This will affect attribute values and nodes' text. It will also entitize all child nodes. - - The node to entitize. - An entitized cloned node. - - - - Replace characters above 127 by entities. - - The source text. - The result text. - - - - Replace characters above 127 by entities. - - The source text. - If set to false, the function will not use known entities name. Default is true. - The result text. - - - - Replace characters above 127 by entities. - - The source text. - If set to false, the function will not use known entities name. Default is true. - If set to true, the [quote], [ampersand], [lower than] and [greather than] characters will be entitized. - The result text - - - - A collection of entities indexed by name. - - - - - A collection of entities indexed by value. - - - - - Represents the type of fragment in a mixed code document. - - - - - The fragment contains code. - - - - - The fragment contains text. - - - - - Represents the type of a node. - - - - - The root of a document. - - - - - An HTML element. - - - - - An HTML comment. - - - - - A text node is always the child of an element or a document node. - - - - - Represents an HTML navigator on an HTML document seen as a data store. - - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. - - The input stream. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. - - The input stream. - Indicates whether to look for byte order marks at the beginning of the stream. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. - - The input stream. - The character encoding to use. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the stream. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the stream. - The minimum buffer size. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a TextReader. - - The TextReader used to feed the HTML data into the document. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. - - The complete file path to be read. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. - - The complete file path to be read. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. - - The complete file path to be read. - The character encoding to use. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. - - The complete file path to be read. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Initializes a new instance of the HtmlNavigator and loads an HTML document from a file. - - The complete file path to be read. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the file. - The minimum buffer size. - - - - Creates a new HtmlNavigator positioned at the same node as this HtmlNavigator. - - A new HtmlNavigator object positioned at the same node as the original HtmlNavigator. - - - - Gets the value of the HTML attribute with the specified LocalName and NamespaceURI. - - The local name of the HTML attribute. - The namespace URI of the attribute. Unsupported with the HtmlNavigator implementation. - The value of the specified HTML attribute. String.Empty or null if a matching attribute is not found or if the navigator is not positioned on an element node. - - - - Returns the value of the namespace node corresponding to the specified local name. - Always returns string.Empty for the HtmlNavigator implementation. - - The local name of the namespace node. - Always returns string.Empty for the HtmlNavigator implementation. - - - - Determines whether the current HtmlNavigator is at the same position as the specified HtmlNavigator. - - The HtmlNavigator that you want to compare against. - true if the two navigators have the same position, otherwise, false. - - - - Moves to the same position as the specified HtmlNavigator. - - The HtmlNavigator positioned on the node that you want to move to. - true if successful, otherwise false. If false, the position of the navigator is unchanged. - - - - Moves to the HTML attribute with matching LocalName and NamespaceURI. - - The local name of the HTML attribute. - The namespace URI of the attribute. Unsupported with the HtmlNavigator implementation. - true if the HTML attribute is found, otherwise, false. If false, the position of the navigator does not change. - - - - Moves to the first sibling of the current node. - - true if the navigator is successful moving to the first sibling node, false if there is no first sibling or if the navigator is currently positioned on an attribute node. - - - - Moves to the first HTML attribute. - - true if the navigator is successful moving to the first HTML attribute, otherwise, false. - - - - Moves to the first child of the current node. - - true if there is a first child node, otherwise false. - - - - Moves the XPathNavigator to the first namespace node of the current element. - Always returns false for the HtmlNavigator implementation. - - An XPathNamespaceScope value describing the namespace scope. - Always returns false for the HtmlNavigator implementation. - - - - Moves to the node that has an attribute of type ID whose value matches the specified string. - - A string representing the ID value of the node to which you want to move. This argument does not need to be atomized. - true if the move was successful, otherwise false. If false, the position of the navigator is unchanged. - - - - Moves the XPathNavigator to the namespace node with the specified local name. - Always returns false for the HtmlNavigator implementation. - - The local name of the namespace node. - Always returns false for the HtmlNavigator implementation. - - - - Moves to the next sibling of the current node. - - true if the navigator is successful moving to the next sibling node, false if there are no more siblings or if the navigator is currently positioned on an attribute node. If false, the position of the navigator is unchanged. - - - - Moves to the next HTML attribute. - - - - - - Moves the XPathNavigator to the next namespace node. - Always returns falsefor the HtmlNavigator implementation. - - An XPathNamespaceScope value describing the namespace scope. - Always returns false for the HtmlNavigator implementation. - - - - Moves to the parent of the current node. - - true if there is a parent node, otherwise false. - - - - Moves to the previous sibling of the current node. - - true if the navigator is successful moving to the previous sibling node, false if there is no previous sibling or if the navigator is currently positioned on an attribute node. - - - - Moves to the root node to which the current node belongs. - - - - - Gets the base URI for the current node. - Always returns string.Empty in the case of HtmlNavigator implementation. - - - - - Gets the current HTML document. - - - - - Gets the current HTML node. - - - - - Gets a value indicating whether the current node has child nodes. - - - - - Gets a value indicating whether the current node has child nodes. - - - - - Gets a value indicating whether the current node is an empty element. - - - - - Gets the name of the current HTML node without the namespace prefix. - - - - - Gets the qualified name of the current node. - - - - - Gets the namespace URI (as defined in the W3C Namespace Specification) of the current node. - Always returns string.Empty in the case of HtmlNavigator implementation. - - - - - Gets the associated with this implementation. - - - - - Gets the type of the current node. - - - - - Gets the prefix associated with the current node. - Always returns string.Empty in the case of HtmlNavigator implementation. - - - - - Gets the text value of the current node. - - - - - Gets the xml:lang scope for the current node. - Always returns string.Empty in the case of HtmlNavigator implementation. - - - - - Represents an HTML text node. - - - - - Represents an HTML node. - - - - - Creates a new XPathNavigator object for navigating this HTML node. - - An XPathNavigator object. The XPathNavigator is positioned on the node from which the method was called. It is not positioned on the root of the document. - - - - Creates an XPathNavigator using the root of this document. - - - - - - Selects a list of nodes matching the expression. - - The XPath expression. - An containing a collection of nodes matching the query, or null if no node matched the XPath expression. - - - - Selects the first XmlNode that matches the XPath expression. - - The XPath expression. May not be null. - The first that matches the XPath query or a null reference if no matching node was found. - - - - Gets the name of a comment node. It is actually defined as '#comment'. - - - - - Gets the name of the document node. It is actually defined as '#document'. - - - - - Gets the name of a text node. It is actually defined as '#text'. - - - - - Gets a collection of flags that define specific behaviors for specific element nodes. - The table contains a DictionaryEntry list with the lowercase tag name as the Key, and a combination of HtmlElementFlags as the Value. - - - - - Initialize HtmlNode. Builds a list of all tags that have special allowances - - - - - Initializes HtmlNode, providing type, owner and where it exists in a collection - - - - - - - - Determines if an element node can be kept overlapped. - - The name of the element node to check. May not be null. - true if the name is the name of an element node that can be kept overlapped, false otherwise. - - - - Creates an HTML node from a string representing literal HTML. - - The HTML text. - The newly created node instance. - - - - Determines if an element node is a CDATA element node. - - The name of the element node to check. May not be null. - true if the name is the name of a CDATA element node, false otherwise. - - - - Determines if an element node is closed. - - The name of the element node to check. May not be null. - true if the name is the name of a closed element node, false otherwise. - - - - Determines if an element node is defined as empty. - - The name of the element node to check. May not be null. - true if the name is the name of an empty element node, false otherwise. - - - - Determines if a text corresponds to the closing tag of an node that can be kept overlapped. - - The text to check. May not be null. - true or false. - - - - Returns a collection of all ancestor nodes of this element. - - - - - - Get Ancestors with matching name - - - - - - - Returns a collection of all ancestor nodes of this element. - - - - - - Gets all anscestor nodes and the current node - - - - - - - Adds the specified node to the end of the list of children of this node. - - The node to add. May not be null. - The node added. - - - - Adds the specified node to the end of the list of children of this node. - - The node list to add. May not be null. - - - - Gets all Attributes with name - - - - - - - Creates a duplicate of the node - - - - - - Creates a duplicate of the node and changes its name at the same time. - - The new name of the cloned node. May not be null. - The cloned node. - - - - Creates a duplicate of the node and changes its name at the same time. - - The new name of the cloned node. May not be null. - true to recursively clone the subtree under the specified node; false to clone only the node itself. - The cloned node. - - - - Creates a duplicate of the node. - - true to recursively clone the subtree under the specified node; false to clone only the node itself. - The cloned node. - - - - Creates a duplicate of the node and the subtree under it. - - The node to duplicate. May not be null. - - - - Creates a duplicate of the node. - - The node to duplicate. May not be null. - true to recursively clone the subtree under the specified node, false to clone only the node itself. - - - - Gets all Descendant nodes for this node and each of child nodes - - - - - - Returns a collection of all descendant nodes of this element, in document order - - - - - - Gets all Descendant nodes in enumerated list - - - - - - Get all descendant nodes with matching name - - - - - - - Returns a collection of all descendant nodes of this element, in document order - - - - - - Gets all descendant nodes including this node - - - - - - - Gets first generation child node matching name - - - - - - - Gets matching first generation child nodes matching name - - - - - - - Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. - - The name of the attribute to get. May not be null. - The default value to return if not found. - The value of the attribute if found, the default value if not found. - - - - Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. - - The name of the attribute to get. May not be null. - The default value to return if not found. - The value of the attribute if found, the default value if not found. - - - - Helper method to get the value of an attribute of this node. If the attribute is not found, the default value will be returned. - - The name of the attribute to get. May not be null. - The default value to return if not found. - The value of the attribute if found, the default value if not found. - - - - Inserts the specified node immediately after the specified reference node. - - The node to insert. May not be null. - The node that is the reference node. The newNode is placed after the refNode. - The node being inserted. - - - - Inserts the specified node immediately before the specified reference node. - - The node to insert. May not be null. - The node that is the reference node. The newChild is placed before this node. - The node being inserted. - - - - Adds the specified node to the beginning of the list of children of this node. - - The node to add. May not be null. - The node added. - - - - Adds the specified node list to the beginning of the list of children of this node. - - The node list to add. May not be null. - - - - Removes node from parent collection - - - - - Removes all the children and/or attributes of the current node. - - - - - Removes all the children of the current node. - - - - - Removes the specified child node. - - The node being removed. May not be null. - The node removed. - - - - Removes the specified child node. - - The node being removed. May not be null. - true to keep grand children of the node, false otherwise. - The node removed. - - - - Replaces the child node oldChild with newChild node. - - The new node to put in the child list. - The node being replaced in the list. - The node replaced. - - - - Helper method to set the value of an attribute of this node. If the attribute is not found, it will be created automatically. - - The name of the attribute to set. May not be null. - The value for the attribute. - The corresponding attribute instance. - - - - Saves all the children of the node to the specified TextWriter. - - The TextWriter to which you want to save. - - - - Saves all the children of the node to a string. - - The saved string. - - - - Saves the current node to the specified TextWriter. - - The TextWriter to which you want to save. - - - - Saves the current node to the specified XmlWriter. - - The XmlWriter to which you want to save. - - - - Saves the current node to a string. - - The saved string. - - - - Gets the collection of HTML attributes for this node. May not be null. - - - - - Gets all the children of the node. - - - - - Gets a value indicating if this node has been closed or not. - - - - - Gets the collection of HTML attributes for the closing tag. May not be null. - - - - - Gets the first child of the node. - - - - - Gets a value indicating whether the current node has any attributes. - - - - - Gets a value indicating whether this node has any child nodes. - - - - - Gets a value indicating whether the current node has any attributes on the closing tag. - - - - - Gets or sets the value of the 'id' HTML attribute. The document must have been parsed using the OptionUseIdAttribute set to true. - - - - - Gets or Sets the HTML between the start and end tags of the object. - - - - - Gets or Sets the text between the start and end tags of the object. - - - - - Gets the last child of the node. - - - - - Gets the line number of this node in the document. - - - - - Gets the column number of this node in the document. - - - - - Gets or sets this node's name. - - - - - Gets the HTML node immediately following this element. - - - - - Gets the type of this node. - - - - - The original unaltered name of the tag - - - - - Gets or Sets the object and its content in HTML. - - - - - Gets the to which this node belongs. - - - - - Gets the parent of this node (for nodes that can have parents). - - - - - Gets the node immediately preceding this node. - - - - - Gets the stream position of this node in the document, relative to the start of the document. - - - - - Gets a valid XPath string that points to this node - - - - - Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. - - - - - Gets or Sets the object and its content in HTML. - - - - - Gets or Sets the text of the node. - - - - - Represents a complete HTML document. - - - - - Adds Debugging attributes to node. Default is false. - - - - - Defines if closing for non closed nodes must be done at the end or directly in the document. - Setting this to true can actually change how browsers render the page. Default is false. - - - - - Defines if non closed nodes will be checked at the end of parsing. Default is true. - - - - - Defines if a checksum must be computed for the document while parsing. Default is false. - - - - - Defines the default stream encoding to use. Default is System.Text.Encoding.Default. - - - - - Defines if source text must be extracted while parsing errors. - If the document has a lot of errors, or cascading errors, parsing performance can be dramatically affected if set to true. - Default is false. - - - - - Defines the maximum length of source text or parse errors. Default is 100. - - - - - Defines if LI, TR, TH, TD tags must be partially fixed when nesting errors are detected. Default is false. - - - - - Defines if output must conform to XML, instead of HTML. - - - - - Defines if attribute value output must be optimized (not bound with double quotes if it is possible). Default is false. - - - - - Defines if name must be output with it's original case. Useful for asp.net tags and attributes - - - - - Defines if name must be output in uppercase. Default is false. - - - - - Defines if declared encoding must be read from the document. - Declared encoding is determined using the meta http-equiv="content-type" content="text/html;charset=XXXXX" html node. - Default is true. - - - - - Defines the name of a node that will throw the StopperNodeException when found as an end node. Default is null. - - - - - Defines if the 'id' attribute must be specifically used. Default is true. - - - - - Defines if empty nodes must be written as closed during output. Default is false. - - - - - Creates an instance of an HTML document. - - - - - Gets a valid XML name. - - Any text. - A string that is a valid XML name. - - - - Applies HTML encoding to a specified string. - - The input string to encode. May not be null. - The encoded string. - - - - Determines if the specified character is considered as a whitespace character. - - The character to check. - true if if the specified character is considered as a whitespace character. - - - - Creates an HTML attribute with the specified name. - - The name of the attribute. May not be null. - The new HTML attribute. - - - - Creates an HTML attribute with the specified name. - - The name of the attribute. May not be null. - The value of the attribute. - The new HTML attribute. - - - - Creates an HTML comment node. - - The new HTML comment node. - - - - Creates an HTML comment node with the specified comment text. - - The comment text. May not be null. - The new HTML comment node. - - - - Creates an HTML element node with the specified name. - - The qualified name of the element. May not be null. - The new HTML node. - - - - Creates an HTML text node. - - The new HTML text node. - - - - Creates an HTML text node with the specified text. - - The text of the node. May not be null. - The new HTML text node. - - - - Detects the encoding of an HTML stream. - - The input stream. May not be null. - The detected encoding. - - - - Detects the encoding of an HTML text provided on a TextReader. - - The TextReader used to feed the HTML. May not be null. - The detected encoding. - - - - Detects the encoding of an HTML text. - - The input html text. May not be null. - The detected encoding. - - - - Gets the HTML node with the specified 'id' attribute value. - - The attribute id to match. May not be null. - The HTML node with the matching id or null if not found. - - - - Loads an HTML document from a stream. - - The input stream. - - - - Loads an HTML document from a stream. - - The input stream. - Indicates whether to look for byte order marks at the beginning of the stream. - - - - Loads an HTML document from a stream. - - The input stream. - The character encoding to use. - - - - Loads an HTML document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the stream. - - - - Loads an HTML document from a stream. - - The input stream. - The character encoding to use. - Indicates whether to look for byte order marks at the beginning of the stream. - The minimum buffer size. - - - - Loads the HTML document from the specified TextReader. - - The TextReader used to feed the HTML data into the document. May not be null. - - - - Loads the HTML document from the specified string. - - String containing the HTML document to load. May not be null. - - - - Saves the HTML document to the specified stream. - - The stream to which you want to save. - - - - Saves the HTML document to the specified stream. - - The stream to which you want to save. May not be null. - The character encoding to use. May not be null. - - - - Saves the HTML document to the specified StreamWriter. - - The StreamWriter to which you want to save. - - - - Saves the HTML document to the specified TextWriter. - - The TextWriter to which you want to save. May not be null. - - - - Saves the HTML document to the specified XmlWriter. - - The XmlWriter to which you want to save. - - - - Detects the encoding of an HTML document from a file first, and then loads the file. - - The complete file path to be read. - - - - Detects the encoding of an HTML document from a file first, and then loads the file. - - The complete file path to be read. May not be null. - true to detect encoding, false otherwise. - - - - Detects the encoding of an HTML file. - - Path for the file containing the HTML document to detect. May not be null. - The detected encoding. - - - - Loads an HTML document from a file. - - The complete file path to be read. May not be null. - - - - Loads an HTML document from a file. - - The complete file path to be read. May not be null. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads an HTML document from a file. - - The complete file path to be read. May not be null. - The character encoding to use. May not be null. - - - - Loads an HTML document from a file. - - The complete file path to be read. May not be null. - The character encoding to use. May not be null. - Indicates whether to look for byte order marks at the beginning of the file. - - - - Loads an HTML document from a file. - - The complete file path to be read. May not be null. - The character encoding to use. May not be null. - Indicates whether to look for byte order marks at the beginning of the file. - The minimum buffer size. - - - - Saves the mixed document to the specified file. - - The location of the file where you want to save the document. - - - - Saves the mixed document to the specified file. - - The location of the file where you want to save the document. May not be null. - The character encoding to use. May not be null. - - - - Creates a new XPathNavigator object for navigating this HTML document. - - An XPathNavigator object. The XPathNavigator is positioned on the root of the document. - - - - Gets the document CRC32 checksum if OptionComputeChecksum was set to true before parsing, 0 otherwise. - - - - - Gets the document's declared encoding. - Declared encoding is determined using the meta http-equiv="content-type" content="text/html;charset=XXXXX" html node. - - - - - Gets the root node of the document. - - - - - Gets the document's output encoding. - - - - - Gets a list of parse errors found in the document. - - - - - Gets the remaining text. - Will always be null if OptionStopperNodeName is null. - - - - - Gets the offset of Remainder in the original Html text. - If OptionStopperNodeName is null, this will return the length of the original Html text. - - - - - Gets the document's stream encoding. - - - - - Represents an HTML attribute. - - - - - Compares the current instance with another attribute. Comparison is based on attributes' name. - - An attribute to compare with this instance. - A 32-bit signed integer that indicates the relative order of the names comparison. - - - - Creates a duplicate of this attribute. - - The cloned attribute. - - - - Removes this attribute from it's parents collection - - - - - Gets the line number of this attribute in the document. - - - - - Gets the column number of this attribute in the document. - - - - - Gets the qualified name of the attribute. - - - - - Name of attribute with original case - - - - - Gets the HTML document to which this attribute belongs. - - - - - Gets the HTML node to which this attribute belongs. - - - - - Specifies what type of quote the data should be wrapped in - - - - - Gets the stream position of this attribute in the document, relative to the start of the document. - - - - - Gets or sets the value of the attribute. - - - - - Gets a valid XPath string that points to this Attribute - - - - - An Enum representing different types of Quotes used for surrounding attribute values - - - - - A single quote mark ' - - - - - A double quote mark " - - - - - Represents a combined list and collection of HTML nodes. - - - - - Initialize the HtmlNodeCollection with the base parent node - - The base node of the collection - - - - Add node to the collection - - - - - - Clears out the collection of HtmlNodes. Removes each nodes reference to parentnode, nextnode and prevnode - - - - - Gets existence of node in collection - - - - - - - Copy collection to array - - - - - - - Get Enumerator - - - - - - Get Explicit Enumerator - - - - - - Get index of node - - - - - - - Insert node at index - - - - - - - Remove node - - - - - - - Remove at index - - - - - - Get first instance of node in supplied collection - - - - - - - - Add node to the end of the collection - - - - - - Get first instance of node with name - - - - - - - Get index of node - - - - - - - Add node to the beginning of the collection - - - - - - Remove node at index - - - - - - - Replace node at index - - - - - - - Get all node descended from this collection - - - - - - Get all node descended from this collection with matching name - - - - - - Gets all first generation elements in collection - - - - - - Gets all first generation elements matching name - - - - - - - All first generation nodes in collection - - - - - - Gets a given node from the list. - - - - - Get node with tag name - - - - - - - Gets the number of elements actually contained in the list. - - - - - Is collection read only - - - - - Gets the node at the specified index. - - - - - Represents an HTML comment. - - - - - Gets or Sets the comment text of the node. - - - - - Gets or Sets the HTML between the start and end tags of the object. In the case of a text node, it is equals to OuterHtml. - - - - - Gets or Sets the object and its content in HTML. - - - - - Flags that describe the behavior of an Element node. - - - - - The node is a CDATA node. - - - - - The node is empty. META or IMG are example of such nodes. - - - - - The node will automatically be closed during parsing. - - - - - The node can overlap. - - - - - Represents the type of parsing error. - - - - - A tag was not closed. - - - - - A tag was not opened. - - - - - There is a charset mismatch between stream and declared (META) encoding. - - - - - An end tag was not required. - - - - - An end tag is invalid at this position. - - - - - A utility class to compute CRC32. - - - - - Compute a checksum for a given array of bytes. - - The array of bytes to compute the checksum for. - The computed checksum. - - - - Compute a checksum for a given string. - - The string to compute the checksum for. - The computed checksum. - - - - Represents a fragment of text in a mixed code document. - - - - - Gets the fragment text. - - - - - Represents a combined list and collection of HTML nodes. - - - - - Adds supplied item to collection - - - - - - Explicit clear - - - - - Retreives existence of supplied item - - - - - - - Copies collection to array - - - - - - - Get Explicit enumerator - - - - - - Explicit non-generic enumerator - - - - - - Retrieves the index for the supplied item, -1 if not found - - - - - - - Inserts given item into collection at supplied index - - - - - - - Explicit collection remove - - - - - - - Removes the attribute at the specified index. - - The index of the attribute to remove. - - - - Adds a new attribute to the collection with the given values - - - - - - - Inserts the specified attribute as the last attribute in the collection. - - The attribute to insert. May not be null. - The appended attribute. - - - - Creates and inserts a new attribute as the last attribute in the collection. - - The name of the attribute to insert. - The appended attribute. - - - - Creates and inserts a new attribute as the last attribute in the collection. - - The name of the attribute to insert. - The value of the attribute to insert. - The appended attribute. - - - - Checks for existance of attribute with given name - - - - - - - Inserts the specified attribute as the first node in the collection. - - The attribute to insert. May not be null. - The prepended attribute. - - - - Removes a given attribute from the list. - - The attribute to remove. May not be null. - - - - Removes an attribute from the list, using its name. If there are more than one attributes with this name, they will all be removed. - - The attribute's name. May not be null. - - - - Remove all attributes in the list. - - - - - Returns all attributes with specified name. Handles case insentivity - - Name of the attribute - - - - - Removes all attributes from the collection - - - - - Clears the attribute collection - - - - - Gets a given attribute from the list using its name. - - - - - Gets the number of elements actually contained in the list. - - - - - Gets readonly status of colelction - - - - - Gets the attribute at the specified index. - - - - - Represents an exception thrown by the HtmlWeb utility class. - - - - - Creates an instance of the HtmlWebException. - - The exception's message. - - - - Represents a parsing error found during document parsing. - - - - - Gets the type of error. - - - - - Gets the line number of this error in the document. - - - - - Gets the column number of this error in the document. - - - - - Gets a description for the error. - - - - - Gets the the full text of the line containing the error. - - - - - Gets the absolute stream position of this error in the document, relative to the start of the document. - - - - diff --git a/BuildTools/NOBuildTools.sln b/BuildTools/NOBuildTools.sln deleted file mode 100644 index 91cc28192..000000000 --- a/BuildTools/NOBuildTools.sln +++ /dev/null @@ -1,66 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOBuildTools.SearchAndReplace", "SearchAndReplace\NOBuildTools.SearchAndReplace.csproj", "{CA71246E-CEB7-4399-B7C3-C5A18B5CC801}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOBuildTools.SourceUpdater", "SourceUpdater\NOBuildTools.SourceUpdater.csproj", "{FE3B95E3-990A-4F82-92D5-6C26046C3EC2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOBuildTools.VersionUpdater", "VersionUpdater\NOBuildTools.VersionUpdater.csproj", "{3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NOBuildTools.ReferenceAnalyzer", "ReferenceAnalyzer\NOBuildTools.ReferenceAnalyzer.csproj", "{C6CD402C-0B5B-45F2-9D96-4F670D379124}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Debug|Any CPU.ActiveCfg = Debug|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Debug|x86.ActiveCfg = Debug|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Debug|x86.Build.0 = Debug|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Release|Any CPU.ActiveCfg = Release|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Release|Mixed Platforms.Build.0 = Release|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Release|x86.ActiveCfg = Release|x86 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801}.Release|x86.Build.0 = Release|x86 - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Debug|x86.ActiveCfg = Debug|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Release|Any CPU.Build.0 = Release|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2}.Release|x86.ActiveCfg = Release|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Debug|x86.ActiveCfg = Debug|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Release|Any CPU.Build.0 = Release|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1}.Release|x86.ActiveCfg = Release|Any CPU - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Debug|Any CPU.ActiveCfg = Debug|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Debug|Mixed Platforms.Build.0 = Debug|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Debug|x86.ActiveCfg = Debug|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Debug|x86.Build.0 = Debug|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Release|Any CPU.ActiveCfg = Release|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Release|Mixed Platforms.Build.0 = Release|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Release|x86.ActiveCfg = Release|x86 - {C6CD402C-0B5B-45F2-9D96-4F670D379124}.Release|x86.Build.0 = Release|x86 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/BuildTools/ReferenceAnalyzer/ExceptionDisplayer.cs b/BuildTools/ReferenceAnalyzer/ExceptionDisplayer.cs deleted file mode 100644 index 7ee37edf1..000000000 --- a/BuildTools/ReferenceAnalyzer/ExceptionDisplayer.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows.Forms; -using System.Text; - -namespace NOBuildTools.ReferenceAnalyzer -{ - /// - /// Exception display helper - /// - internal static class ExceptionDisplayer - { - /// - /// Shows exception as string message box to the user - /// - /// modal parent - /// exception as any - public static void ShowException(IWin32Window parent, Exception exception) - { - string message = "An error is occured." + Environment.NewLine; - string detailsMessage = "Details: " + Environment.NewLine; - - while (null != exception) - { - detailsMessage += "Exception: " + exception.GetType().Name + Environment.NewLine; - detailsMessage += "Exception: " + exception.Message + Environment.NewLine; - - exception = exception.InnerException; - } - - MessageBox.Show(parent, message + detailsMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } -} diff --git a/BuildTools/ReferenceAnalyzer/Form1.Designer.cs b/BuildTools/ReferenceAnalyzer/Form1.Designer.cs deleted file mode 100644 index b8409feb1..000000000 --- a/BuildTools/ReferenceAnalyzer/Form1.Designer.cs +++ /dev/null @@ -1,117 +0,0 @@ -namespace NOBuildTools.ReferenceAnalyzer -{ - partial class Form1 - { - /// - /// Erforderliche Designervariable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Verwendete Ressourcen bereinigen. - /// - /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Vom Windows Form-Designer generierter Code - - /// - /// Erforderliche Methode für die Designerunterstützung. - /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. - /// - private void InitializeComponent() - { - this.LabelFile = new System.Windows.Forms.Label(); - this.ButttonChooseFile = new System.Windows.Forms.Button(); - this.TextBoxFile = new System.Windows.Forms.TextBox(); - this.ButtonStart = new System.Windows.Forms.Button(); - this.RichTextBoxLog = new System.Windows.Forms.RichTextBox(); - this.SuspendLayout(); - // - // LabelFile - // - this.LabelFile.AutoSize = true; - this.LabelFile.Location = new System.Drawing.Point(20, 28); - this.LabelFile.Name = "LabelFile"; - this.LabelFile.Size = new System.Drawing.Size(58, 13); - this.LabelFile.TabIndex = 6; - this.LabelFile.Text = "Output File"; - // - // ButttonChooseFile - // - this.ButttonChooseFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButttonChooseFile.Location = new System.Drawing.Point(459, 23); - this.ButttonChooseFile.Name = "ButttonChooseFile"; - this.ButttonChooseFile.Size = new System.Drawing.Size(40, 22); - this.ButttonChooseFile.TabIndex = 5; - this.ButttonChooseFile.Text = "..."; - this.ButttonChooseFile.UseVisualStyleBackColor = true; - this.ButttonChooseFile.Click += new System.EventHandler(this.ButttonChooseFile_Click); - // - // TextBoxFile - // - this.TextBoxFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.TextBoxFile.Location = new System.Drawing.Point(83, 25); - this.TextBoxFile.Name = "TextBoxFile"; - this.TextBoxFile.Size = new System.Drawing.Size(366, 20); - this.TextBoxFile.TabIndex = 4; - // - // ButtonStart - // - this.ButtonStart.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonStart.Location = new System.Drawing.Point(23, 59); - this.ButtonStart.Name = "ButtonStart"; - this.ButtonStart.Size = new System.Drawing.Size(476, 23); - this.ButtonStart.TabIndex = 8; - this.ButtonStart.Text = "Start"; - this.ButtonStart.UseVisualStyleBackColor = true; - this.ButtonStart.Click += new System.EventHandler(this.ButtonStart_Click); - // - // RichTextBoxLog - // - this.RichTextBoxLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.RichTextBoxLog.Location = new System.Drawing.Point(23, 109); - this.RichTextBoxLog.Name = "RichTextBoxLog"; - this.RichTextBoxLog.ReadOnly = true; - this.RichTextBoxLog.Size = new System.Drawing.Size(476, 282); - this.RichTextBoxLog.TabIndex = 7; - this.RichTextBoxLog.Text = ""; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(526, 416); - this.Controls.Add(this.ButtonStart); - this.Controls.Add(this.RichTextBoxLog); - this.Controls.Add(this.LabelFile); - this.Controls.Add(this.ButttonChooseFile); - this.Controls.Add(this.TextBoxFile); - this.Name = "Form1"; - this.Text = "NOBuildTools.ReferenceAnalyzer"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label LabelFile; - private System.Windows.Forms.Button ButttonChooseFile; - private System.Windows.Forms.TextBox TextBoxFile; - private System.Windows.Forms.Button ButtonStart; - private System.Windows.Forms.RichTextBox RichTextBoxLog; - } -} - diff --git a/BuildTools/ReferenceAnalyzer/Form1.cs b/BuildTools/ReferenceAnalyzer/Form1.cs deleted file mode 100644 index 9d969a3f9..000000000 --- a/BuildTools/ReferenceAnalyzer/Form1.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.IO; -using System.Drawing; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using System.Text; -using System.Windows.Forms; - -namespace NOBuildTools.ReferenceAnalyzer -{ - /// - /// Main form in the application - /// - public partial class Form1 : Form - { - #region - - /// - /// Creates an instance of the class - /// - public Form1() - { - InitializeComponent(); - } - - #endregion - - #region Methods - - private void LogAction(string message) - { - if (!String.IsNullOrWhiteSpace(message)) - RichTextBoxLog.Text = message + Environment.NewLine + RichTextBoxLog.Text; - this.Refresh(); - Application.DoEvents(); // not nice but okay for this simple one - } - - #endregion - - #region Trigger - - private void ButttonChooseFile_Click(object sender, EventArgs e) - { - SaveFileDialog dialog = new SaveFileDialog(); - dialog.Filter = "Xml Files(*.xml)|*.xml"; - if (DialogResult.OK == dialog.ShowDialog(this)) - TextBoxFile.Text = dialog.FileName; - } - - private void ButtonStart_Click(object sender, EventArgs e) - { - try - { - if (String.IsNullOrWhiteSpace(TextBoxFile.Text)) - return; - RichTextBoxLog.Clear(); - XDocument document = Parser.ParseReference(LogAction); - if (File.Exists(TextBoxFile.Text)) - File.Delete(TextBoxFile.Text); - document.Save(TextBoxFile.Text); - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - #endregion - } -} diff --git a/BuildTools/ReferenceAnalyzer/Form1.resx b/BuildTools/ReferenceAnalyzer/Form1.resx deleted file mode 100644 index 1af7de150..000000000 --- a/BuildTools/ReferenceAnalyzer/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/ReferenceAnalyzer/NOBuildTools.ReferenceAnalyzer.csproj b/BuildTools/ReferenceAnalyzer/NOBuildTools.ReferenceAnalyzer.csproj deleted file mode 100644 index 7ab4d1607..000000000 --- a/BuildTools/ReferenceAnalyzer/NOBuildTools.ReferenceAnalyzer.csproj +++ /dev/null @@ -1,91 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {C6CD402C-0B5B-45F2-9D96-4F670D379124} - WinExe - Properties - NOBuildTools.ReferenceAnalyzer - NOBuildTools.ReferenceAnalyzer - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\Lib\HtmlAgilityPack.dll - - - - - - - - - - - - - - - Form - - - Form1.cs - - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - \ No newline at end of file diff --git a/BuildTools/ReferenceAnalyzer/Parser.cs b/BuildTools/ReferenceAnalyzer/Parser.cs deleted file mode 100644 index 3a07d296f..000000000 --- a/BuildTools/ReferenceAnalyzer/Parser.cs +++ /dev/null @@ -1,1803 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml; -using System.Xml.Linq; -using System.Text; -using HtmlAgilityPack; - -namespace NOBuildTools.ReferenceAnalyzer -{ - /// - /// Progress log action handler - /// - /// log action message - public delegate void LogAction(string message); - - internal static class Parser - { - #region Fields - - private static string _rootAdress = "http://msdn.microsoft.com/en-us"; - - private static string _excelTypesRelative = "/library/office/ff194068.aspx"; - private static string _excelEnumsRelative = "/library/office/ff838815.aspx"; - - private static string _accessTypesRelative = "/library/office/ff192120.aspx"; - private static string _accessEnumsRelative = "/library/office/jj713155.aspx"; - private static string _accessConstantsRelative = "/library/office/jj713057.aspx"; - - private static string _officeTypesRelative = "/library/office/ff861484.aspx"; - private static string _officeEnumsRelative = "/library/office/jj229676.aspx"; - - private static string _outlookTypesRelative = "/library/office/ff866465.aspx"; - private static string _outlookEnumsRelative = "/library/office/ff860961.aspx"; - - private static string _powerPointTypesRelative = "/library/office/ff743835.aspx"; - private static string _powerPointEnumsRelative = "/library/office/ff744042.aspx"; - - private static string _projectTypesRelative = "/library/office/ff920539(v=office.14).aspx"; - private static string _projectEnumsRelative = "/library/office/ff920788(v=office.14).aspx"; - - private static string _visioTypesRelative = "/library/ff765377(v=office.14).aspx"; - private static string _visioEnumsRelative = "/library/ff769457(v=office.14).aspx"; - - private static string _wordTypesRelative = "/library/office/ff837519.aspx"; - private static string _wordEnumsRelative = "/library/office/dn353221.aspx"; - - #endregion - - #region Parse Word - - /// - /// Parse Word Docu pages - /// - /// document to fill - /// progress handler - internal static void ParseWord(XDocument document, LogAction func) - { - XElement WordNode = new XElement("Word"); - (document.FirstNode as XElement).Add(WordNode); - ParseWordTypes(WordNode, func); - ParseWordEnums(WordNode, func); - ParseWordTypesMembers(WordNode, func); - } - - private static void ParseWordTypes(XElement excelNode, LogAction func) - { - func("Parse Word Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _wordTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Word Types recieved", counter)); - } - - private static void ParseWordEnums(XElement excelNode, LogAction func) - { - func("Parse Word Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _wordEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} Word Enums recieved", counter)); - } - - private static void ParseWordTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Word Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseOfficeTypeMembers(item, func); - } - } - - private static void ParseWordTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseWordTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseWordTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseWordTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseWordTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseWordTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseWordTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse Project - - private static void ParseProjectTypes(XElement excelNode, LogAction func) - { - func("Parse Project Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _projectTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Project Types recieved", counter)); - } - - private static void ParseProjectEnums(XElement excelNode, LogAction func) - { - func("Parse Project Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _projectEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} Project Enums recieved", counter)); - } - - private static void ParseProjectTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Project Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseOfficeTypeMembers(item, func); - } - } - - private static void ParseProjectTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseProjectTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseProjectTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseProjectTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseProjectTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseProjectTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseProjectTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse PowerPoint - - /// - /// Parse PPoint Docu pages - /// - /// document to fill - /// progress handler - internal static void ParsePowerPoint(XDocument document, LogAction func) - { - XElement pPointNode = new XElement("PowerPoint"); - (document.FirstNode as XElement).Add(pPointNode); - ParsePowerPointTypes(pPointNode, func); - ParsePowerPointEnums(pPointNode, func); - ParsePowerPointTypesMembers(pPointNode, func); - } - - private static void ParsePowerPointTypes(XElement excelNode, LogAction func) - { - func("Parse PowerPoint Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _powerPointTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} PowerPoint Types recieved", counter)); - } - - private static void ParsePowerPointEnums(XElement excelNode, LogAction func) - { - func("Parse PowerPoint Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _powerPointEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} PowerPoint Enums recieved", counter)); - } - - private static void ParsePowerPointTypesMembers(XElement typeNode, LogAction func) - { - func("Parse PowerPoint Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseOfficeTypeMembers(item, func); - } - } - - private static void ParsePowerPointTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParsePowerPointTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParsePowerPointTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParsePowerPointTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParsePowerPointTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParsePowerPointTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParsePowerPointTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse Outlook - - /// - /// Parse Outlook Docu pages - /// - /// document to fill - /// progress handler - internal static void ParseOutlook(XDocument document, LogAction func) - { - XElement outlookNode = new XElement("Outlook"); - (document.FirstNode as XElement).Add(outlookNode); - ParseOutlookTypes(outlookNode, func); - ParseOutlookEnums(outlookNode, func); - ParseOutlookTypesMembers(outlookNode, func); - } - - private static void ParseOutlookTypes(XElement excelNode, LogAction func) - { - func("Parse Outlook Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _outlookTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Outlook Types recieved", counter)); - } - - private static void ParseOutlookEnums(XElement excelNode, LogAction func) - { - func("Parse Outlook Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _outlookEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} Outlook Enums recieved", counter)); - } - - private static void ParseOutlookTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Outlook Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseOfficeTypeMembers(item, func); - } - } - - private static void ParseOutlookTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOutlookTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOutlookTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOutlookTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseOutlookTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseOutlookTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseOutlookTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse Office - - /// - /// Parse Common Office Docu pages - /// - /// document to fill - /// progress handler - internal static void ParseOffice(XDocument document, LogAction func) - { - XElement officeNode = new XElement("Office"); - (document.FirstNode as XElement).Add(officeNode); - ParseOfficeTypes(officeNode, func); - ParseOfficeEnums(officeNode, func); - ParseOfficeTypesMembers(officeNode, func); - } - - private static void ParseOfficeTypes(XElement excelNode, LogAction func) - { - func("Parse Office Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _officeTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Office Types recieved", counter)); - } - - private static void ParseOfficeEnums(XElement excelNode, LogAction func) - { - func("Parse Office Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _officeEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} Office Enums recieved", counter)); - } - - private static void ParseOfficeTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Office Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseOfficeTypeMembers(item, func); - } - } - - private static void ParseOfficeTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOfficeTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOfficeTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseOfficeTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseOfficeTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseOfficeTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseOfficeTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse Excel - - /// - /// Parse Excel Docu pages - /// - /// document to fill - /// progress handler - internal static void ParseExcel(XDocument document, LogAction func) - { - XElement excelNode = new XElement("Excel"); - (document.FirstNode as XElement).Add(excelNode); - ParseExcelTypes(excelNode, func); - ParseExcelEnums(excelNode, func); - ParseExcelTypesMembers(excelNode, func); - } - - private static void ParseExcelTypes(XElement excelNode, LogAction func) - { - func("Parse Excel Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _excelTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Excel Types recieved", counter)); - } - - private static void ParseExcelEnums(XElement excelNode, LogAction func) - { - func("Parse Excel Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _excelEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - - } - - } - - func(String.Format("{0} Excel Enums recieved", counter)); - } - - private static void ParseExcelTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Excel Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseExcelTypeMembers(item, func); - } - } - - private static void ParseExcelTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseExcelTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseExcelTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseExcelTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseExcelTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseExcelTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseExcelTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - #endregion - - #region Parse Access - - /// - /// Parse Access Docu pages - /// - /// document to fill - /// progress handler - internal static void ParseAccess(XDocument document, LogAction func) - { - XElement accessNode = new XElement("Access"); - (document.FirstNode as XElement).Add(accessNode); - ParseAccessTypes(accessNode, func); - ParseAccessEnums(accessNode, func); - ParseAccessConstants(accessNode, func); - ParseAccessTypesMembers(accessNode, func); - } - - private static void ParseAccessTypes(XElement excelNode, LogAction func) - { - func("Parse Access Types"); - - XElement rootNode = new XElement("Types"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _accessTypesRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.EndsWith(" Object", StringComparison.InvariantCultureIgnoreCase)) - { - name = name.Substring(0, name.Length - " Object".Length); - rootNode.Add(new XElement("Type", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - } - - func(String.Format("{0} Access Types recieved", counter)); - } - - private static void ParseAccessEnums(XElement excelNode, LogAction func) - { - func("Parse Access Enums"); - - XElement rootNode = new XElement("Enums"); - excelNode.Add(rootNode); - - int counter = 0; - string excelRootReferencePage = _rootAdress + _accessEnumsRelative; - using (var client = new System.Net.WebClient()) - { - string pageContent = DownloadPage(client, excelRootReferencePage); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.Substring(0, name.Length - " Enumeration".Length); - - if (!name.Equals("OldConstants", StringComparison.InvariantCultureIgnoreCase)) - { - rootNode.Add(new XElement("Enum", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - counter++; - } - } - } - - } - - } - - func(String.Format("{0} Access Enums recieved", counter)); - } - - private static void ParseAccessTypesMembers(XElement typeNode, LogAction func) - { - func("Parse Access Type Members"); - foreach (XElement item in typeNode.Element("Types").Elements("Type")) - { - ParseAccessTypeMembers(item, func); - } - } - - private static void ParseAccessTypeMembers(XElement typeNode, LogAction func) - { - XElement propsNode = new XElement("Properties"); - XElement methodsNode = new XElement("Methods"); - XElement eventsNode = new XElement("Events"); - typeNode.Add(propsNode); - typeNode.Add(methodsNode); - typeNode.Add(eventsNode); - - using (var client = new System.Net.WebClient()) - { - string pageLink = typeNode.Element("Link").Value; - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - name = name.ToLower().Trim(); - switch (name) - { - case "properties": - propsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseAccessTypeProperties(propsNode, func); - break; - case "methods": - methodsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseAccessTypeMethods(methodsNode, func); - break; - case "events": - eventsNode.Add(new XAttribute("Link", XmlConvert.EncodeName(_rootAdress + href))); - ParseAccessTypeEvents(eventsNode, func); - break; - default: - break; - } - } - } - } - } - } - - private static void ParseAccessTypeProperties(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Property", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseAccessTypeMethods(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Method", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseAccessTypeEvents(XElement propertiesNode, LogAction func) - { - using (var client = new System.Net.WebClient()) - { - string pageLink = XmlConvert.DecodeName(propertiesNode.Attribute("Link").Value); - string pageContent = DownloadPage(client, pageLink); - HtmlDocument doc = new HtmlDocument(); - doc.LoadHtml(pageContent); - var root = doc.DocumentNode; - var divNodes = root.Descendants("div").ToList(); - foreach (var item in divNodes) - { - string className = item.GetAttributeValue("class", null); - if (className == "toclevel2") - { - string href = item.FirstChild.NextSibling.GetAttributeValue("href", null); - string name = item.FirstChild.NextSibling.GetAttributeValue("title", null); - if (null != href && null != name) - { - if (name.IndexOf(" ") > -1) - name = name.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries)[0]; - propertiesNode.Add(new XElement("Event", new XElement("Name", name), new XElement("Link", _rootAdress + href))); - func(""); - } - } - } - } - } - - private static void ParseAccessConstants(XElement excelNode, LogAction func) - { - func("Parse Access Constants"); - XElement constantNode = new XElement("OldConstants", _rootAdress + _accessConstantsRelative); - excelNode.Add(constantNode); - func(String.Format("{0} Access Contants recieved", 1)); - } - - #endregion - - #region Methods - - /// - /// Parse MSDN Docu pages for MS-Office - /// - /// document to fill - /// progress handler - internal static XDocument ParseReference(LogAction func) - { - func("Parse References "); - XDocument document = new XDocument(); - document.Add(new XElement("NOBuildTools.ReferenceAnalyzer")); - ParseExcel(document, func); - ParseAccess(document, func); - ParseOffice(document, func); - ParseOutlook(document, func); - ParsePowerPoint(document, func); - ParseWord(document, func); - func("Done!"); - - return document; - } - - private static string DownloadPage(System.Net.WebClient client, string uri) - { - try - { - string pageContent = client.DownloadString(uri); - return pageContent; - } - catch - { - return DownloadPage(client, uri); - } - } - - #endregion - - } -} diff --git a/BuildTools/ReferenceAnalyzer/Program.cs b/BuildTools/ReferenceAnalyzer/Program.cs deleted file mode 100644 index 1e96a63a3..000000000 --- a/BuildTools/ReferenceAnalyzer/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; - -namespace NOBuildTools.ReferenceAnalyzer -{ - static class Program - { - /// - /// Der Haupteinstiegspunkt für die Anwendung. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/BuildTools/ReferenceAnalyzer/Properties/AssemblyInfo.cs b/BuildTools/ReferenceAnalyzer/Properties/AssemblyInfo.cs deleted file mode 100644 index a2fa71a34..000000000 --- a/BuildTools/ReferenceAnalyzer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Allgemeine Informationen über eine Assembly werden über die folgenden -// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, -// die mit einer Assembly verknüpft sind. -[assembly: AssemblyTitle("NOBuildTools.ReferenceAnalyzer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("NOBuildTools.ReferenceAnalyzer")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar -// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von -// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. -[assembly: ComVisible(false)] - -// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird -[assembly: Guid("d4050595-94c2-4ef5-acfe-500aa84b4079")] - -// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: -// -// Hauptversion -// Nebenversion -// Buildnummer -// Revision -// -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern -// übernehmen, indem Sie "*" eingeben: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BuildTools/ReferenceAnalyzer/Properties/Resources.Designer.cs b/BuildTools/ReferenceAnalyzer/Properties/Resources.Designer.cs deleted file mode 100644 index 146a18ca6..000000000 --- a/BuildTools/ReferenceAnalyzer/Properties/Resources.Designer.cs +++ /dev/null @@ -1,71 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können fehlerhaftes Verhalten verursachen und gehen verloren, wenn -// der Code neu generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.ReferenceAnalyzer.Properties -{ - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder-Klasse - // über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der Option /str erneut aus, oder erstellen Sie Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources - { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() - { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager - { - get - { - if ((resourceMan == null)) - { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NOBuildTools.ReferenceAnalyzer.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenlookups, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture - { - get - { - return resourceCulture; - } - set - { - resourceCulture = value; - } - } - } -} diff --git a/BuildTools/ReferenceAnalyzer/Properties/Resources.resx b/BuildTools/ReferenceAnalyzer/Properties/Resources.resx deleted file mode 100644 index af7dbebba..000000000 --- a/BuildTools/ReferenceAnalyzer/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/ReferenceAnalyzer/Properties/Settings.Designer.cs b/BuildTools/ReferenceAnalyzer/Properties/Settings.Designer.cs deleted file mode 100644 index 9cdc5d076..000000000 --- a/BuildTools/ReferenceAnalyzer/Properties/Settings.Designer.cs +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.1 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.ReferenceAnalyzer.Properties -{ - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase - { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default - { - get - { - return defaultInstance; - } - } - } -} diff --git a/BuildTools/ReferenceAnalyzer/Properties/Settings.settings b/BuildTools/ReferenceAnalyzer/Properties/Settings.settings deleted file mode 100644 index 39645652a..000000000 --- a/BuildTools/ReferenceAnalyzer/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/BuildTools/SearchAndReplace/ConfigManager.cs b/BuildTools/SearchAndReplace/ConfigManager.cs deleted file mode 100644 index a16b6d2de..000000000 --- a/BuildTools/SearchAndReplace/ConfigManager.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Xml; -using System.Xml.Linq; -using System.Text; - -namespace NOBuildTools.SearchAndReplace -{ - /// - /// Little helper to read and save config - /// - internal static class ConfigManager - { - /// - /// Save a configuration file - /// - /// target config file name - /// update folder - /// filter extension - /// search expression - /// replace value - public static void SaveConfigurationToXMLFile(string fullFileName, string targetFolder, string fileFilter, string search, string replace) - { - if (File.Exists(fullFileName)) - File.Delete(fullFileName); - - XDocument document = new XDocument(new XElement("NOBuildTools.SearchAndReplace")); - XElement root = document.FirstNode as XElement; - root.Add(new XElement("TargetFolder", XmlConvert.EncodeName(targetFolder))); - root.Add(new XElement("FileFilter", XmlConvert.EncodeName(fileFilter))); - root.Add(new XElement("Search", XmlConvert.EncodeName(search))); - root.Add(new XElement("Replace", XmlConvert.EncodeName(replace))); - - document.Save(fullFileName); - } - - /// - /// Load a configuration file - /// - /// target config file name - /// update folder - /// filter extension - /// search expression - /// replace value - public static void LoadConfigurationFromConfigFile(string fullFileName, ref string targetFolder, ref string fileFilter, ref string search, ref string replace) - { - if (!File.Exists(fullFileName)) - throw new FileNotFoundException(fullFileName); - - XDocument document = XDocument.Load(fullFileName); - XElement root = document.FirstNode as XElement; - if (root.Name != "NOBuildTools.SearchAndReplace") - throw new FormatException("Wrong Magic"); - - targetFolder = XmlConvert.DecodeName(root.Element("TargetFolder").Value); - fileFilter = XmlConvert.DecodeName(root.Element("FileFilter").Value); - search = XmlConvert.DecodeName(root.Element("Search").Value); - replace = XmlConvert.DecodeName(root.Element("Replace").Value); - } - } -} diff --git a/BuildTools/SearchAndReplace/ExceptionDisplayer.cs b/BuildTools/SearchAndReplace/ExceptionDisplayer.cs deleted file mode 100644 index 3ba0dfe51..000000000 --- a/BuildTools/SearchAndReplace/ExceptionDisplayer.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; -using System.Text; - -namespace NOBuildTools.SearchAndReplace -{ - /// - /// Exception display helper - /// - internal static class ExceptionDisplayer - { /// - /// Shows exception as string message box to the user - /// - /// modal parent - /// exception as any - public static void ShowException(IWin32Window parent, Exception exception) - { - string message = "An error is occured." + Environment.NewLine; - string detailsMessage = "Details: " + Environment.NewLine; - - while (null != exception) - { - detailsMessage += "Exception: " + exception.GetType().Name + Environment.NewLine; - detailsMessage += "Exception: " + exception.Message + Environment.NewLine; - - exception = exception.InnerException; - } - - MessageBox.Show(parent, message + detailsMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } -} diff --git a/BuildTools/SearchAndReplace/Form1.Designer.cs b/BuildTools/SearchAndReplace/Form1.Designer.cs deleted file mode 100644 index ab2abb5f1..000000000 --- a/BuildTools/SearchAndReplace/Form1.Designer.cs +++ /dev/null @@ -1,220 +0,0 @@ -namespace NOBuildTools.SearchAndReplace -{ - partial class Form1 - { - /// - /// Erforderliche Designervariable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Verwendete Ressourcen bereinigen. - /// - /// True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Vom Windows Form-Designer generierter Code - - /// - /// Erforderliche Methode für die Designerunterstützung. - /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. - /// - private void InitializeComponent() - { - this.TextBoxFolder = new System.Windows.Forms.TextBox(); - this.ButttonChooseFolder = new System.Windows.Forms.Button(); - this.RichTextBoxLog = new System.Windows.Forms.RichTextBox(); - this.LabelFolder = new System.Windows.Forms.Label(); - this.ButtonStart = new System.Windows.Forms.Button(); - this.TextBoxFilter = new System.Windows.Forms.TextBox(); - this.LabelFilter = new System.Windows.Forms.Label(); - this.LabelSearch = new System.Windows.Forms.Label(); - this.TextBoxSearch = new System.Windows.Forms.TextBox(); - this.TextBoxReplace = new System.Windows.Forms.TextBox(); - this.LabelReplace = new System.Windows.Forms.Label(); - this.ButtonLoadConfig = new System.Windows.Forms.Button(); - this.ButtonSaveConfig = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // TextBoxFolder - // - this.TextBoxFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.TextBoxFolder.Location = new System.Drawing.Point(67, 21); - this.TextBoxFolder.Name = "TextBoxFolder"; - this.TextBoxFolder.Size = new System.Drawing.Size(431, 20); - this.TextBoxFolder.TabIndex = 0; - // - // ButttonChooseFolder - // - this.ButttonChooseFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButttonChooseFolder.Location = new System.Drawing.Point(507, 20); - this.ButttonChooseFolder.Name = "ButttonChooseFolder"; - this.ButttonChooseFolder.Size = new System.Drawing.Size(40, 22); - this.ButttonChooseFolder.TabIndex = 1; - this.ButttonChooseFolder.Text = "..."; - this.ButttonChooseFolder.UseVisualStyleBackColor = true; - this.ButttonChooseFolder.Click += new System.EventHandler(this.ButtonChooseFolder_Click); - // - // RichTextBoxLog - // - this.RichTextBoxLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.RichTextBoxLog.Location = new System.Drawing.Point(67, 209); - this.RichTextBoxLog.Name = "RichTextBoxLog"; - this.RichTextBoxLog.ReadOnly = true; - this.RichTextBoxLog.Size = new System.Drawing.Size(746, 282); - this.RichTextBoxLog.TabIndex = 2; - this.RichTextBoxLog.Text = ""; - // - // LabelFolder - // - this.LabelFolder.AutoSize = true; - this.LabelFolder.Location = new System.Drawing.Point(12, 24); - this.LabelFolder.Name = "LabelFolder"; - this.LabelFolder.Size = new System.Drawing.Size(49, 13); - this.LabelFolder.TabIndex = 3; - this.LabelFolder.Text = "Directory"; - // - // ButtonStart - // - this.ButtonStart.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonStart.Location = new System.Drawing.Point(67, 159); - this.ButtonStart.Name = "ButtonStart"; - this.ButtonStart.Size = new System.Drawing.Size(746, 23); - this.ButtonStart.TabIndex = 4; - this.ButtonStart.Text = "Start"; - this.ButtonStart.UseVisualStyleBackColor = true; - this.ButtonStart.Click += new System.EventHandler(this.ButtonStart_Click); - // - // TextBoxFilter - // - this.TextBoxFilter.Location = new System.Drawing.Point(67, 62); - this.TextBoxFilter.Multiline = true; - this.TextBoxFilter.Name = "TextBoxFilter"; - this.TextBoxFilter.Size = new System.Drawing.Size(141, 79); - this.TextBoxFilter.TabIndex = 5; - this.TextBoxFilter.Text = "*.csproj\r\n*.vbproj"; - // - // LabelFilter - // - this.LabelFilter.AutoSize = true; - this.LabelFilter.Location = new System.Drawing.Point(12, 64); - this.LabelFilter.Name = "LabelFilter"; - this.LabelFilter.Size = new System.Drawing.Size(29, 13); - this.LabelFilter.TabIndex = 6; - this.LabelFilter.Text = "Filter"; - // - // LabelSearch - // - this.LabelSearch.AutoSize = true; - this.LabelSearch.Location = new System.Drawing.Point(214, 63); - this.LabelSearch.Name = "LabelSearch"; - this.LabelSearch.Size = new System.Drawing.Size(41, 13); - this.LabelSearch.TabIndex = 7; - this.LabelSearch.Text = "Search"; - // - // TextBoxSearch - // - this.TextBoxSearch.Location = new System.Drawing.Point(261, 62); - this.TextBoxSearch.Multiline = true; - this.TextBoxSearch.Name = "TextBoxSearch"; - this.TextBoxSearch.Size = new System.Drawing.Size(237, 79); - this.TextBoxSearch.TabIndex = 8; - this.TextBoxSearch.Text = "True"; - // - // TextBoxReplace - // - this.TextBoxReplace.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.TextBoxReplace.Location = new System.Drawing.Point(557, 62); - this.TextBoxReplace.Multiline = true; - this.TextBoxReplace.Name = "TextBoxReplace"; - this.TextBoxReplace.Size = new System.Drawing.Size(256, 79); - this.TextBoxReplace.TabIndex = 10; - this.TextBoxReplace.Text = "False"; - // - // LabelReplace - // - this.LabelReplace.AutoSize = true; - this.LabelReplace.Location = new System.Drawing.Point(504, 63); - this.LabelReplace.Name = "LabelReplace"; - this.LabelReplace.Size = new System.Drawing.Size(47, 13); - this.LabelReplace.TabIndex = 9; - this.LabelReplace.Text = "Replace"; - // - // ButtonLoadConfig - // - this.ButtonLoadConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonLoadConfig.Location = new System.Drawing.Point(558, 18); - this.ButtonLoadConfig.Name = "ButtonLoadConfig"; - this.ButtonLoadConfig.Size = new System.Drawing.Size(127, 27); - this.ButtonLoadConfig.TabIndex = 11; - this.ButtonLoadConfig.Text = "Load Config"; - this.ButtonLoadConfig.UseVisualStyleBackColor = true; - this.ButtonLoadConfig.Click += new System.EventHandler(this.ButtonLoadConfig_Click); - // - // ButtonSaveConfig - // - this.ButtonSaveConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.ButtonSaveConfig.Location = new System.Drawing.Point(697, 18); - this.ButtonSaveConfig.Name = "ButtonSaveConfig"; - this.ButtonSaveConfig.Size = new System.Drawing.Size(116, 27); - this.ButtonSaveConfig.TabIndex = 12; - this.ButtonSaveConfig.Text = "Save Config"; - this.ButtonSaveConfig.UseVisualStyleBackColor = true; - this.ButtonSaveConfig.Click += new System.EventHandler(this.ButtonSaveConfig_Click); - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(839, 512); - this.Controls.Add(this.ButtonSaveConfig); - this.Controls.Add(this.ButtonLoadConfig); - this.Controls.Add(this.TextBoxReplace); - this.Controls.Add(this.LabelReplace); - this.Controls.Add(this.TextBoxSearch); - this.Controls.Add(this.LabelSearch); - this.Controls.Add(this.LabelFilter); - this.Controls.Add(this.TextBoxFilter); - this.Controls.Add(this.ButtonStart); - this.Controls.Add(this.LabelFolder); - this.Controls.Add(this.RichTextBoxLog); - this.Controls.Add(this.ButttonChooseFolder); - this.Controls.Add(this.TextBoxFolder); - this.Name = "Form1"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "NOBuildTools.SearchAndReplace"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox TextBoxFolder; - private System.Windows.Forms.Button ButttonChooseFolder; - private System.Windows.Forms.RichTextBox RichTextBoxLog; - private System.Windows.Forms.Label LabelFolder; - private System.Windows.Forms.Button ButtonStart; - private System.Windows.Forms.TextBox TextBoxFilter; - private System.Windows.Forms.Label LabelFilter; - private System.Windows.Forms.Label LabelSearch; - private System.Windows.Forms.TextBox TextBoxSearch; - private System.Windows.Forms.TextBox TextBoxReplace; - private System.Windows.Forms.Label LabelReplace; - private System.Windows.Forms.Button ButtonLoadConfig; - private System.Windows.Forms.Button ButtonSaveConfig; - } -} - diff --git a/BuildTools/SearchAndReplace/Form1.cs b/BuildTools/SearchAndReplace/Form1.cs deleted file mode 100644 index 6663d610a..000000000 --- a/BuildTools/SearchAndReplace/Form1.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -using System.Text; -using System.Windows.Forms; - -namespace NOBuildTools.SearchAndReplace -{ - /// - /// Main form in the application - /// - public partial class Form1 : Form - { - #region Ctor - - /// - /// Creates an instance of the class - /// - public Form1() - { - InitializeComponent(); - TextBoxFolder.Text = Application.StartupPath; - } - - #endregion - - #region Methods - - private void LogAction(string message) - { - if(!String.IsNullOrWhiteSpace(message)) - RichTextBoxLog.Text = message + Environment.NewLine + RichTextBoxLog.Text; - this.Refresh(); - } - - #endregion - - #region Triger - - private void ButtonChooseFolder_Click(object sender, EventArgs e) - { - FolderBrowserDialog dlg = new FolderBrowserDialog(); - if (dlg.ShowDialog() == DialogResult.Cancel) - return; - TextBoxFolder.Text = dlg.SelectedPath; - } - - private void ButtonStart_Click(object sender, EventArgs e) - { - try - { - RichTextBoxLog.Clear(); - SearchAndReplaceManager.SearchAndReplace(TextBoxFolder.Text, TextBoxFilter.Text, TextBoxSearch.Text, TextBoxReplace.Text, LogAction); - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - private void ButtonSaveConfig_Click(object sender, EventArgs e) - { - try - { - SaveFileDialog dlg = new SaveFileDialog(); - dlg.InitialDirectory = Application.StartupPath; - dlg.Filter = "Xml Files(*.xml)|*.xml"; - if (dlg.ShowDialog(this) == DialogResult.Cancel) - return; - - ConfigManager.SaveConfigurationToXMLFile(dlg.FileName, TextBoxFolder.Text, TextBoxFilter.Text, TextBoxSearch.Text, TextBoxReplace.Text); - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - private void ButtonLoadConfig_Click(object sender, EventArgs e) - { - try - { - OpenFileDialog dlg = new OpenFileDialog(); - dlg.InitialDirectory = Application.StartupPath; - dlg.Filter = "Xml Files(*.xml)|*.xml"; - if (dlg.ShowDialog(this) == DialogResult.Cancel) - return; - - string targetFolder = string.Empty; - string filter = string.Empty; - string search = string.Empty; - string replace = string.Empty; - - ConfigManager.LoadConfigurationFromConfigFile(dlg.FileName, ref targetFolder, ref filter, ref search, ref replace); - - TextBoxFolder.Text = targetFolder; - TextBoxFilter.Text = filter; - TextBoxSearch.Text = search; - TextBoxReplace.Text = replace; - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - #endregion - } -} diff --git a/BuildTools/SearchAndReplace/Form1.resx b/BuildTools/SearchAndReplace/Form1.resx deleted file mode 100644 index 1af7de150..000000000 --- a/BuildTools/SearchAndReplace/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/SearchAndReplace/NOBuildTools.SearchAndReplace.csproj b/BuildTools/SearchAndReplace/NOBuildTools.SearchAndReplace.csproj deleted file mode 100644 index ccd77dabe..000000000 --- a/BuildTools/SearchAndReplace/NOBuildTools.SearchAndReplace.csproj +++ /dev/null @@ -1,90 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {CA71246E-CEB7-4399-B7C3-C5A18B5CC801} - WinExe - Properties - NOBuildTools.SearchAndReplace - NOBuildTools.SearchAndReplace - v4.0 - Client - 512 - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - Form - - - Form1.cs - - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - \ No newline at end of file diff --git a/BuildTools/SearchAndReplace/Program.cs b/BuildTools/SearchAndReplace/Program.cs deleted file mode 100644 index 1265546ed..000000000 --- a/BuildTools/SearchAndReplace/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; - -namespace NOBuildTools.SearchAndReplace -{ - static class Program - { - /// - /// Der Haupteinstiegspunkt für die Anwendung. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/BuildTools/SearchAndReplace/Properties/AssemblyInfo.cs b/BuildTools/SearchAndReplace/Properties/AssemblyInfo.cs deleted file mode 100644 index 4a7258720..000000000 --- a/BuildTools/SearchAndReplace/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// Allgemeine Informationen über eine Assembly werden über die folgenden -// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, -// die mit einer Assembly verknüpft sind. -[assembly: AssemblyTitle("NOBuildTools.SearchAndReplace")] -[assembly: AssemblyDescription("Search And Replace in Files")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("http://netoffice.codeplex.com")] -[assembly: AssemblyCopyright("Copyright © 2013 Sebastian Lange")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar -// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von -// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. -[assembly: ComVisible(false)] - -// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird -[assembly: Guid("acbaadf2-d4f0-4c3d-a604-de6b16f01e90")] - -// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: -// -// Hauptversion -// Nebenversion -// Buildnummer -// Revision -// -// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern -// übernehmen, indem Sie "*" eingeben: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BuildTools/SearchAndReplace/Properties/Resources.Designer.cs b/BuildTools/SearchAndReplace/Properties/Resources.Designer.cs deleted file mode 100644 index 508e25e73..000000000 --- a/BuildTools/SearchAndReplace/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.SearchAndReplace.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NOBuildTools.SearchAndReplace.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/BuildTools/SearchAndReplace/Properties/Resources.resx b/BuildTools/SearchAndReplace/Properties/Resources.resx deleted file mode 100644 index af7dbebba..000000000 --- a/BuildTools/SearchAndReplace/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/SearchAndReplace/Properties/Settings.Designer.cs b/BuildTools/SearchAndReplace/Properties/Settings.Designer.cs deleted file mode 100644 index 005abfc52..000000000 --- a/BuildTools/SearchAndReplace/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.SearchAndReplace.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/BuildTools/SearchAndReplace/Properties/Settings.settings b/BuildTools/SearchAndReplace/Properties/Settings.settings deleted file mode 100644 index 39645652a..000000000 --- a/BuildTools/SearchAndReplace/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/BuildTools/SearchAndReplace/SearchAndReplaceManager.cs b/BuildTools/SearchAndReplace/SearchAndReplaceManager.cs deleted file mode 100644 index f4310d8ed..000000000 --- a/BuildTools/SearchAndReplace/SearchAndReplaceManager.cs +++ /dev/null @@ -1,256 +0,0 @@ -using System; -using System.IO; -using System.Windows.Forms; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NOBuildTools.SearchAndReplace -{ - /// Progress log action handler - /// - /// log action message - public delegate void LogAction(string message); - - /// - /// Search and replace logic for text files - /// - internal static class SearchAndReplaceManager - { - /// - /// Read all files in a directory and replace arg search with arg replace in file content(s) - /// - /// target root directory - /// exclude filter as file extension - /// search expression - /// replace value - /// log handler - public static void SearchAndReplace(string directoryName, string fileFilter, string search, string replace, LogAction func) - { - if (!Directory.Exists(directoryName)) - throw new DirectoryNotFoundException(directoryName); - if (null == func || String.IsNullOrWhiteSpace(replace) || String.IsNullOrWhiteSpace(search) || String.IsNullOrWhiteSpace(fileFilter) || String.IsNullOrWhiteSpace(directoryName)) - throw new ArgumentNullException(); - - string[] filterArray = BuildFilterArray(fileFilter); - string[] searchArray = BuildSearchArray(search); - string[] replaceArray = BuildReplaceArray(replace); - if (searchArray.Length != replaceArray.Length) - throw new FormatException("Search and Repleace terms count must equal"); - SearchAndReplace(directoryName, filterArray, searchArray, replaceArray, func); - } - - private static string[] BuildFilterArray(string fileFilter) - { - List list = new List(); - if (!String.IsNullOrWhiteSpace(fileFilter)) - { - string[] tempArray = fileFilter.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - foreach (var item in tempArray) - list.Add(item.Trim()); - if (list.Count == 0) - list.Add("*.*"); - } - else - list.Add("*.*"); - return list.ToArray(); - } - - private static string[] BuildSearchArray(string search) - { - List list = new List(); - if (!String.IsNullOrWhiteSpace(search)) - { - string[] tempArray = search.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); - foreach (var item in tempArray) - list.Add(item.Trim()); - if(list.Count == 0) - throw new FormatException("Search term can't be empty."); - } - else - throw new FormatException("Search term can't be empty."); - return list.ToArray(); - } - - private static string[] BuildReplaceArray(string replace) - { - List list = new List(); - if (!String.IsNullOrWhiteSpace(replace)) - { - string[] tempArray = replace.Split(new string[] { Environment.NewLine }, StringSplitOptions.None); - foreach (var item in tempArray) - list.Add(item.Trim()); - if (list.Count == 0) - throw new FormatException("Replace term can't be empty."); - } - else - throw new FormatException("Replace term can't be empty."); - return list.ToArray(); - } - - private static bool FilterPassed(string file, string[] fileFilter) - { - foreach (var item in fileFilter) - { - string end = item; - string extenstion = Path.GetExtension(file); - if (extenstion.StartsWith(".")) - extenstion = extenstion.Substring(1); - int pos = item.IndexOf("."); - if (pos > -1) - end = item.Substring(pos + 1); - if (end.Equals(extenstion, StringComparison.InvariantCultureIgnoreCase)) - return true; - } - return false; - } - - private static bool DoSearchAndReplace(ref string fileContent, string[] searchArray, string[] replaceArray, LogAction func) - { - bool oneOrMoreReplaced = false; - for (int i = 0; i < searchArray.Length; i++) - { - string search = searchArray[i]; - string replace = replaceArray[i]; - int cnt = 0; - while (fileContent.IndexOf(search) > -1) - { - fileContent = fileContent.Replace(search, replace); - cnt++; - } - if (cnt > 0) - { - oneOrMoreReplaced = true; - func(String.Format("{0} entries of {1} replaced", cnt, search)); - } - - } - - return oneOrMoreReplaced; - } - - private static bool WriteFile(string file, string fileContent, LogAction func) - { - try - { - File.WriteAllText(file, fileContent); - return true; - } - catch (Exception exception) - { - func("File write error." + exception.ToString()); - return false; - } - } - - private static bool ReverseMoveBackupFile(string backupFile, string originFile) - { - try - { - File.Move(backupFile, originFile); - return true; - } - catch - { - return false; - } - } - - private static string CopyFileBackup(string file, LogAction func) - { - try - { - string fileName = System.IO.Path.GetFileName(file); - string newFile = System.IO.Path.Combine(Application.StartupPath, "BackupSearchAndReplace", fileName); - - if(!Directory.Exists( System.IO.Path.Combine(Application.StartupPath, "BackupSearchAndReplace"))) - Directory.CreateDirectory(System.IO.Path.Combine(Application.StartupPath, "BackupSearchAndReplace")); - - File.Copy(file, newFile); - return newFile; - } - catch (Exception exception) - { - func("File copy error." + exception.ToString()); - return null; - } - } - - private static bool FileDelete(string file, LogAction func) - { - try - { - File.Delete(file); - return true; - } - catch (Exception exception) - { - func("File delete error." + exception.ToString()); - return false; - } - } - - private static bool ReadFile(string file, ref string fileContent, LogAction func) - { - try - { - fileContent = File.ReadAllText(file, Encoding.UTF8); - return true; - } - catch (Exception exception) - { - func("File reading error." + exception.ToString()); - return false; - } - } - - private static void DeleteBackupFile(string fileName) - { - File.Delete(fileName); - } - - private static void SearchAndReplace(string directoryName, string[] fileFilter, string[] search, string[] replace, LogAction func) - { - int i = 0; - func("Search and Replace is started"); - foreach (var item in Directory.GetFiles(directoryName, "*.*", SearchOption.AllDirectories)) - { - i++; - if(i.ToString().EndsWith("00")) - func(""); - - bool filterPassed = FilterPassed(item, fileFilter); - if (!filterPassed) - continue; - string fileContent = string.Empty; - if (ReadFile(item, ref fileContent, func)) - { - if (DoSearchAndReplace(ref fileContent, search, replace, func)) - { - string newFileName = CopyFileBackup(item, func); - if (null != newFileName) - { - if(FileDelete(item, func)) - { - if (WriteFile(item, fileContent, func)) - { - DeleteBackupFile(newFileName); - func("changed: " + item); - } - else - { - if(ReverseMoveBackupFile(newFileName, item)) - func("backup file restored after write error: " + item); - else - func("WARNING: backup file not restored after write error: " + item); - } - } - - } - } - } - } - func("Search and Replace is complete"); - } - } -} diff --git a/BuildTools/SourceUpdater/Form1.Designer.cs b/BuildTools/SourceUpdater/Form1.Designer.cs deleted file mode 100644 index 39c783b71..000000000 --- a/BuildTools/SourceUpdater/Form1.Designer.cs +++ /dev/null @@ -1,158 +0,0 @@ -namespace NOBuildTools.SourceUpdater -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.label1 = new System.Windows.Forms.Label(); - this.label2 = new System.Windows.Forms.Label(); - this.textBoxSource = new System.Windows.Forms.TextBox(); - this.textBoxDest = new System.Windows.Forms.TextBox(); - this.buttonChooseSource = new System.Windows.Forms.Button(); - this.buttonChooseDest = new System.Windows.Forms.Button(); - this.buttonStart = new System.Windows.Forms.Button(); - this.textBoxLog = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.SuspendLayout(); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(29, 62); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(41, 13); - this.label1.TabIndex = 0; - this.label1.Text = "Source"; - // - // label2 - // - this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(29, 88); - this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(29, 13); - this.label2.TabIndex = 1; - this.label2.Text = "Dest"; - // - // textBoxSource - // - this.textBoxSource.Location = new System.Drawing.Point(76, 59); - this.textBoxSource.Name = "textBoxSource"; - this.textBoxSource.Size = new System.Drawing.Size(606, 20); - this.textBoxSource.TabIndex = 2; - this.textBoxSource.Text = "C:\\LateBindingApi\\LateBindingApi.CodeGenerator.WFApplication\\bin\\Debug\\NetOffice"; - // - // textBoxDest - // - this.textBoxDest.Location = new System.Drawing.Point(76, 85); - this.textBoxDest.Name = "textBoxDest"; - this.textBoxDest.Size = new System.Drawing.Size(606, 20); - this.textBoxDest.TabIndex = 3; - this.textBoxDest.Text = "C:\\NetOffice\\Source"; - // - // buttonChooseSource - // - this.buttonChooseSource.Location = new System.Drawing.Point(688, 57); - this.buttonChooseSource.Name = "buttonChooseSource"; - this.buttonChooseSource.Size = new System.Drawing.Size(44, 23); - this.buttonChooseSource.TabIndex = 4; - this.buttonChooseSource.Text = "..."; - this.buttonChooseSource.UseVisualStyleBackColor = true; - this.buttonChooseSource.Click += new System.EventHandler(this.buttonChooseSource_Click); - // - // buttonChooseDest - // - this.buttonChooseDest.Location = new System.Drawing.Point(688, 88); - this.buttonChooseDest.Name = "buttonChooseDest"; - this.buttonChooseDest.Size = new System.Drawing.Size(44, 23); - this.buttonChooseDest.TabIndex = 5; - this.buttonChooseDest.Text = "..."; - this.buttonChooseDest.UseVisualStyleBackColor = true; - this.buttonChooseDest.Click += new System.EventHandler(this.buttonChooseDest_Click); - // - // buttonStart - // - this.buttonStart.Location = new System.Drawing.Point(596, 126); - this.buttonStart.Name = "buttonStart"; - this.buttonStart.Size = new System.Drawing.Size(77, 23); - this.buttonStart.TabIndex = 6; - this.buttonStart.Text = "Start"; - this.buttonStart.UseVisualStyleBackColor = true; - this.buttonStart.Click += new System.EventHandler(this.buttonStart_Click); - // - // textBoxLog - // - this.textBoxLog.Location = new System.Drawing.Point(76, 129); - this.textBoxLog.Name = "textBoxLog"; - this.textBoxLog.ReadOnly = true; - this.textBoxLog.Size = new System.Drawing.Size(485, 20); - this.textBoxLog.TabIndex = 7; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(73, 9); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(624, 13); - this.label3.TabIndex = 8; - this.label3.Text = "This tool update the existing NetOffice source folder with a newer version. (repl" + - "ace by windows explorer kills .svn meta informations)"; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(761, 180); - this.Controls.Add(this.label3); - this.Controls.Add(this.textBoxLog); - this.Controls.Add(this.buttonStart); - this.Controls.Add(this.buttonChooseDest); - this.Controls.Add(this.buttonChooseSource); - this.Controls.Add(this.textBoxDest); - this.Controls.Add(this.textBoxSource); - this.Controls.Add(this.label2); - this.Controls.Add(this.label1); - this.Name = "Form1"; - this.Text = "SVN friendly CodeIntegrator"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.Label label1; - private System.Windows.Forms.Label label2; - private System.Windows.Forms.TextBox textBoxSource; - private System.Windows.Forms.TextBox textBoxDest; - private System.Windows.Forms.Button buttonChooseSource; - private System.Windows.Forms.Button buttonChooseDest; - private System.Windows.Forms.Button buttonStart; - private System.Windows.Forms.TextBox textBoxLog; - private System.Windows.Forms.Label label3; - } -} - diff --git a/BuildTools/SourceUpdater/Form1.cs b/BuildTools/SourceUpdater/Form1.cs deleted file mode 100644 index aa6c0e5d6..000000000 --- a/BuildTools/SourceUpdater/Form1.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; -using System.Windows.Forms; -using System.IO; - -namespace NOBuildTools.SourceUpdater -{ - /// - /// Main form in the application - /// - public partial class Form1 : Form - { - #region Ctor - - /// - /// Creates an instance of the class - /// - public Form1() - { - InitializeComponent(); - } - - #endregion - - #region Methods - - private bool GetIsInSvnFolder(string file) - { - if (file.IndexOf(".svn",StringComparison.InvariantCultureIgnoreCase) > -1) - return true; - else - return false; - - } - - #endregion - - #region Trigger - - private void buttonStart_Click(object sender, EventArgs e) - { - if (!Directory.Exists(textBoxSource.Text)) - { - MessageBox.Show("SourceDir not found"); - return; - } - - if (!Directory.Exists(textBoxDest.Text)) - { - MessageBox.Show("DestDir not found"); - return; - } - - int i = 0; - string[] codeFiles = Directory.GetFiles(textBoxSource.Text, "*.*", SearchOption.AllDirectories); - foreach (string item in codeFiles) - { - bool isInSvnFolder = GetIsInSvnFolder(item); - if (false == isInSvnFolder) - { - textBoxLog.Text = item; - string newFilePath = GetNewFilePath(textBoxSource.Text, textBoxDest.Text, item); - if (File.Exists(newFilePath)) - File.Delete(newFilePath); - - if (!Directory.Exists(Path.GetDirectoryName(newFilePath))) - Directory.CreateDirectory(Path.GetDirectoryName(newFilePath)); - - File.Copy(item, newFilePath); - i++; - } - } - - textBoxLog.Text = "Finish " + i.ToString() + " Files."; - } - - private string GetNewFilePath(string sourceDir, string DestDir, string file) - { - file = file.Substring(sourceDir.Length); - return DestDir + file; - } - - private void buttonChooseSource_Click(object sender, EventArgs e) - { - FolderBrowserDialog fbd = new FolderBrowserDialog(); - if (DialogResult.OK == fbd.ShowDialog(this)) - textBoxSource.Text = fbd.SelectedPath; - } - - private void buttonChooseDest_Click(object sender, EventArgs e) - { - FolderBrowserDialog fbd = new FolderBrowserDialog(); - if (DialogResult.OK == fbd.ShowDialog(this)) - textBoxDest.Text = fbd.SelectedPath; - } - - #endregion - - } -} diff --git a/BuildTools/SourceUpdater/Form1.resx b/BuildTools/SourceUpdater/Form1.resx deleted file mode 100644 index 7080a7d11..000000000 --- a/BuildTools/SourceUpdater/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/SourceUpdater/NOBuildTools.SourceUpdater.csproj b/BuildTools/SourceUpdater/NOBuildTools.SourceUpdater.csproj deleted file mode 100644 index 72fb52a33..000000000 --- a/BuildTools/SourceUpdater/NOBuildTools.SourceUpdater.csproj +++ /dev/null @@ -1,92 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {FE3B95E3-990A-4F82-92D5-6C26046C3EC2} - WinExe - Properties - NOBuildTools.SourceUpdater - NOBuildTools.SourceUpdater - v4.0 - 512 - - - 3.5 - - Client - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - - - - - 3.5 - - - - - - - - - - Form - - - Form1.cs - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - \ No newline at end of file diff --git a/BuildTools/SourceUpdater/Program.cs b/BuildTools/SourceUpdater/Program.cs deleted file mode 100644 index 429807d85..000000000 --- a/BuildTools/SourceUpdater/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows.Forms; - -namespace NOBuildTools.SourceUpdater -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/BuildTools/SourceUpdater/Properties/AssemblyInfo.cs b/BuildTools/SourceUpdater/Properties/AssemblyInfo.cs deleted file mode 100644 index c2007bb55..000000000 --- a/BuildTools/SourceUpdater/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NOBuildTools.SourceUpdater")] -[assembly: AssemblyDescription("Smart Source Integrator")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("http://netoffice.codeplex.com")] -[assembly: AssemblyCopyright("Copyright 2011 © Sebastian Lange")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("187348b1-6889-4a37-ada3-f93fa8a7dad9")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BuildTools/SourceUpdater/Properties/Resources.Designer.cs b/BuildTools/SourceUpdater/Properties/Resources.Designer.cs deleted file mode 100644 index 304385182..000000000 --- a/BuildTools/SourceUpdater/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.SourceUpdater.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NOBuildTools.SourceUpdater.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/BuildTools/SourceUpdater/Properties/Resources.resx b/BuildTools/SourceUpdater/Properties/Resources.resx deleted file mode 100644 index af7dbebba..000000000 --- a/BuildTools/SourceUpdater/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/SourceUpdater/Properties/Settings.Designer.cs b/BuildTools/SourceUpdater/Properties/Settings.Designer.cs deleted file mode 100644 index 60145aad0..000000000 --- a/BuildTools/SourceUpdater/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.SourceUpdater.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/BuildTools/SourceUpdater/Properties/Settings.settings b/BuildTools/SourceUpdater/Properties/Settings.settings deleted file mode 100644 index 39645652a..000000000 --- a/BuildTools/SourceUpdater/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/BuildTools/SourceUpdater/app.config b/BuildTools/SourceUpdater/app.config deleted file mode 100644 index a293d0a0e..000000000 --- a/BuildTools/SourceUpdater/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/BuildTools/VersionUpdater/ConfigManager.cs b/BuildTools/VersionUpdater/ConfigManager.cs deleted file mode 100644 index ebd91fc38..000000000 --- a/BuildTools/VersionUpdater/ConfigManager.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using System.Xml; -using System.Xml.Linq; -using System.Text; - -namespace NOBuildTools.VersionUpdater -{ - /// - /// Little helper to read and save config - /// - internal static class ConfigManager - { - /// - /// Save a configuration file - /// - /// target config file - /// target update root directory - /// change Marker - /// from .net version - /// to .net versions - /// change also key files - /// root folder with key files - public static void SaveConfigurationToXMLFile(string fullFileName, string directory, bool changeMarker, string fromNet, string toNet, bool changeKeyFiles, string keyFilesFolder) - { - if (File.Exists(fullFileName)) - File.Delete(fullFileName); - XDocument document = new XDocument(new XElement("NOBuildTools.VersionUpdater")); - XElement root = document.FirstNode as XElement; - - root.Add(new XElement("TargetFolder", XmlConvert.EncodeName(directory))); - root.Add(new XElement("ChangeMarker", XmlConvert.EncodeName(changeMarker.ToString()))); - root.Add(new XElement("From", XmlConvert.EncodeName(fromNet))); - root.Add(new XElement("To", XmlConvert.EncodeName(fromNet))); - root.Add(new XElement("ChangeKeyFiles", XmlConvert.EncodeName(changeKeyFiles.ToString()))); - root.Add(new XElement("KeyFilesFolder", XmlConvert.EncodeName(keyFilesFolder))); - - document.Save(fullFileName); - } - - /// - /// Loads a configuration file - /// - /// target config file - /// target update root directory - /// change Marker - /// from .net version - /// to .net versions - /// change also key files - /// root folder with key files - public static void LoadConfigurationFromConfigFile(string fullFileName, ref string directory, ref bool changeMarker, ref string fromNet, ref string toNet, ref bool changeKeyFiles, ref string keyFilesFolder) - { - if (!File.Exists(fullFileName)) - throw new FileNotFoundException(fullFileName); - - XDocument document = XDocument.Load(fullFileName); - XElement root = document.FirstNode as XElement; - if (root.Name != "NOBuildTools.VersionUpdater") - throw new FormatException("Wrong Magic"); - - directory = XmlConvert.DecodeName(root.Element("TargetFolder").Value); - changeMarker = Convert.ToBoolean(XmlConvert.DecodeName(root.Element("ChangeMarker").Value)); - fromNet = XmlConvert.DecodeName(root.Element("From").Value); - toNet = XmlConvert.DecodeName(root.Element("To").Value); - changeKeyFiles = Convert.ToBoolean(XmlConvert.DecodeName(root.Element("ChangeKeyFiles").Value)); - keyFilesFolder = XmlConvert.DecodeName(root.Element("KeyFilesFolder").Value); - } - } -} diff --git a/BuildTools/VersionUpdater/ExceptionDisplayer.cs b/BuildTools/VersionUpdater/ExceptionDisplayer.cs deleted file mode 100644 index 3f54b8f4a..000000000 --- a/BuildTools/VersionUpdater/ExceptionDisplayer.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Windows.Forms; -using System.Text; - -namespace NOBuildTools.VersionUpdater -{ - /// - /// Exception display helper - /// - internal static class ExceptionDisplayer - { - /// - /// Shows exception as string message box to the user - /// - /// modal parent - /// exception as any - public static void ShowException(IWin32Window parent, Exception exception) - { - string message = "An error is occured." + Environment.NewLine; - string detailsMessage = "Details: " + Environment.NewLine; - - while (null != exception) - { - detailsMessage += "Exception: " + exception.GetType().Name + Environment.NewLine; - detailsMessage += "Exception: " + exception.Message + Environment.NewLine; - - exception = exception.InnerException; - } - - MessageBox.Show(parent, message + detailsMessage, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } -} diff --git a/BuildTools/VersionUpdater/Form1.Designer.cs b/BuildTools/VersionUpdater/Form1.Designer.cs deleted file mode 100644 index 879f6e90c..000000000 --- a/BuildTools/VersionUpdater/Form1.Designer.cs +++ /dev/null @@ -1,255 +0,0 @@ -namespace NOBuildTools.VersionUpdater -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.textBoxFolder = new System.Windows.Forms.TextBox(); - this.textBoxLog = new System.Windows.Forms.TextBox(); - this.buttonChooseFolder = new System.Windows.Forms.Button(); - this.buttonStart = new System.Windows.Forms.Button(); - this.comboBoxToNetVersion = new System.Windows.Forms.ComboBox(); - this.checkBoxChangeKeyFiles = new System.Windows.Forms.CheckBox(); - this.textBoxKeyFilesRootFolder = new System.Windows.Forms.TextBox(); - this.labelKeyFolder = new System.Windows.Forms.Label(); - this.checkBoxChangeNetMarker = new System.Windows.Forms.CheckBox(); - this.labelFolder = new System.Windows.Forms.Label(); - this.labelNetVersion = new System.Windows.Forms.Label(); - this.buttonLoadConfig = new System.Windows.Forms.Button(); - this.buttonSaveConfig = new System.Windows.Forms.Button(); - this.label1 = new System.Windows.Forms.Label(); - this.comboBoxFromNetVersion = new System.Windows.Forms.ComboBox(); - this.SuspendLayout(); - // - // textBoxFolder - // - this.textBoxFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxFolder.Location = new System.Drawing.Point(100, 19); - this.textBoxFolder.Name = "textBoxFolder"; - this.textBoxFolder.Size = new System.Drawing.Size(740, 20); - this.textBoxFolder.TabIndex = 0; - // - // textBoxLog - // - this.textBoxLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxLog.Location = new System.Drawing.Point(101, 155); - this.textBoxLog.Multiline = true; - this.textBoxLog.Name = "textBoxLog"; - this.textBoxLog.ReadOnly = true; - this.textBoxLog.Size = new System.Drawing.Size(739, 305); - this.textBoxLog.TabIndex = 1; - // - // buttonChooseFolder - // - this.buttonChooseFolder.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.buttonChooseFolder.Location = new System.Drawing.Point(863, 16); - this.buttonChooseFolder.Name = "buttonChooseFolder"; - this.buttonChooseFolder.Size = new System.Drawing.Size(45, 24); - this.buttonChooseFolder.TabIndex = 2; - this.buttonChooseFolder.Text = "..."; - this.buttonChooseFolder.UseVisualStyleBackColor = true; - this.buttonChooseFolder.Click += new System.EventHandler(this.buttonChooseFolder_Click); - // - // buttonStart - // - this.buttonStart.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.buttonStart.Location = new System.Drawing.Point(100, 125); - this.buttonStart.Name = "buttonStart"; - this.buttonStart.Size = new System.Drawing.Size(540, 24); - this.buttonStart.TabIndex = 3; - this.buttonStart.Text = "Start"; - this.buttonStart.UseVisualStyleBackColor = true; - this.buttonStart.Click += new System.EventHandler(this.buttonStart_Click); - // - // comboBoxToNetVersion - // - this.comboBoxToNetVersion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxToNetVersion.FormattingEnabled = true; - this.comboBoxToNetVersion.Items.AddRange(new object[] { - ".Net 2.0", - ".Net 3.0", - ".Net 3.5", - ".Net 4.0", - ".Net 4.5"}); - this.comboBoxToNetVersion.Location = new System.Drawing.Point(476, 51); - this.comboBoxToNetVersion.Name = "comboBoxToNetVersion"; - this.comboBoxToNetVersion.Size = new System.Drawing.Size(172, 21); - this.comboBoxToNetVersion.TabIndex = 4; - // - // checkBoxChangeKeyFiles - // - this.checkBoxChangeKeyFiles.AutoSize = true; - this.checkBoxChangeKeyFiles.Location = new System.Drawing.Point(100, 91); - this.checkBoxChangeKeyFiles.Name = "checkBoxChangeKeyFiles"; - this.checkBoxChangeKeyFiles.Size = new System.Drawing.Size(105, 17); - this.checkBoxChangeKeyFiles.TabIndex = 6; - this.checkBoxChangeKeyFiles.Text = "Change KeyFiles"; - this.checkBoxChangeKeyFiles.UseVisualStyleBackColor = true; - // - // textBoxKeyFilesRootFolder - // - this.textBoxKeyFilesRootFolder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.textBoxKeyFilesRootFolder.Location = new System.Drawing.Point(330, 89); - this.textBoxKeyFilesRootFolder.Name = "textBoxKeyFilesRootFolder"; - this.textBoxKeyFilesRootFolder.Size = new System.Drawing.Size(510, 20); - this.textBoxKeyFilesRootFolder.TabIndex = 7; - this.textBoxKeyFilesRootFolder.Text = "C:\\NetOffice\\KeyFiles"; - // - // labelKeyFolder - // - this.labelKeyFolder.AutoSize = true; - this.labelKeyFolder.Location = new System.Drawing.Point(219, 93); - this.labelKeyFolder.Name = "labelKeyFolder"; - this.labelKeyFolder.Size = new System.Drawing.Size(101, 13); - this.labelKeyFolder.TabIndex = 8; - this.labelKeyFolder.Text = "KeyFiles RootFolder"; - // - // checkBoxChangeNetMarker - // - this.checkBoxChangeNetMarker.AutoSize = true; - this.checkBoxChangeNetMarker.Location = new System.Drawing.Point(668, 55); - this.checkBoxChangeNetMarker.Name = "checkBoxChangeNetMarker"; - this.checkBoxChangeNetMarker.Size = new System.Drawing.Size(116, 17); - this.checkBoxChangeNetMarker.TabIndex = 12; - this.checkBoxChangeNetMarker.Text = "Change NetMarker"; - this.checkBoxChangeNetMarker.UseVisualStyleBackColor = true; - // - // labelFolder - // - this.labelFolder.AutoSize = true; - this.labelFolder.Location = new System.Drawing.Point(21, 22); - this.labelFolder.Name = "labelFolder"; - this.labelFolder.Size = new System.Drawing.Size(49, 13); - this.labelFolder.TabIndex = 13; - this.labelFolder.Text = "Directory"; - // - // labelNetVersion - // - this.labelNetVersion.AutoSize = true; - this.labelNetVersion.Location = new System.Drawing.Point(384, 55); - this.labelNetVersion.Name = "labelNetVersion"; - this.labelNetVersion.Size = new System.Drawing.Size(86, 13); - this.labelNetVersion.TabIndex = 15; - this.labelNetVersion.Text = "To .NET Version"; - // - // buttonLoadConfig - // - this.buttonLoadConfig.Location = new System.Drawing.Point(653, 125); - this.buttonLoadConfig.Name = "buttonLoadConfig"; - this.buttonLoadConfig.Size = new System.Drawing.Size(90, 24); - this.buttonLoadConfig.TabIndex = 21; - this.buttonLoadConfig.Text = "Load Config"; - this.buttonLoadConfig.UseVisualStyleBackColor = true; - this.buttonLoadConfig.Click += new System.EventHandler(this.buttonLoadConfig_Click); - // - // buttonSaveConfig - // - this.buttonSaveConfig.Location = new System.Drawing.Point(750, 125); - this.buttonSaveConfig.Name = "buttonSaveConfig"; - this.buttonSaveConfig.Size = new System.Drawing.Size(90, 24); - this.buttonSaveConfig.TabIndex = 22; - this.buttonSaveConfig.Text = "Save Config"; - this.buttonSaveConfig.UseVisualStyleBackColor = true; - this.buttonSaveConfig.Click += new System.EventHandler(this.buttonSaveConfig_Click); - // - // label1 - // - this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(101, 55); - this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(93, 13); - this.label1.TabIndex = 24; - this.label1.Text = "From NET Version"; - // - // comboBoxFromNetVersion - // - this.comboBoxFromNetVersion.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.comboBoxFromNetVersion.FormattingEnabled = true; - this.comboBoxFromNetVersion.Items.AddRange(new object[] { - ".Net 2.0", - ".Net 3.0", - ".Net 3.5", - ".Net 4.0", - ".Net 4.5"}); - this.comboBoxFromNetVersion.Location = new System.Drawing.Point(200, 51); - this.comboBoxFromNetVersion.Name = "comboBoxFromNetVersion"; - this.comboBoxFromNetVersion.Size = new System.Drawing.Size(172, 21); - this.comboBoxFromNetVersion.TabIndex = 23; - // - // Form1 - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(925, 472); - this.Controls.Add(this.label1); - this.Controls.Add(this.comboBoxFromNetVersion); - this.Controls.Add(this.buttonSaveConfig); - this.Controls.Add(this.buttonLoadConfig); - this.Controls.Add(this.labelNetVersion); - this.Controls.Add(this.labelFolder); - this.Controls.Add(this.checkBoxChangeNetMarker); - this.Controls.Add(this.labelKeyFolder); - this.Controls.Add(this.textBoxKeyFilesRootFolder); - this.Controls.Add(this.checkBoxChangeKeyFiles); - this.Controls.Add(this.comboBoxToNetVersion); - this.Controls.Add(this.buttonStart); - this.Controls.Add(this.buttonChooseFolder); - this.Controls.Add(this.textBoxLog); - this.Controls.Add(this.textBoxFolder); - this.Name = "Form1"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "NOBuildTools.VersionUpdater"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox textBoxFolder; - private System.Windows.Forms.TextBox textBoxLog; - private System.Windows.Forms.Button buttonChooseFolder; - private System.Windows.Forms.Button buttonStart; - private System.Windows.Forms.ComboBox comboBoxToNetVersion; - private System.Windows.Forms.CheckBox checkBoxChangeKeyFiles; - private System.Windows.Forms.TextBox textBoxKeyFilesRootFolder; - private System.Windows.Forms.Label labelKeyFolder; - private System.Windows.Forms.CheckBox checkBoxChangeNetMarker; - private System.Windows.Forms.Label labelFolder; - private System.Windows.Forms.Label labelNetVersion; - private System.Windows.Forms.Button buttonLoadConfig; - private System.Windows.Forms.Button buttonSaveConfig; - private System.Windows.Forms.Label label1; - private System.Windows.Forms.ComboBox comboBoxFromNetVersion; - } -} - diff --git a/BuildTools/VersionUpdater/Form1.cs b/BuildTools/VersionUpdater/Form1.cs deleted file mode 100644 index 3b927552c..000000000 --- a/BuildTools/VersionUpdater/Form1.cs +++ /dev/null @@ -1,463 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.IO; -using System.Drawing; -using System.Text; -using System.Windows.Forms; - -namespace NOBuildTools.VersionUpdater -{ - /// - /// Main form in the application - /// - public partial class Form1 : Form - { - #region Ctor - - /// - /// Creates an instance of the class - /// - public Form1() - { - InitializeComponent(); - textBoxFolder.Text = Application.StartupPath; - comboBoxFromNetVersion.SelectedIndex = 0; - comboBoxToNetVersion.SelectedIndex = 0; - } - - #endregion - - #region Methods - - private string GetSelectedFromNetVersion() - { - switch (comboBoxFromNetVersion.SelectedIndex) - { - case 0: - return "2.0"; - case 1: - return "3.0"; - case 2: - return "3.5"; - case 3: - return "4.0"; - case 4: - return "4.5"; - } - throw (new Exception("From .NET Version not selected.")); - } - - private string GetSelectedToNetVersion() - { - switch (comboBoxToNetVersion.SelectedIndex) - { - case 0: - return "2.0"; - case 1: - return "3.0"; - case 2: - return "3.5"; - case 3: - return "4.0"; - case 4: - return "4.5"; - } - throw (new Exception("To .NET Version not selected.")); - } - - private bool CheckPrequsits() - { - if (!Directory.Exists(textBoxFolder.Text)) - { - MessageBox.Show("Directory not exists", "Doooh", MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - - return true; - } - - private void ChangeKeyFileInProjectFile(ref string fileContent, string currentFolder, string name, string netVersion) - { - if (!checkBoxChangeKeyFiles.Checked) - return; - - int position1 = fileContent.IndexOf(""); - if (position1 < 0) - { - textBoxLog.AppendText("\t\tKeyFile Entry not found:" + name + "\r\n"); - return; - } - - int position2 = fileContent.IndexOf("", position1); - string keyFile = fileContent.Substring(position1 + "".Length, position2 - (position1 + "".Length)); - string[] arr = keyFile.Split(new string[] {"_"},StringSplitOptions.RemoveEmptyEntries); - string newKeyFile = arr[0] + "_v" + netVersion + ".snk"; - string newLine = "" + newKeyFile + ""; - - string net1 = "" + keyFile + ""; - fileContent = fileContent.Replace(net1, newLine); - - string sourceFile = System.IO.Path.Combine(textBoxKeyFilesRootFolder.Text, netVersion); - sourceFile = System.IO.Path.Combine(sourceFile, newKeyFile); - - string destFile = System.IO.Path.Combine(currentFolder, newKeyFile); - if(!System.IO.File.Exists(destFile)) - System.IO.File.Copy(sourceFile, destFile); - } - - private void ChangeToolCodeInCSharpSolutionFile(ref string fileContent, string toNetVersion) - { - if (toNetVersion == "4.5") - { - string replaceToolsString = "# Visual Studio Express 2012 for Windows Desktop"; - - string tools2008 = "# Visual Studio 2008"; - int position = fileContent.IndexOf(tools2008); - if (position > -1) - { - fileContent = fileContent.Replace(tools2008, replaceToolsString); - return; - } - - string tools2010 = "# Visual Studio 2010"; - position = fileContent.IndexOf(tools2010); - if (position > -1) - { - fileContent = fileContent.Replace(tools2010, replaceToolsString); - return; - } - } - else - { - string replaceToolsString = "# Visual C# Express 2010"; - - string tools2008 = "# Visual Studio 2008"; - int position = fileContent.IndexOf(tools2008); - if (position > -1) - { - fileContent = fileContent.Replace(tools2008, replaceToolsString); - return; - } - - string tools2010 = "# Visual Studio 2010"; - position = fileContent.IndexOf(tools2010); - if (position > -1) - { - fileContent = fileContent.Replace(tools2010, replaceToolsString); - return; - } - } - } - - private void ChangeToolCodeInVBSolutionFile(ref string fileContent, string toNetVersion) - { - if (toNetVersion == "4.5") - { - string replaceToolsString = "# Visual Studio Express 2012 for Windows Desktop"; - - string tools2008 = "# Visual Studio 2008"; - int position = fileContent.IndexOf(tools2008); - if (position > -1) - { - fileContent = fileContent.Replace(tools2008, replaceToolsString); - return; - } - - string tools2010 = "# Visual Studio 2010"; - position = fileContent.IndexOf(tools2010); - if (position > -1) - { - fileContent = fileContent.Replace(tools2010, replaceToolsString); - return; - } - } - else - { - string replaceToolsString = "# Visual Basic Express 2010"; - - string tools2008 = "# Visual Studio 2008"; - int position = fileContent.IndexOf(tools2008); - if (position > -1) - { - fileContent = fileContent.Replace(tools2008, replaceToolsString); - return; - } - - string tools2010 = "# Visual Studio 2010"; - position = fileContent.IndexOf(tools2010); - if (position > -1) - { - fileContent = fileContent.Replace(tools2010, replaceToolsString); - return; - } - } - } - - private void ChangeToolsVersionEntryInProjectFile(ref string fileContent) - { - string replacedString = ""; - replacedString = "ToolsVersion=\"4.0\""; - - string searchTools1 = "ToolsVersion=\"3.5\""; - int position = fileContent.IndexOf(searchTools1); - if (position > -1) - { - fileContent = fileContent.Replace(searchTools1, replacedString); - return; - } - } - - private void ChangeNetVersionEntryInProjectFile(ref string fileContent, string toNetVersion) - { - if (toNetVersion != "4.0") - { - fileContent = fileContent.Replace("Client", ""); - } - - - string net1 = "v2.0"; - int position = fileContent.IndexOf(net1); - if (position > -1) - { - fileContent = fileContent.Replace(net1, "v" + toNetVersion + ""); - return; - } - - string net2 = "v3.0"; - position = fileContent.IndexOf(net2); - if (position > -1) - { - fileContent = fileContent.Replace(net2, "v" + toNetVersion + ""); - return; - } - - string net3 = "v3.5"; - position = fileContent.IndexOf(net3); - if (position > -1) - { - fileContent = fileContent.Replace(net3, "v" + toNetVersion + ""); - return; - } - - string net4 = "v4.0"; - position = fileContent.IndexOf(net4); - if (position > -1) - { - fileContent = fileContent.Replace(net4, "v" + toNetVersion + ""); - return; - } - - string net5 = "v4.5"; - position = fileContent.IndexOf(net5); - if (position > -1) - { - fileContent = fileContent.Replace(net4, "v" + toNetVersion + ""); - return; - } - - } - - private void ChangeFormatVersionInSolutionFile(ref string fileContent, string toNetVersion) - { - if (toNetVersion == "4.5") - { - string replacedString = ""; - replacedString = "Format Version 12.00"; - - string tools1 = "Format Version 10.00"; // vs2008 - int position = fileContent.IndexOf(tools1); - if (position > -1) - { - fileContent = fileContent.Replace(tools1, replacedString); - return; - } - - string tools2 = "Format Version 11.00"; //vs2010 - position = fileContent.IndexOf(tools2); - if (position > -1) - { - fileContent = fileContent.Replace(tools2, replacedString); - return; - } - } - else - { - string replacedString = ""; - replacedString = "Format Version 11.00"; - - string tools1 = "Format Version 10.00"; // vs2008 - int position = fileContent.IndexOf(tools1); - if (position > -1) - { - fileContent = fileContent.Replace(tools1, replacedString); - return; - } - - string tools2 = "Format Version 12.00"; // vs2012 - position = fileContent.IndexOf(tools2); - if (position > -1) - { - fileContent = fileContent.Replace(tools2, replacedString); - return; - } - } - } - - #endregion - - #region Trigger - - private void buttonStart_Click(object sender, EventArgs e) - { - if (!CheckPrequsits()) - return; - - textBoxLog.Clear(); - string netFromVersion = GetSelectedFromNetVersion(); - string netToVersion = GetSelectedToNetVersion(); - - //change projects - string[] files = Directory.GetFiles(textBoxFolder.Text, "*.*", SearchOption.AllDirectories); - foreach (string file in files) - { - if (file.EndsWith("vbproj") || file.EndsWith("csproj")) - { - textBoxLog.AppendText("Change : " + System.IO.Path.GetFileName(file) + "\r\n"); - string fileContent = File.ReadAllText(file); - - ChangeNetVersionEntryInProjectFile(ref fileContent, netToVersion); - ChangeToolsVersionEntryInProjectFile(ref fileContent); - if (checkBoxChangeKeyFiles.Checked) - ChangeKeyFileInProjectFile(ref fileContent, System.IO.Path.GetDirectoryName(file), System.IO.Path.GetFileNameWithoutExtension(file), netToVersion); - - File.Delete(file); - File.WriteAllText(file, fileContent, Encoding.UTF8); - } - } - - //change solution - string[] slnFiles = Directory.GetFiles(textBoxFolder.Text, "*.sln", SearchOption.AllDirectories); - foreach (string slnFile in slnFiles) - { - textBoxLog.AppendText("Change : " + System.IO.Path.GetFileName(slnFile) + "\r\n"); - - string fileContent = File.ReadAllText(slnFile); - ChangeFormatVersionInSolutionFile(ref fileContent, netToVersion); - if (fileContent.IndexOf(".csproj") > -1) - ChangeToolCodeInCSharpSolutionFile(ref fileContent, netToVersion); - else if (fileContent.IndexOf(".vbproj") > -1) - ChangeToolCodeInVBSolutionFile(ref fileContent, netToVersion); - else - { - throw new IndexOutOfRangeException(); - } - - File.Delete(slnFile); - File.WriteAllText(slnFile, fileContent, Encoding.UTF8); - } - - //change net marker - if (!checkBoxChangeNetMarker.Checked) - return; - string[] allFiles = Directory.GetFiles(textBoxFolder.Text, "*.*", SearchOption.AllDirectories); - foreach (string file in allFiles) - { - if (file.EndsWith(".cs") || file.EndsWith(".csproj")) - { - string fileContent = File.ReadAllText(file); - string csMarkerSource = "CS" + netFromVersion.Replace(".", ""); - string csMarkerTarget = "CS" + netToVersion.Replace(".", ""); - if (csMarkerSource.EndsWith("0")) - csMarkerSource = csMarkerSource.Substring(0, csMarkerSource.Length - 1); - if (csMarkerTarget.EndsWith("0")) - csMarkerTarget = csMarkerTarget.Substring(0, csMarkerTarget.Length - 1); - - if (fileContent.IndexOf(csMarkerSource) > -1) - { - fileContent = fileContent.Replace(csMarkerSource, csMarkerTarget); - File.Delete(file); - File.WriteAllText(file, fileContent, Encoding.UTF8); - } - } - else if (file.EndsWith(".vb") || file.EndsWith(".vbproj")) - { - string fileContent = File.ReadAllText(file); - string vbMarkerSource = "VB" + netFromVersion.Replace(".", ""); - string vbMarkerTarget = "VB" + netToVersion.Replace(".", ""); - if (vbMarkerSource.EndsWith("0")) - vbMarkerSource = vbMarkerSource.Substring(0, vbMarkerSource.Length - 1); - if (vbMarkerTarget.EndsWith("0")) - vbMarkerTarget = vbMarkerTarget.Substring(0, vbMarkerTarget.Length - 1); - - if (fileContent.IndexOf(vbMarkerSource) > -1) - { - fileContent = fileContent.Replace(vbMarkerSource, vbMarkerTarget); - File.Delete(file); - File.WriteAllText(file, fileContent, Encoding.UTF8); - } - } - } - } - - private void buttonChooseFolder_Click(object sender, EventArgs e) - { - FolderBrowserDialog fdg = new FolderBrowserDialog(); - if (DialogResult.OK == fdg.ShowDialog(this)) - textBoxFolder.Text = fdg.SelectedPath; - } - - private void buttonLoadConfig_Click(object sender, EventArgs e) - { - try - { - OpenFileDialog dlg = new OpenFileDialog(); - dlg.InitialDirectory = Application.StartupPath; - dlg.Filter = "Xml Files(*.xml)|*.xml"; - if (dlg.ShowDialog(this) == DialogResult.Cancel) - return; - - string targetFolder = string.Empty; - bool changeNetMarker = false; - string from = string.Empty; - string to = string.Empty; - bool changeKeyFiles = false; - string keyFilesFolder = string.Empty; - - ConfigManager.LoadConfigurationFromConfigFile(dlg.FileName, ref targetFolder, ref changeNetMarker, ref from, ref to, ref changeKeyFiles, ref keyFilesFolder); - - textBoxFolder.Text = targetFolder; - checkBoxChangeNetMarker.Checked = changeNetMarker; - comboBoxFromNetVersion.Text = from; - comboBoxToNetVersion.Text = to; - checkBoxChangeKeyFiles.Checked = changeKeyFiles; - textBoxKeyFilesRootFolder.Text = keyFilesFolder; - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - private void buttonSaveConfig_Click(object sender, EventArgs e) - { - try - { - SaveFileDialog dlg = new SaveFileDialog(); - dlg.InitialDirectory = Application.StartupPath; - dlg.Filter = "Xml Files(*.xml)|*.xml"; - if (dlg.ShowDialog(this) == DialogResult.Cancel) - return; - - ConfigManager.SaveConfigurationToXMLFile(dlg.FileName, textBoxFolder.Text, checkBoxChangeNetMarker.Checked, comboBoxFromNetVersion.Text, comboBoxToNetVersion.Text, checkBoxChangeKeyFiles.Checked, textBoxKeyFilesRootFolder.Text); - } - catch (Exception exception) - { - ExceptionDisplayer.ShowException(this, exception); - } - } - - #endregion - } -} diff --git a/BuildTools/VersionUpdater/Form1.resx b/BuildTools/VersionUpdater/Form1.resx deleted file mode 100644 index 1af7de150..000000000 --- a/BuildTools/VersionUpdater/Form1.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/VersionUpdater/NOBuildTools.VersionUpdater.csproj b/BuildTools/VersionUpdater/NOBuildTools.VersionUpdater.csproj deleted file mode 100644 index 6c5169d8e..000000000 --- a/BuildTools/VersionUpdater/NOBuildTools.VersionUpdater.csproj +++ /dev/null @@ -1,124 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {3CDA84DA-CC00-49FE-B05F-EB12E38E5AF1} - WinExe - Properties - NOBuildTools.VersionUpdater - NOBuildTools.VersionUpdater - v4.0 - 512 - - - 3.5 - - Client - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - - - - - - - - - - - - - - - Form - - - Form1.cs - - - - - Form1.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - \ No newline at end of file diff --git a/BuildTools/VersionUpdater/Program.cs b/BuildTools/VersionUpdater/Program.cs deleted file mode 100644 index ff86639dc..000000000 --- a/BuildTools/VersionUpdater/Program.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Windows.Forms; - -namespace NOBuildTools.VersionUpdater -{ - static class Program - { - /// - /// The main entry point for the application. - /// - [STAThread] - static void Main() - { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new Form1()); - } - } -} diff --git a/BuildTools/VersionUpdater/Properties/AssemblyInfo.cs b/BuildTools/VersionUpdater/Properties/AssemblyInfo.cs deleted file mode 100644 index 09645156b..000000000 --- a/BuildTools/VersionUpdater/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("NOBuildTools.VersionUpdater")] -[assembly: AssemblyDescription("Change the .NET/version in VS Solutions/Projects")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("http://netoffice.codeplex.com")] -[assembly: AssemblyCopyright("Copyright 2011 © Sebastian Lange")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("dcfb10e2-d7d1-49dd-ba2a-09f3a044c08d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/BuildTools/VersionUpdater/Properties/Resources.Designer.cs b/BuildTools/VersionUpdater/Properties/Resources.Designer.cs deleted file mode 100644 index c2b7fc9b8..000000000 --- a/BuildTools/VersionUpdater/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.VersionUpdater.Properties { - using System; - - - /// - /// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - /// - // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NOBuildTools.VersionUpdater.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - /// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/BuildTools/VersionUpdater/Properties/Resources.resx b/BuildTools/VersionUpdater/Properties/Resources.resx deleted file mode 100644 index af7dbebba..000000000 --- a/BuildTools/VersionUpdater/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/BuildTools/VersionUpdater/Properties/Settings.Designer.cs b/BuildTools/VersionUpdater/Properties/Settings.Designer.cs deleted file mode 100644 index e44624b39..000000000 --- a/BuildTools/VersionUpdater/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Dieser Code wurde von einem Tool generiert. -// Laufzeitversion:4.0.30319.1 -// -// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -// der Code erneut generiert wird. -// -//------------------------------------------------------------------------------ - -namespace NOBuildTools.VersionUpdater.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/BuildTools/VersionUpdater/Properties/Settings.settings b/BuildTools/VersionUpdater/Properties/Settings.settings deleted file mode 100644 index 39645652a..000000000 --- a/BuildTools/VersionUpdater/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/BuildTools/VersionUpdater/app.config b/BuildTools/VersionUpdater/app.config deleted file mode 100644 index a293d0a0e..000000000 --- a/BuildTools/VersionUpdater/app.config +++ /dev/null @@ -1,3 +0,0 @@ - - - From 610171a885e37bbe1f444798c3e273ae722dd8b7 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Fri, 2 Jan 2026 16:03:01 +0100 Subject: [PATCH 17/29] Fix `.gitignore` patterns to correctly exclude folders (#451) --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index aabe096a0..21d8c786c 100755 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ NetOffice*.rar ReferenceIndex*.rar Assemblies/ Any\ CPU/ -Current\ Binaries\ -Persistance\ Cache*\ +Current\ Binaries/ +Persistance\ Cache*/ Toolbox/Libs/ ..svnbridge/ out/ From 917818881bf15f481cc5843347ca8ba747a69316 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Fri, 30 Jan 2026 23:25:12 +0100 Subject: [PATCH 18/29] Fix bug in `DocumentEvents2` sink implementation of the `ContentControlBeforeContentUpdate` event --- Source/NetOffice.Tests/NetOffice.Tests.csproj | 1 + .../Events/DocumentEvents2_SinkHelperTests.cs | 45 +++++++++++++++++++ Source/NetOffice.Tests/packages.lock.json | 9 ++++ Source/Word/Events/DocumentEvents2.cs | 2 +- 4 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 Source/NetOffice.Tests/WordApi/Events/DocumentEvents2_SinkHelperTests.cs diff --git a/Source/NetOffice.Tests/NetOffice.Tests.csproj b/Source/NetOffice.Tests/NetOffice.Tests.csproj index 8c93ec14b..f9e693a99 100644 --- a/Source/NetOffice.Tests/NetOffice.Tests.csproj +++ b/Source/NetOffice.Tests/NetOffice.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/Source/NetOffice.Tests/WordApi/Events/DocumentEvents2_SinkHelperTests.cs b/Source/NetOffice.Tests/WordApi/Events/DocumentEvents2_SinkHelperTests.cs new file mode 100644 index 000000000..6bf13cc76 --- /dev/null +++ b/Source/NetOffice.Tests/WordApi/Events/DocumentEvents2_SinkHelperTests.cs @@ -0,0 +1,45 @@ +// Copyright 2024 Cisco Systems, Inc. +// Licensed under MIT-style license (see LICENSE.txt file). + +using System; +using NetOffice.WordApi; +using NetOffice.WordApi.Events; +using NetOffice.Tests.Helpers; +using NUnit.Framework; + +namespace NetOffice.Tests.WordApi.Events +{ + [TestFixture] + public class DocumentEvents2_SinkHelperTests + { + /// + /// Regression test for #453 - Ensures ContentControlBeforeContentUpdate event uses correct event name + /// in both Validate() and EventBinding.RaiseCustomEvent() calls + /// + [Test] + public void ContentControlBeforeContentUpdate_EventRaised_CallsHandlerWithCorrectEventName() + { + // Arrange + var eventBinder = new TestableComObjectStub(); + eventBinder.AddEventRecipient(nameof(DocumentEvents2_SinkHelper.ContentControlBeforeContentUpdate)); + var connectionPoint = new ConnectionPointStub(); + + var events = new DocumentEvents2_SinkHelper(eventBinder, connectionPoint); + var parameter1 = new FakeComObject(); + var content = new object(); + + // Act + events.ContentControlBeforeContentUpdate(parameter1, ref content); + var actualParametersPassToEvent = eventBinder.LastRaisedEventParameters; + + // Assert + Assert.AreEqual("ContentControlBeforeContentUpdate", eventBinder.LastRaisedEventName, + "EventBinding.RaiseCustomEvent must be called with 'ContentControlBeforeContentUpdate' event name"); + + CollectionAssert.IsNotEmpty(actualParametersPassToEvent); + var actualParameter1 = actualParametersPassToEvent[0]; + Assert.IsInstanceOf(actualParameter1, + "Event ContentControlBeforeContentUpdate parameter must be of type ContentControl."); + } + } +} diff --git a/Source/NetOffice.Tests/packages.lock.json b/Source/NetOffice.Tests/packages.lock.json index 12724d173..b0d202f5e 100644 --- a/Source/NetOffice.Tests/packages.lock.json +++ b/Source/NetOffice.Tests/packages.lock.json @@ -142,6 +142,15 @@ "NetOfficeFw.Core": "[1.9.3, )", "NetOfficeFw.Office": "[1.9.3, )" } + }, + "NetOfficeFw.Word": { + "type": "Project", + "dependencies": { + "NetOfficeFw.Core": "[1.9.3, )", + "NetOfficeFw.Office": "[1.9.3, )", + "NetOfficeFw.VBIDE": "[1.9.3, )", + "stdole": "[7.0.3300, )" + } } } } diff --git a/Source/Word/Events/DocumentEvents2.cs b/Source/Word/Events/DocumentEvents2.cs index 610253fef..4b23b6e7d 100644 --- a/Source/Word/Events/DocumentEvents2.cs +++ b/Source/Word/Events/DocumentEvents2.cs @@ -279,7 +279,7 @@ public void ContentControlBeforeStoreUpdate([In, MarshalAs(UnmanagedType.IDispat public void ContentControlBeforeContentUpdate([In, MarshalAs(UnmanagedType.IDispatch)] object contentControl, [In] [Out] ref object content) { - if (!Validate("ContentControlBeforeStoreUpdate")) + if (!Validate("ContentControlBeforeContentUpdate")) { Invoker.ReleaseParamsArray(contentControl, content); return; From de31b5b10501c45abb171782bf117034c8ffb165 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Fri, 30 Jan 2026 23:34:37 +0100 Subject: [PATCH 19/29] Update changelog for v1.9.8 with the fix for `ContentControlBeforeContentUpdate` event --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3418aadac..cea68308b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.9.8 + +### Fixed +* Fix bug in `ContentControlBeforeContentUpdate` code by verifying the correct event name [#454](https://github.com/NetOfficeFw/NetOffice/pull/454) + + ## v1.9.7 ### Added From cd6392bea41e3af517384ec1103b78689c3d82e7 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:32:56 +0100 Subject: [PATCH 20/29] Bump NetOffice libraries to v1.9.8 --- Source/NetOffice.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NetOffice.props b/Source/NetOffice.props index 59cce4aa0..47f2bb411 100644 --- a/Source/NetOffice.props +++ b/Source/NetOffice.props @@ -1,7 +1,7 @@  - 1.9.7 + 1.9.8 From 655b1d8dcac3eab165a53205fa69c7f67ef0e37b Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:26:50 +0100 Subject: [PATCH 21/29] Run `build` workflow on more branches --- .github/workflows/tests.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index ef6b8ec58..1a117263d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -5,8 +5,11 @@ on: push: branches: - 'main' - - 'dev/*' - - 'releases/*' + - 'bugfix/**' + - 'dev/**' + - 'feature/**' + - 'tests/**' + - 'releases/**' permissions: contents: read From 9ca2482a07acb1b4f1d8ce47153db3583ffd1103 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:30:11 +0100 Subject: [PATCH 22/29] Update GitHub actions packages --- .github/workflows/labels.yml | 2 +- .github/workflows/release.yml | 14 +++++++------- .github/workflows/tests.yml | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 75892cade..8ecfd748a 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -14,7 +14,7 @@ jobs: labels: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: gitlabels/gitlabels@v2 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index abd22187b..14562ed0a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup dotnet uses: actions/setup-dotnet@v5 @@ -45,7 +45,7 @@ jobs: uses: microsoft/setup-msbuild@v2 - name: Cache dotnet tools - uses: actions/cache@v4 + uses: actions/cache@v5 id: cache-dotnettools with: path: ~/.dotnet/tools @@ -60,7 +60,7 @@ jobs: run: dotnet tool install --verbosity minimal --global Knapcode.CertificateExtractor --version 0.1.1 - name: Cache packages - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.nuget/packages key: NetOffice-nuget-${{ hashFiles('**/packages.lock.json') }} @@ -118,7 +118,7 @@ jobs: timestamp-digest: SHA256 - name: Archive NetOffice binaries - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: NetOffice_binaries_v${{ steps.build.outputs.app_version_full }}_${{ matrix.configuration }} path: '${{ github.workspace }}\Source\ClientApplication\bin\${{ matrix.configuration }}' @@ -152,14 +152,14 @@ jobs: - name: Archive NetOffice packages if: success() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: ${{ steps.build.outputs.nuget_packages_artifact_name }} path: '${{ github.workspace }}\dist' - name: Archive code signing certificate if: success() && matrix.configuration == 'Release' - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: certificate path: '${{ github.workspace }}/dist/*.cer' @@ -184,7 +184,7 @@ jobs: steps: - name: Download NetOffice packages - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: name: ${{ needs.release.outputs.nuget_packages_artifact_name }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1a117263d..26cfa2ee6 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup dotnet uses: actions/setup-dotnet@v5 @@ -45,7 +45,7 @@ jobs: uses: microsoft/setup-msbuild@v2 - name: Cache packages - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ~/.nuget/packages key: NetOffice-nuget-${{ hashFiles('**/packages.lock.json') }} @@ -69,7 +69,7 @@ jobs: VersionSuffix: ${{ steps.build.outputs.app_version_suffix }} - name: Archive NetOffice binaries - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: NetOffice_binaries_v${{ steps.build.outputs.app_version_full }}_${{ matrix.configuration }} path: '${{ github.workspace }}\Source\ClientApplication\bin\${{ matrix.configuration }}' From 21ab5947a2d77e354c53315815ce1dee24b5f2e7 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:45:24 +0100 Subject: [PATCH 23/29] Use `azure/artifact-signing-action` action to sign libraries (#456) The `azure/trusted-signing-action` was rebranded to `azure/artifact-signing-action`. --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14562ed0a..7500652dc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -92,10 +92,10 @@ jobs: - name: Sign NetOffice libraries if: success() && steps.build.outputs.sign_binaries == 'true' - uses: azure/trusted-signing-action@v0.5.10 + uses: azure/artifact-signing-action@v1 with: endpoint: ${{ secrets.TRUSTED_SIGNING_ENDPOINT }} - trusted-signing-account-name: ${{ secrets.TRUSTED_SIGNING_ACCOUNT_NAME }} + signing-account-name: ${{ secrets.TRUSTED_SIGNING_ACCOUNT_NAME }} certificate-profile-name: ${{ secrets.TRUSTED_SIGNING_CERTIFICATE_PROFILE }} files-catalog: '${{ github.workspace }}/obj/signlist.txt' files: | From 0690ec6970dcd48df9de544d666bf002c1429ad1 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:46:57 +0100 Subject: [PATCH 24/29] Run builds on Windows Server 2025 --- .github/workflows/release.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7500652dc..bed6b498f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: release: environment: production - runs-on: windows-2022 + runs-on: windows-2025 strategy: matrix: diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 26cfa2ee6..4e5448765 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,7 +16,7 @@ permissions: jobs: tests: - runs-on: windows-2022 + runs-on: windows-2025 strategy: matrix: From 67eafb6fdd91715702fcf8090413fe507680a047 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 12:53:32 +0100 Subject: [PATCH 25/29] NetOffice v1.9.8 release From c96b5ca2a66d1558e94d4774daf2bf44e8fac01a Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 13:05:36 +0100 Subject: [PATCH 26/29] Use `BUILD_SIGN_RELEASE` env variable to dynamically configure release signing for build environment --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bed6b498f..c07c5bb7a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,6 +23,7 @@ jobs: DOTNET_NOLOGO: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_GENERATE_ASPNET_CERTIFICATE: 0 + BUILD_SIGN_RELEASE: '${{ vars.BUILD_SIGN_RELEASE }}' ContinuousIntegrationBuild: true RestoreLockedMode: true RepositoryBranch: '${{ github.ref_name }}' From a15cf657cf29aa5a8b40e2330d5138366bb245a7 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 13:11:03 +0100 Subject: [PATCH 27/29] Improve documentation for publishing signed nuget packages --- .github/workflows/release.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c07c5bb7a..6d3dd1db7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -160,6 +160,7 @@ jobs: - name: Archive code signing certificate if: success() && matrix.configuration == 'Release' + id: certificate_artifact uses: actions/upload-artifact@v6 with: name: certificate @@ -168,9 +169,12 @@ jobs: - name: Release documentation if: matrix.configuration == 'Release' run: | + $certUrl = '${{ steps.certificate_artifact.outputs.artifact-url }}' 'To release the NuGet package, upload the signing certificate to NuGet Gallery via Account Settings: . ' >> $env:GITHUB_STEP_SUMMARY 'See the `certificate` artifact for the signing certificate file.' >> $env:GITHUB_STEP_SUMMARY '' >> $env:GITHUB_STEP_SUMMARY + 'Download the [certiticate file]($certUrl).' >> $env:GITHUB_STEP_SUMMARY + '' >> $env:GITHUB_STEP_SUMMARY 'Approve the `publish` job deployment to the `nuget-gallery` environment when the certificate was added to NuGet Gallery.' >> $env:GITHUB_STEP_SUMMARY publish: From 2e37894eaa89c32a4cd586cf5f8c66842d80a23f Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 13:13:22 +0100 Subject: [PATCH 28/29] NetOffice v1.9.8 release From fc76da278e08074f94232266d15a36af84606286 Mon Sep 17 00:00:00 2001 From: Jozef Izso Date: Sat, 21 Feb 2026 13:55:46 +0100 Subject: [PATCH 29/29] Fix the certificate download link --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d3dd1db7..93a899ea5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -173,7 +173,7 @@ jobs: 'To release the NuGet package, upload the signing certificate to NuGet Gallery via Account Settings: . ' >> $env:GITHUB_STEP_SUMMARY 'See the `certificate` artifact for the signing certificate file.' >> $env:GITHUB_STEP_SUMMARY '' >> $env:GITHUB_STEP_SUMMARY - 'Download the [certiticate file]($certUrl).' >> $env:GITHUB_STEP_SUMMARY + "Download the [certiticate file]($certUrl)." >> $env:GITHUB_STEP_SUMMARY '' >> $env:GITHUB_STEP_SUMMARY 'Approve the `publish` job deployment to the `nuget-gallery` environment when the certificate was added to NuGet Gallery.' >> $env:GITHUB_STEP_SUMMARY