This commit is contained in:
Matteo Pagani 2021-02-10 22:22:14 +01:00
Родитель e6fc99f930
Коммит 642129dd5a
37 изменённых файлов: 3281 добавлений и 549 удалений

Просмотреть файл

@ -1,145 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6C859FC9-03B3-4D7D-B83E-A276457C80F6}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>MyEmployees</RootNamespace>
<AssemblyName>MyEmployees</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>contoso_5Ob_icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="CsvHelper, Version=9.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.9.0.0\lib\net45\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Data.SQLite, Version=1.0.109.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\packages\System.Data.SQLite.Core.1.0.109.2\lib\net46\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AboutForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="AboutForm.Designer.cs">
<DependentUpon>AboutForm.cs</DependentUpon>
</Compile>
<Compile Include="Config.cs" />
<Compile Include="Entities\Employee.cs" />
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="AboutForm.resx">
<DependentUpon>AboutForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="config.json" />
<Content Include="contoso_5Ob_icon.ico" />
<Content Include="Employees.db">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="NLog.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<None Include="packages.config" />
<None Include="Properties\DataSources\LobApp.Entities.Employee.datasource">
<SubType>Designer</SubType>
</None>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyEmployees.PluginInterface\MyEmployees.PluginInterface.csproj">
<Project>{a8814208-9b34-41c9-b0d0-b31a6c11af27}</Project>
<Name>MyEmployees.PluginInterface</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.109.2\build\net46\System.Data.SQLite.Core.targets'))" />
</Target>
</Project>

Просмотреть файл

@ -1,165 +0,0 @@
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="NuGetUpgradeReportTitle">
NuGetMigrationLog
</title><style>
/* Body style, for the entire document */
body
{
background: #F3F3F4;
color: #1E1E1F;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
font-size: 12pt;
padding: 0;
margin: 0;
}
/* Header1 style, used for the main title */
h1
{
padding: 10px 0px 10px 10px;
font-size: 21pt;
background-color: #E2E2E2;
border-bottom: 1px #C1C1C2 solid;
color: #201F20;
margin: 0;
font-weight: normal;
}
/* Header2 style, used for "Overview" and other sections */
h2
{
font-size: 18pt;
font-weight: normal;
padding: 15px 0 5px 0;
margin: 0;
}
/* Header3 style, used for sub-sections, such as project name */
h3
{
font-weight: normal;
font-size: 15pt;
margin: 0;
padding: 15px 0 5px 0;
background-color: transparent;
}
.info-text
{
margin: 0px 0 0.75em 0;
}
/* Color all hyperlinks one color */
a
{
color: #1382CE;
}
/* Table styles */
table
{
border-spacing: 0 0;
border-collapse: collapse;
font-size: 11pt;
}
table th
{
background: #E7E7E8;
text-align: left;
text-decoration: none;
font-weight: normal;
padding: 3px 6px 3px 6px;
}
table td
{
vertical-align: top;
padding: 3px 6px 5px 5px;
margin: 0px;
border: 1px solid #E7E7E8;
background: #F7F7F8;
}
/* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
.localLink
{
color: #1E1E1F;
background: #EEEEED;
text-decoration: none;
}
.localLink:hover
{
color: #1382CE;
background: #FFFF99;
text-decoration: none;
}
.issueCell
{
width: 100%;
}
.packageIssue
{
margin-left: 25px;
}
/* Padding around the content after the h1 */
#content
{
padding: 0px 20px 20px 20px;
}
.issues table
{
width: 97%;
}
/* All Icons */
.IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
{
min-width:18px;
min-height:18px;
background-repeat:no-repeat;
background-position:center;
}
.IconSuccessEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
}
.IconInfoEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
}
.IconWarningEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
}
.IconErrorEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
}
</style></head><body><h1>
NuGet Migration Report - MyEmployees</h1><div id="content"><h2 _locID="OverviewTitle">Overview</h2><div class="info-text">Migration to PackageReference was completed successfully. Please build and run your solution to verify that all packages are available.</div><div class="info-text">
If you run into any problems, have feedback, questions, or concerns, please
<a href="https://github.com/NuGet/Home/issues/">file an issue on the NuGet GitHub repository.</a></div><div class="info-text">
Changed files and this report have been backed up here:
<a href="C:\Users\mpagani\Source\AppConsult\Windows-AppConsult-Samples-DesktopBridge\Blog-OptionalPackages\MyEmployees-OptionalPackages\MigrationBackup\6b3d387a\MyEmployees">C:\Users\mpagani\Source\AppConsult\Windows-AppConsult-Samples-DesktopBridge\Blog-OptionalPackages\MyEmployees-OptionalPackages\MigrationBackup\6b3d387a\MyEmployees</a></div><div class="info-text"><a href="https://aka.ms/nuget-pc2pr-migrator-rollback">Help me rollback to packages.config</a></div><h2 _locID="PackagesTitle">Packages processed</h2><h3 _locID="IncludePackagesTitle">Top-level dependencies:</h3><div class="issues"><table><tr><th class="issueCell">Package Id</th><th>Version</th></tr><tr><td class="issueCell"><span>CsvHelper</span></td><td><span>
v9.0.0</span></td></tr><tr><td class="issueCell"><span>Newtonsoft.Json</span></td><td><span>
v12.0.1</span></td></tr><tr><td class="issueCell"><span>System.Data.SQLite.Core</span></td><td><span>
v1.0.109.2</span></td></tr><tr><td class="issueCell"><span>System.ValueTuple</span></td><td><span>
v4.5.0</span></td></tr></table></div><p /><h3 _locID="IncludePackagesTitle">Transitive dependencies:</h3><div class="issues"><table><tr><th class="issueCell">Package Id</th><th>Version</th></tr><tr><td class="issueCell">
No transitive dependencies found.
</td><td /></tr></table></div><h2 _locID="IssuesTitle">Package compatibility issues</h2><div class="issues"><table><tr><th /><th class="issueCell" _locID="DescriptionTableHeader">Description</th></tr><tr><td class="IconInfoEncoded" /><td class="issueCell">
No issues were found.
</td></tr></table></div></div></body></html>

Просмотреть файл

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CsvHelper" version="9.0.0" targetFramework="net472" />
<package id="Newtonsoft.Json" version="12.0.1" targetFramework="net472" />
<package id="System.Data.SQLite.Core" version="1.0.109.2" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
</packages>

Просмотреть файл

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CE812A43-7F69-4361-9B0B-43AA20739446}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ExportDataLibrary</RootNamespace>
<AssemblyName>ExportDataLibrary</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="CsvHelper, Version=9.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\packages\CsvHelper.9.0.0\lib\net45\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ExportData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MyEmployees.PluginInterface\MyEmployees.PluginInterface.csproj">
<Project>{a8814208-9b34-41c9-b0d0-b31a6c11af27}</Project>
<Name>MyEmployees.PluginInterface</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Просмотреть файл

@ -1,163 +0,0 @@
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="NuGetUpgradeReportTitle">
NuGetMigrationLog
</title><style>
/* Body style, for the entire document */
body
{
background: #F3F3F4;
color: #1E1E1F;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
font-size: 12pt;
padding: 0;
margin: 0;
}
/* Header1 style, used for the main title */
h1
{
padding: 10px 0px 10px 10px;
font-size: 21pt;
background-color: #E2E2E2;
border-bottom: 1px #C1C1C2 solid;
color: #201F20;
margin: 0;
font-weight: normal;
}
/* Header2 style, used for "Overview" and other sections */
h2
{
font-size: 18pt;
font-weight: normal;
padding: 15px 0 5px 0;
margin: 0;
}
/* Header3 style, used for sub-sections, such as project name */
h3
{
font-weight: normal;
font-size: 15pt;
margin: 0;
padding: 15px 0 5px 0;
background-color: transparent;
}
.info-text
{
margin: 0px 0 0.75em 0;
}
/* Color all hyperlinks one color */
a
{
color: #1382CE;
}
/* Table styles */
table
{
border-spacing: 0 0;
border-collapse: collapse;
font-size: 11pt;
}
table th
{
background: #E7E7E8;
text-align: left;
text-decoration: none;
font-weight: normal;
padding: 3px 6px 3px 6px;
}
table td
{
vertical-align: top;
padding: 3px 6px 5px 5px;
margin: 0px;
border: 1px solid #E7E7E8;
background: #F7F7F8;
}
/* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
.localLink
{
color: #1E1E1F;
background: #EEEEED;
text-decoration: none;
}
.localLink:hover
{
color: #1382CE;
background: #FFFF99;
text-decoration: none;
}
.issueCell
{
width: 100%;
}
.packageIssue
{
margin-left: 25px;
}
/* Padding around the content after the h1 */
#content
{
padding: 0px 20px 20px 20px;
}
.issues table
{
width: 97%;
}
/* All Icons */
.IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
{
min-width:18px;
min-height:18px;
background-repeat:no-repeat;
background-position:center;
}
.IconSuccessEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
}
.IconInfoEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
}
.IconWarningEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
}
.IconErrorEncoded
{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
}
</style></head><body><h1>
NuGet Migration Report - ExportDataLibrary</h1><div id="content"><h2 _locID="OverviewTitle">Overview</h2><div class="info-text">Migration to PackageReference was completed successfully. Please build and run your solution to verify that all packages are available.</div><div class="info-text">
If you run into any problems, have feedback, questions, or concerns, please
<a href="https://github.com/NuGet/Home/issues/">file an issue on the NuGet GitHub repository.</a></div><div class="info-text">
Changed files and this report have been backed up here:
<a href="C:\Users\mpagani\Source\AppConsult\Windows-AppConsult-Samples-DesktopBridge\Blog-OptionalPackages\MyEmployees-OptionalPackages\MigrationBackup\7b3c193f\ExportDataLibrary">C:\Users\mpagani\Source\AppConsult\Windows-AppConsult-Samples-DesktopBridge\Blog-OptionalPackages\MyEmployees-OptionalPackages\MigrationBackup\7b3c193f\ExportDataLibrary</a></div><div class="info-text"><a href="https://aka.ms/nuget-pc2pr-migrator-rollback">Help me rollback to packages.config</a></div><h2 _locID="PackagesTitle">Packages processed</h2><h3 _locID="IncludePackagesTitle">Top-level dependencies:</h3><div class="issues"><table><tr><th class="issueCell">Package Id</th><th>Version</th></tr><tr><td class="issueCell"><span>CsvHelper</span></td><td><span>
v9.0.0</span></td></tr><tr><td class="issueCell"><span>System.ValueTuple</span></td><td><span>
v4.5.0</span></td></tr></table></div><p /><h3 _locID="IncludePackagesTitle">Transitive dependencies:</h3><div class="issues"><table><tr><th class="issueCell">Package Id</th><th>Version</th></tr><tr><td class="issueCell">
No transitive dependencies found.
</td><td /></tr></table></div><h2 _locID="IssuesTitle">Package compatibility issues</h2><div class="issues"><table><tr><th /><th class="issueCell" _locID="DescriptionTableHeader">Description</th></tr><tr><td class="IconInfoEncoded" /><td class="issueCell">
No issues were found.
</td></tr></table></div></div></body></html>

Просмотреть файл

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CsvHelper" version="9.0.0" targetFramework="net472" />
<package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
</packages>

63
Docs-ContextMenuSample/.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

340
Docs-ContextMenuSample/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,340 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb

Просмотреть файл

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>6378d9d6-b2ed-4fc7-a42e-e5903c700764</ProjectGuid>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\ContextMenuSample\ContextMenuSample.csproj</EntryPointProjectUniqueName>
<PackageCertificateThumbprint>7F0254FEC8E115DD807FEAA8553D3953E7B770E7</PackageCertificateThumbprint>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateKeyFile>ContextMenuSample.Package_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<AppxBundle>Never</AppxBundle>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<None Include="ContextMenuSample.Package_TemporaryKey.pfx" />
<Content Include="ExplorerCommandVerb.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ContextMenuSample\ContextMenuSample.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
</Project>

Двоичный файл не отображается.

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Просмотреть файл

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap2="http://schemas.microsoft.com/appx/manifest/uap/windows10/2"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
xmlns:desktop4="http://schemas.microsoft.com/appx/manifest/desktop/windows10/4"
xmlns:desktop5="http://schemas.microsoft.com/appx/manifest/desktop/windows10/5"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
IgnorableNamespaces="uap uap2 uap3 rescap desktop desktop4 desktop5">
<Identity
Name="ContextMenuSample"
Publisher="CN=Windows AppConsult"
Version="1.0.2.0" />
<Properties>
<DisplayName>ContextMenu Sample</DisplayName>
<PublisherDisplayName>Windows AppConsult</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="ContextMenu Sample"
Description="ContextMenuSample.Package"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<uap3:Extension Category="windows.fileTypeAssociation">
<uap3:FileTypeAssociation Name="foo" Parameters="&quot;%1&quot;">
<uap:SupportedFileTypes>
<uap:FileType>.foo</uap:FileType>
</uap:SupportedFileTypes>
<uap2:SupportedVerbs>
<uap3:Verb Id="Resize" Parameters="&quot;%1&quot;">Resize file</uap3:Verb>
</uap2:SupportedVerbs>
</uap3:FileTypeAssociation>
</uap3:Extension>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:SurrogateServer DisplayName="ContextMenuSample">
<com:Class Id="CC19E147-7757-483C-B27F-3D81BCEB38FE" Path="ExplorerCommandVerb.dll" ThreadingModel="STA"/>
</com:SurrogateServer>
</com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
<desktop4:FileExplorerContextMenus>
<desktop5:ItemType Type="Directory">
<desktop5:Verb Id="Command1" Clsid="CC19E147-7757-483C-B27F-3D81BCEB38FE" />
</desktop5:ItemType>
</desktop4:FileExplorerContextMenus>
</desktop4:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="protocolname"/>
</uap:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

Просмотреть файл

@ -0,0 +1,97 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30406.217
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContextMenuSample", "ContextMenuSample\ContextMenuSample.csproj", "{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "ContextMenuSample.Package", "ContextMenuSample.Package\ContextMenuSample.Package.wapproj", "{6378D9D6-B2ED-4FC7-A42E-E5903C700764}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerCommandVerb", "ExplorerCommandVerb\ExplorerCommandVerb.vcxproj", "{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|ARM.Build.0 = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|ARM64.Build.0 = Debug|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|x64.ActiveCfg = Debug|x64
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|x64.Build.0 = Debug|x64
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|x86.ActiveCfg = Debug|x86
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Debug|x86.Build.0 = Debug|x86
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|Any CPU.Build.0 = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|ARM.ActiveCfg = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|ARM.Build.0 = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|ARM64.ActiveCfg = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|ARM64.Build.0 = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|x64.ActiveCfg = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|x64.Build.0 = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|x86.ActiveCfg = Release|Any CPU
{F944BE89-7FF8-4BDB-B419-DFAD9BCDBCAC}.Release|x86.Build.0 = Release|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM.ActiveCfg = Debug|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM.Build.0 = Debug|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM.Deploy.0 = Debug|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM64.ActiveCfg = Debug|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM64.Build.0 = Debug|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|ARM64.Deploy.0 = Debug|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x64.ActiveCfg = Debug|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x64.Build.0 = Debug|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x64.Deploy.0 = Debug|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x86.ActiveCfg = Debug|x86
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x86.Build.0 = Debug|x86
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Debug|x86.Deploy.0 = Debug|x86
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|Any CPU.Build.0 = Release|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|Any CPU.Deploy.0 = Release|Any CPU
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM.ActiveCfg = Release|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM.Build.0 = Release|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM.Deploy.0 = Release|ARM
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM64.ActiveCfg = Release|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM64.Build.0 = Release|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|ARM64.Deploy.0 = Release|ARM64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x64.ActiveCfg = Release|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x64.Build.0 = Release|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x64.Deploy.0 = Release|x64
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x86.ActiveCfg = Release|x86
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x86.Build.0 = Release|x86
{6378D9D6-B2ED-4FC7-A42E-E5903C700764}.Release|x86.Deploy.0 = Release|x86
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|Any CPU.ActiveCfg = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|ARM.ActiveCfg = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|ARM64.ActiveCfg = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x64.ActiveCfg = Debug|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x64.Build.0 = Debug|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x86.ActiveCfg = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x86.Build.0 = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|Any CPU.ActiveCfg = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|ARM.ActiveCfg = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|ARM64.ActiveCfg = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x64.ActiveCfg = Release|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x64.Build.0 = Release|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x86.ActiveCfg = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {450CE318-9428-4582-9D15-CB639AF97509}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,8 @@
<Application x:Class="ContextMenuSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ContextMenuSample">
<Application.Resources>
</Application.Resources>
</Application>

Просмотреть файл

@ -0,0 +1,23 @@
using System;
using System.Windows;
namespace ContextMenuSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
public string FilePath { get; set; }
protected override void OnStartup(StartupEventArgs e)
{
if (e.Args.Length > 0)
{
FilePath = e.Args[0];
}
this.StartupUri = new Uri("MainWindow.xaml", UriKind.Relative);
}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

Просмотреть файл

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<UseWPF>true</UseWPF>
<Platforms>AnyCPU;x86;x64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64</RuntimeIdentifiers>
</PropertyGroup>
</Project>

Просмотреть файл

@ -0,0 +1,21 @@
<Window x:Class="ContextMenuSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ContextMenuSample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<TextBlock Text="This is a sample application that registers a context menu"
FontSize="30"
HorizontalAlignment="Center"
VerticalAlignment="Center"
/>
<TextBlock x:Name="txtFilePath"
FontSize="22"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>
</Window>

Просмотреть файл

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ContextMenuSample
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
string path = (Application.Current as App).FilePath;
txtFilePath.Text = path;
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
EXPORTS
DllCanUnloadNow PRIVATE
DllGetClassObject PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE

Просмотреть файл

@ -0,0 +1,25 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "ShellHelpers.h"
#include "RegisterExtension.h"
#include <strsafe.h>
#include <new> // std::nothrow
void DllAddRef();
void DllRelease();
// use UUDIGEN.EXE to generate unique CLSID values for your objects
class __declspec(uuid("CC19E147-7757-483C-B27F-3D81BCEB38FE")) CExplorerCommandVerb;
class __declspec(uuid("5A777238-07F9-42AB-B074-4004F1ED74A9")) CExplorerCommandStateHandler;
HRESULT CExplorerCommandVerb_CreateInstance(REFIID riid, void **ppv);
HRESULT CExplorerCommandStateHandler_CreateInstance(REFIID riid, void **ppv);
HRESULT CExplorerCommandVerb_RegisterUnRegister(bool fRegister);
HRESULT CExplorerCommandStateHandler_RegisterUnRegister(bool fRegister);

Просмотреть файл

@ -0,0 +1,149 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
// ExplorerCommandState handlers are not a verb implementation method, it is a way to give a dynamic
// behavior to a static verb implementation, that is show or not. This handler is run on a background thread
// to avoid UI hangs. So, for example you can combine it with ExecuteCommand, DropTarget or CreateProcess
// verb to give them dynamic behavior. Only use this method if you cannot express your dynamic behavior
// using an AQS expression. There is a limitation to this in that this cannot be used on the default verb.
#include "Dll.h"
class CExplorerCommandStateHandler
: public IExplorerCommandState, public IInitializeCommand
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] =
{
QITABENT(CExplorerCommandStateHandler, IExplorerCommandState), // required
QITABENT(CExplorerCommandStateHandler, IInitializeCommand), // optional
// QITABENT(CExplorerCommandStateHandler, IObjectWithSite), // optional. the site can be used to get the explorer browser or view. not implemented in this sample
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&_cRef);
}
IFACEMETHODIMP_(ULONG) Release()
{
long cRef = InterlockedDecrement(&_cRef);
if (!cRef)
{
delete this;
}
return cRef;
}
// IExplorerCommandState
// compute the visibility of the verb here, respect "fOkToBeSlow" if this is slow
// when called with fOkToBeSlow == FALSE return E_PENDING and this object will be called
// back on a background thread with fOkToBeSlow == TRUE
IFACEMETHODIMP GetState(IShellItemArray * /* psiItemArray */, BOOL fOkToBeSlow, EXPCMDSTATE *pCmdState)
{
HRESULT hr;
if (fOkToBeSlow)
{
Sleep(4 * 1000); // simulate expensive work
*pCmdState = ECS_ENABLED;
hr = S_OK;
}
else
{
*pCmdState = ECS_DISABLED;
// returning E_PENDING requests that a new instance of this object be called back
// on a background thread so that it can do work that might be slow
hr = E_PENDING;
}
return hr;
}
// IInitializeCommand
IFACEMETHODIMP Initialize(PCWSTR pszCommandName, IPropertyBag *ppb)
{
SetInterface(&_pPropBag, ppb);
return SHStrDup(pszCommandName, &_pszCommandName);
}
CExplorerCommandStateHandler() : _cRef(1), _pPropBag(NULL), _pszCommandName(NULL)
{
DllAddRef();
}
private:
virtual ~CExplorerCommandStateHandler()
{
SafeRelease(&_pPropBag);
CoTaskMemFree(_pszCommandName);
DllRelease();
}
long _cRef;
IPropertyBag *_pPropBag;
PWSTR _pszCommandName;
};
HRESULT CExplorerCommandStateHandler_CreateInstance(REFIID riid, void **ppv)
{
*ppv = NULL;
CExplorerCommandStateHandler *pVerbState = new (std::nothrow) CExplorerCommandStateHandler();
HRESULT hr = pVerbState ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
pVerbState->QueryInterface(riid, ppv);
pVerbState->Release();
}
return hr;
}
static WCHAR const c_szVerbDisplayName[] = L"CommandState Handler Verb";
static WCHAR const c_szVerbName[] = L"Sample.ExplorerCommandStateHandlerVerb";
static WCHAR const c_szProgID[] = L"txtfile";
HRESULT CExplorerCommandStateHandler_RegisterUnRegister(bool fRegister)
{
HRESULT hr;
if (fRegister)
{
// register a create process based verb. this could also be a delegate execute
// or drop target verb
CRegisterExtension registerCreateProcess(CLSID_NULL);
hr = registerCreateProcess.RegisterCreateProcessVerb(c_szProgID, c_szVerbName, L"notepad.exe %1", c_szVerbDisplayName);
if (SUCCEEDED(hr))
{
hr = registerCreateProcess.RegisterVerbAttribute(c_szProgID, c_szVerbName, L"NeverDefault");
if (SUCCEEDED(hr))
{
// now register the command state handler, this computes if this verb is enabled or not
CRegisterExtension re(__uuidof(CExplorerCommandStateHandler));
hr = re.RegisterInProcServer(c_szVerbDisplayName, L"Apartment");
if (SUCCEEDED(hr))
{
hr = re.RegisterExplorerCommandStateHandler(c_szProgID, c_szVerbName);
}
}
}
}
else
{
// best effort
CRegisterExtension registerCreateProcess(CLSID_NULL);
hr = registerCreateProcess.UnRegisterVerb(c_szProgID, c_szVerbName);
CRegisterExtension re(__uuidof(CExplorerCommandStateHandler));
hr = re.UnRegisterObject();
}
return hr;
}

Просмотреть файл

@ -0,0 +1,265 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
// ExplorerCommand handlers are an inproc verb implementation method that can provide
// dynamic behavior including computing the name of the command, its icon and its visibility state.
// only use this verb implemetnation method if you are implementing a command handler on
// the commands module and need the same functionality on a context menu.
//
// each ExplorerCommand handler needs to have a unique COM object, run uuidgen to
// create new CLSID values for your handler. a handler can implement multiple
// different verbs using the information provided via IInitializeCommand (the verb name).
// your code can switch off those different verb names or the properties provided
// in the property bag
#include "Dll.h"
#include <iostream>
#include <Windows.h>
static WCHAR const c_szVerbDisplayName[] = L"This is a custom context menu...";
static WCHAR const c_szVerbName[] = L"Sample.ExplorerCommandVerb";
class CExplorerCommandVerb : public IExplorerCommand,
public IInitializeCommand,
public IObjectWithSite
{
public:
CExplorerCommandVerb() : _cRef(1), _punkSite(NULL), _hwnd(NULL), _pstmShellItemArray(NULL)
{
DllAddRef();
}
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] =
{
QITABENT(CExplorerCommandVerb, IExplorerCommand), // required
QITABENT(CExplorerCommandVerb, IInitializeCommand), // optional
QITABENT(CExplorerCommandVerb, IObjectWithSite), // optional
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&_cRef);
}
IFACEMETHODIMP_(ULONG) Release()
{
long cRef = InterlockedDecrement(&_cRef);
if (!cRef)
{
delete this;
}
return cRef;
}
// IExplorerCommand
IFACEMETHODIMP GetTitle(IShellItemArray* /* psiItemArray */, LPWSTR* ppszName)
{
// the verb name can be computed here, in this example it is static
return SHStrDup(c_szVerbDisplayName, ppszName);
}
IFACEMETHODIMP GetIcon(IShellItemArray* /* psiItemArray */, LPWSTR* ppszIcon)
{
// the icon ref ("dll,-<resid>") is provied here, in this case none is provieded
*ppszIcon = NULL;
return E_NOTIMPL;
}
IFACEMETHODIMP GetToolTip(IShellItemArray* /* psiItemArray */, LPWSTR* ppszInfotip)
{
// tooltip provided here, in this case none is provieded
*ppszInfotip = NULL;
return E_NOTIMPL;
}
IFACEMETHODIMP GetCanonicalName(GUID* pguidCommandName)
{
*pguidCommandName = __uuidof(this);
return S_OK;
}
// compute the visibility of the verb here, respect "fOkToBeSlow" if this is slow (does IO for example)
// when called with fOkToBeSlow == FALSE return E_PENDING and this object will be called
// back on a background thread with fOkToBeSlow == TRUE
IFACEMETHODIMP GetState(IShellItemArray* /* psiItemArray */, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
{
//HRESULT hr;
//if (fOkToBeSlow)
//{
// Sleep(4 * 1000); // simulate expensive work
// *pCmdState = ECS_ENABLED;
// hr = S_OK;
//}
//else
//{
// *pCmdState = ECS_DISABLED;
// // returning E_PENDING requests that a new instance of this object be called back
// // on a background thread so that it can do work that might be slow
// hr = E_PENDING;
//}
HRESULT hr = S_OK;
return hr;
}
IFACEMETHODIMP Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc);
IFACEMETHODIMP GetFlags(EXPCMDFLAGS* pFlags)
{
*pFlags = ECF_DEFAULT;
return S_OK;
}
IFACEMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum)
{
*ppEnum = NULL;
return E_NOTIMPL;
}
// IInitializeCommand
IFACEMETHODIMP Initialize(PCWSTR /* pszCommandName */, IPropertyBag* /* ppb */)
{
// the verb name is in pszCommandName, this handler can vary its behavior
// based on the command name (implementing different verbs) or the
// data stored under that verb in the registry can be read via ppb
return S_OK;
}
// IObjectWithSite
IFACEMETHODIMP SetSite(IUnknown* punkSite)
{
SetInterface(&_punkSite, punkSite);
return S_OK;
}
IFACEMETHODIMP GetSite(REFIID riid, void** ppv)
{
*ppv = NULL;
return _punkSite ? _punkSite->QueryInterface(riid, ppv) : E_FAIL;
}
private:
~CExplorerCommandVerb()
{
SafeRelease(&_punkSite);
SafeRelease(&_pstmShellItemArray);
DllRelease();
}
DWORD _ThreadProc();
static DWORD __stdcall s_ThreadProc(void* pv)
{
CExplorerCommandVerb* pecv = (CExplorerCommandVerb*)pv;
const DWORD ret = pecv->_ThreadProc();
pecv->Release();
return ret;
}
long _cRef;
IUnknown* _punkSite;
HWND _hwnd;
IStream* _pstmShellItemArray;
};
DWORD CExplorerCommandVerb::_ThreadProc()
{
IShellItemArray* psia;
HRESULT hr = CoGetInterfaceAndReleaseStream(_pstmShellItemArray, IID_PPV_ARGS(&psia));
_pstmShellItemArray = NULL;
if (SUCCEEDED(hr))
{
DWORD count;
psia->GetCount(&count);
IShellItem2* psi;
HRESULT hr = GetItemAt(psia, 0, IID_PPV_ARGS(&psi));
if (SUCCEEDED(hr))
{
PWSTR pszName;
hr = psi->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszName);
if (SUCCEEDED(hr))
{
WCHAR szMsg[128];
StringCchPrintf(szMsg, ARRAYSIZE(szMsg), L"%d item(s), first item is named %s", count, pszName);
MessageBox(_hwnd, szMsg, L"ExplorerCommand Sample Verb", MB_OK);
CoTaskMemFree(pszName);
}
psi->Release();
}
psia->Release();
}
return 0;
}
IFACEMETHODIMP CExplorerCommandVerb::Invoke(IShellItemArray* psia, IBindCtx* /* pbc */)
{
IUnknown_GetWindow(_punkSite, &_hwnd);
HRESULT hr = CoMarshalInterThreadInterfaceInStream(__uuidof(psia), psia, &_pstmShellItemArray);
if (SUCCEEDED(hr))
{
AddRef();
if (!SHCreateThread(s_ThreadProc, this, CTF_COINIT_STA | CTF_PROCESS_REF, NULL))
{
Release();
}
}
return S_OK;
}
static WCHAR const c_szProgID[] = L"txtfile";
HRESULT CExplorerCommandVerb_RegisterUnRegister(bool fRegister)
{
CRegisterExtension re(__uuidof(CExplorerCommandVerb));
HRESULT hr;
if (fRegister)
{
hr = re.RegisterInProcServer(c_szVerbDisplayName, L"Apartment");
if (SUCCEEDED(hr))
{
// register this verb on .txt files ProgID
hr = re.RegisterExplorerCommandVerb(c_szProgID, c_szVerbName, c_szVerbDisplayName);
if (SUCCEEDED(hr))
{
hr = re.RegisterVerbAttribute(c_szProgID, c_szVerbName, L"NeverDefault");
}
}
}
else
{
// best effort
hr = re.UnRegisterVerb(c_szProgID, c_szVerbName);
hr = re.UnRegisterObject();
}
return hr;
}
HRESULT CExplorerCommandVerb_CreateInstance(REFIID riid, void** ppv)
{
*ppv = NULL;
CExplorerCommandVerb* pVerb = new (std::nothrow) CExplorerCommandVerb();
HRESULT hr = pVerb ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
pVerb->QueryInterface(riid, ppv);
pVerb->Release();
}
return hr;
}

Просмотреть файл

@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28721.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExplorerCommandVerb", "ExplorerCommandVerb.vcxproj", "{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|Win32.ActiveCfg = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|Win32.Build.0 = Debug|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x64.ActiveCfg = Debug|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Debug|x64.Build.0 = Debug|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|Win32.ActiveCfg = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|Win32.Build.0 = Release|Win32
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x64.ActiveCfg = Release|x64
{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {75DD7178-723E-4369-92F3-73AFDA5784CC}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,363 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="ExplorerCommandVerb"
ProjectGUID="{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}"
RootNamespace="ExplorerCommandVerb"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
IgnoreDefaultLibraryNames="libcmt"
ModuleDefinitionFile="Dll.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
IgnoreDefaultLibraryNames="libcmt"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
IgnoreDefaultLibraryNames="libcmt"
ModuleDefinitionFile="Dll.def"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="4"
WarnAsError="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
IgnoreDefaultLibraryNames="libcmt"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath=".\dll.cpp"
>
</File>
<File
RelativePath=".\Dll.def"
>
</File>
<File
RelativePath=".\Dll.h"
>
</File>
<File
RelativePath=".\ExplorerCommandStateHandler.cpp"
>
</File>
<File
RelativePath=".\ExplorerCommandVerb.cpp"
>
</File>
<File
RelativePath=".\RegisterExtension.cpp"
>
</File>
<File
RelativePath=".\RegisterExtension.h"
>
</File>
<File
RelativePath=".\ShellHelpers.h"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

Просмотреть файл

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{6ADD939C-A7C3-4FB3-B08B-8B037854E98C}</ProjectGuid>
<RootNamespace>ExplorerCommandVerb</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>16.0.28707.177</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
<IntDir>$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(Platform)\$(Configuration)\</IntDir>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>false</TreatWarningAsError>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<IgnoreSpecificDefaultLibraries>libcmt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>Dll.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy $(OutputPath)$(MSBuildProjectName).dll $(SolutionDir)ContextMenuSample.Package\ /y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<IgnoreSpecificDefaultLibraries>libcmt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<IgnoreSpecificDefaultLibraries>libcmt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<ModuleDefinitionFile>Dll.def</ModuleDefinitionFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Midl>
<TargetEnvironment>X64</TargetEnvironment>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXPLORERCOMMANDVERB_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<IgnoreSpecificDefaultLibraries>libcmt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX64</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dll.cpp" />
<ClCompile Include="ExplorerCommandStateHandler.cpp" />
<ClCompile Include="ExplorerCommandVerb.cpp" />
<ClCompile Include="RegisterExtension.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="Dll.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Dll.h" />
<ClInclude Include="RegisterExtension.h" />
<ClInclude Include="ShellHelpers.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

Просмотреть файл

@ -0,0 +1,839 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "RegisterExtension.h"
#include <shlobj.h>
#include <shlwapi.h>
#include <strsafe.h>
#include <shobjidl.h>
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "shlwapi.lib") // link to this
__inline HRESULT ResultFromKnownLastError() { const DWORD err = GetLastError(); return err == ERROR_SUCCESS ? E_FAIL : HRESULT_FROM_WIN32(err); }
// retrieve the HINSTANCE for the current DLL or EXE using this symbol that
// the linker provides for every module, avoids the need for a global HINSTANCE variable
// and provides access to this value for static libraries
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
__inline HINSTANCE GetModuleHINSTANCE() { return (HINSTANCE)&__ImageBase; }
CRegisterExtension::CRegisterExtension(REFCLSID clsid /* = CLSID_NULL */, HKEY hkeyRoot /* = HKEY_CURRENT_USER */) : _hkeyRoot(hkeyRoot), _fAssocChanged(false)
{
SetHandlerCLSID(clsid);
GetModuleFileName(GetModuleHINSTANCE(), _szModule, ARRAYSIZE(_szModule));
}
CRegisterExtension::~CRegisterExtension()
{
if (_fAssocChanged)
{
// inform Explorer, et al that file association data has changed
SHChangeNotify(SHCNE_ASSOCCHANGED, 0, 0, 0);
}
}
void CRegisterExtension::SetHandlerCLSID(REFCLSID clsid)
{
_clsid = clsid;
StringFromGUID2(_clsid, _szCLSID, ARRAYSIZE(_szCLSID));
}
void CRegisterExtension::SetInstallScope(HKEY hkeyRoot)
{
// must be HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE
_hkeyRoot = hkeyRoot;
}
HRESULT CRegisterExtension::SetModule(PCWSTR pszModule)
{
return StringCchCopy(_szModule, ARRAYSIZE(_szModule), pszModule);
}
HRESULT CRegisterExtension::SetModule(HINSTANCE hinst)
{
return GetModuleFileName(hinst, _szModule, ARRAYSIZE(_szModule)) ? S_OK : E_FAIL;
}
HRESULT CRegisterExtension::_EnsureModule() const
{
return _szModule[0] ? S_OK : E_FAIL;
}
// this sample registers its objects in the per user registry to avoid having
// to elevate
// register the COM local server for the current running module
// this is for self registering applications
HRESULT CRegisterExtension::RegisterAppAsLocalServer(PCWSTR pszFriendlyName, PCWSTR pszCmdLine) const
{
HRESULT hr = _EnsureModule();
if (SUCCEEDED(hr))
{
WCHAR szCmdLine[MAX_PATH + 20];
if (pszCmdLine)
{
StringCchPrintf(szCmdLine, ARRAYSIZE(szCmdLine), L"%s %s", _szModule, pszCmdLine);
}
else
{
StringCchCopy(szCmdLine, ARRAYSIZE(szCmdLine), _szModule);
}
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s\\LocalServer32", L"", szCmdLine, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s", L"AppId", _szCLSID, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s", L"", pszFriendlyName, _szCLSID);
if (SUCCEEDED(hr))
{
// hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\AppID\\%s", L"RunAs", L"Interactive User", _szCLSID);
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\AppID\\%s", L"", pszFriendlyName, _szCLSID);
}
}
}
}
return hr;
}
HRESULT CRegisterExtension::RegisterElevatableLocalServer(PCWSTR pszFriendlyName, UINT idLocalizeString, UINT idIconRef) const
{
HRESULT hr = _EnsureModule();
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s", L"", pszFriendlyName, _szCLSID);
if (SUCCEEDED(hr))
{
WCHAR szRes[MAX_PATH + 20];
StringCchPrintf(szRes, ARRAYSIZE(szRes), L"@%s,-%d", _szModule, idLocalizeString);
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s", L"LocalizedString", szRes, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\LocalServer32", L"", _szModule, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\Elevation", L"Enabled", 1, _szCLSID);
if (SUCCEEDED(hr) && idIconRef)
{
StringCchPrintf(szRes, ARRAYSIZE(szRes), L"@%s,-%d", _szModule, idIconRef);
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\Elevation", L"IconReference", szRes, _szCLSID);
}
}
}
}
}
return hr;
}
HRESULT CRegisterExtension::RegisterElevatableInProcServer(PCWSTR pszFriendlyName, UINT idLocalizeString, UINT idIconRef) const
{
HRESULT hr = _EnsureModule();
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\AppId\\%s", L"", pszFriendlyName, _szCLSID);
if (SUCCEEDED(hr))
{
const unsigned char c_rgAccessPermission[] =
{0x01,0x00,0x04,0x80,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,
0x00,0x00,0x00,0x02,0x00,0x4c,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x03,0x00,
0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00,0x00,0x00,0x14,
0x00,0x07,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x0a,0x00,0x00,0x00,
0x00,0x00,0x14,0x00,0x03,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x04,
0x00,0x00,0x00,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0x01,0x02,0x00,0x00,0x00,0x00,
0x00,0x05,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,
0x05,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00};
// shell32\shell32.man uses this for InProcServer32 cases
// 010004805800000068000000000000001400000002004400030000000000140003000000010100000000000504000000000014000700000001010000000000050a00000000001400030000000101000000000005120000000102000000000005200000002002000001020000000000052000000020020000
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\AppId\\%s", L"AccessPermission", c_rgAccessPermission, sizeof(c_rgAccessPermission), _szCLSID);
const unsigned char c_rgLaunchPermission[] =
{0x01,0x00,0x04,0x80,0x78,0x00,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,
0x00,0x00,0x00,0x02,0x00,0x64,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x1f,0x00,
0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00,0x00,0x00,0x18,
0x00,0x1f,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00,
0x20,0x02,0x00,0x00,0x00,0x00,0x14,0x00,0x1f,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x05,0x04,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x0b,0x00,0x00,0x00,0x01,0x01,
0x00,0x00,0x00,0x00,0x00,0x05,0x12,0x00,0x00,0x00,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,0xcd,
0xcd,0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00,
0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00};
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\AppId\\%s", L"LaunchPermission", c_rgLaunchPermission, sizeof(c_rgLaunchPermission), _szCLSID);
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s", L"", pszFriendlyName, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s", L"AppId", _szCLSID, _szCLSID);
if (SUCCEEDED(hr))
{
WCHAR szRes[MAX_PATH + 20];
StringCchPrintf(szRes, ARRAYSIZE(szRes), L"@%s,-%d", _szModule, idLocalizeString);
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s", L"LocalizedString", szRes, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\InProcServer32", L"", _szModule, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\Elevation", L"Enabled", 1, _szCLSID);
if (SUCCEEDED(hr) && idIconRef)
{
StringCchPrintf(szRes, ARRAYSIZE(szRes), L"@%s,-%d", _szModule, idIconRef);
hr = RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Classes\\CLSID\\%s\\Elevation", L"IconReference", szRes, _szCLSID);
}
}
}
}
}
}
}
return hr;
}
HRESULT CRegisterExtension::RegisterInProcServer(PCWSTR pszFriendlyName, PCWSTR pszThreadingModel) const
{
HRESULT hr = _EnsureModule();
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s", L"", pszFriendlyName, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s\\InProcServer32", L"", _szModule, _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s\\InProcServer32", L"ThreadingModel", pszThreadingModel, _szCLSID);
}
}
}
return hr;
}
// use for
// ManualSafeSave = REG_DWORD:<1>
// EnableShareDenyNone = REG_DWORD:<1>
// EnableShareDenyWrite = REG_DWORD:<1>
HRESULT CRegisterExtension::RegisterInProcServerAttribute(PCWSTR pszAttribute, DWORD dwValue) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s", pszAttribute, dwValue, _szCLSID);
}
HRESULT CRegisterExtension::UnRegisterObject() const
{
// might have an AppID value, try that
HRESULT hr = RegDeleteKeyPrintf(_hkeyRoot, L"Software\\Classes\\AppID\\%s", _szCLSID);
if (SUCCEEDED(hr))
{
hr = RegDeleteKeyPrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s", _szCLSID);
}
return hr;
}
//
// pszProtocol values:
// "*" - all
// "http"
// "ftp"
// "shellstream" - NYI in Win7
HRESULT CRegisterExtension::RegisterHandlerSupportedProtocols(PCWSTR pszProtocol) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s\\SupportedProtocols", pszProtocol, L"", _szCLSID);
}
// this enables drag drop directly onto the .exe, useful if you have a
// shortcut to the exe somewhere (or the .exe is accessable via the send to menu)
HRESULT CRegisterExtension::RegisterAppDropTarget() const
{
HRESULT hr = _EnsureModule();
if (SUCCEEDED(hr))
{
// Windows7 supports per user App Paths, downlevel requires HKLM
hr = RegSetKeyValuePrintf(_hkeyRoot,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\%s",
L"DropTarget", _szCLSID, PathFindFileName(_szModule));
}
return hr;
}
// work around the missing "NeverDefault" feature for verbs on downlevel platforms
// these ProgID values should need special treatment to keep the verbs registered there
// from becoming default
bool CRegisterExtension::_IsBaseClassProgID(PCWSTR pszProgID) const
{
return !StrCmpIC(pszProgID, L"AllFileSystemObjects") ||
!StrCmpIC(pszProgID, L"Directory") ||
!StrCmpIC(pszProgID, L"*") ||
StrStrI(pszProgID, L"SystemFileAssociations\\Directory."); // SystemFileAssociations\Directory.* values
}
HRESULT CRegisterExtension::_EnsureBaseProgIDVerbIsNone(PCWSTR pszProgID) const
{
// putting the value of "none" that does not match any of the verbs under this key
// avoids those verbs from becoming the default.
return _IsBaseClassProgID(pszProgID) ?
RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell", L"", L"none", pszProgID) :
S_OK;
}
HRESULT CRegisterExtension::RegisterCreateProcessVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszCmdLine, PCWSTR pszVerbDisplayName) const
{
UnRegisterVerb(pszProgID, pszVerb); // make sure no existing registration exists, ignore failure
HRESULT hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shell\\%s\\command", L"", pszCmdLine, pszProgID, pszVerb);
if (SUCCEEDED(hr))
{
hr = _EnsureBaseProgIDVerbIsNone(pszProgID);
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shell\\%s", L"", pszVerbDisplayName, pszProgID, pszVerb);
}
return hr;
}
// create registry entries for drop target based static verb.
// the specified clsid will be
HRESULT CRegisterExtension::RegisterDropTargetVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const
{
UnRegisterVerb(pszProgID, pszVerb); // make sure no existing registration exists, ignore failure
HRESULT hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s\\DropTarget",
L"CLSID", _szCLSID, pszProgID, pszVerb);
if (SUCCEEDED(hr))
{
hr = _EnsureBaseProgIDVerbIsNone(pszProgID);
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s",
L"", pszVerbDisplayName, pszProgID, pszVerb);
}
return hr;
}
HRESULT CRegisterExtension::RegisterExecuteCommandVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const
{
UnRegisterVerb(pszProgID, pszVerb); // make sure no existing registration exists, ignore failure
HRESULT hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s\\command",
L"DelegateExecute", _szCLSID, pszProgID, pszVerb);
if (SUCCEEDED(hr))
{
hr = _EnsureBaseProgIDVerbIsNone(pszProgID);
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s",
L"", pszVerbDisplayName, pszProgID, pszVerb);
}
return hr;
}
// must be an inproc handler registered here
HRESULT CRegisterExtension::RegisterExplorerCommandVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const
{
UnRegisterVerb(pszProgID, pszVerb); // make sure no existing registration exists, ignore failure
HRESULT hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s",
L"ExplorerCommandHandler", _szCLSID, pszProgID, pszVerb);
if (SUCCEEDED(hr))
{
hr = _EnsureBaseProgIDVerbIsNone(pszProgID);
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s",
L"", pszVerbDisplayName, pszProgID, pszVerb);
}
return hr;
}
HRESULT CRegisterExtension::RegisterExplorerCommandStateHandler(PCWSTR pszProgID, PCWSTR pszVerb) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s",
L"CommandStateHandler", _szCLSID, pszProgID, pszVerb);
}
HRESULT CRegisterExtension::UnRegisterVerb(PCWSTR pszProgID, PCWSTR pszVerb) const
{
return RegDeleteKeyPrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell\\%s", pszProgID, pszVerb);
}
HRESULT CRegisterExtension::UnRegisterVerbs(PCWSTR const rgpszAssociation[], UINT countAssociation, PCWSTR pszVerb) const
{
HRESULT hr = S_OK;
for (UINT i = 0; SUCCEEDED(hr) && (i < countAssociation); i++)
{
hr = UnRegisterVerb(rgpszAssociation[i], pszVerb);
}
if (SUCCEEDED(hr) && HasClassID())
{
hr = UnRegisterObject();
}
return hr;
}
HRESULT CRegisterExtension::RegisterThumbnailHandler(PCWSTR pszExtension) const
{
// IThumbnailHandler
// HKEY_CLASSES_ROOT\.wma\ShellEx\{e357fccd-a995-4576-b01f-234630154e96}={9DBD2C50-62AD-11D0-B806-00C04FD706EC}
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\ShellEx\\{e357fccd-a995-4576-b01f-234630154e96}",
L"", _szCLSID, pszExtension);
}
// in process context menu handler for right drag context menu
// need to create new method that allows out of proc handling of this
// pszProgID "Folder" or "Directory"
HRESULT CRegisterExtension::RegisterRightDragContextMenuHandler(PCWSTR pszProgID, PCWSTR pszDescription) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shellex\\DragDropHandlers\\%s",
L"", pszDescription, pszProgID, _szCLSID);
}
// in process context menu handler
HRESULT CRegisterExtension::RegisterContextMenuHandler(PCWSTR pszProgID, PCWSTR pszDescription) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shellex\\ContextMenuHandlers\\%s",
L"", pszDescription, pszProgID, _szCLSID);
}
HRESULT CRegisterExtension::RegisterPropertyHandler(PCWSTR pszExtension) const
{
// IPropertyHandler
// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PropertySystem\PropertyHandlers\.docx={993BE281-6695-4BA5-8A2A-7AACBFAAB69E}
return RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\%s",
L"", _szCLSID, pszExtension);
}
HRESULT CRegisterExtension::UnRegisterPropertyHandler(PCWSTR pszExtension) const
{
return RegDeleteKeyPrintf(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PropertySystem\\PropertyHandlers\\%s", pszExtension);
}
// IResolveShellLink handler, used for custom link resolution behavior
HRESULT CRegisterExtension::RegisterLinkHandler(PCWSTR pszProgID) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\ShellEx\\LinkHandler", L"", _szCLSID, pszProgID);
}
// HKCR\<ProgID> = <Type Name>
// DefaultIcon=<icon ref>
// <icon ref>=<module path>,<res_id>
HRESULT CRegisterExtension::RegisterProgID(PCWSTR pszProgID, PCWSTR pszTypeName, UINT idIcon) const
{
HRESULT hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s", L"", pszTypeName, pszProgID);
if (SUCCEEDED(hr))
{
if (idIcon)
{
WCHAR szIconRef[MAX_PATH];
StringCchPrintf(szIconRef, ARRAYSIZE(szIconRef), L"\"%s\",-%d", _szModule, idIcon);
// HKCR\<ProgID>\DefaultIcon
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\DefaultIcon", L"", szIconRef, pszProgID);
}
}
return hr;
}
HRESULT CRegisterExtension::UnRegisterProgID(PCWSTR pszProgID, PCWSTR pszFileExtension) const
{
HRESULT hr = RegDeleteKeyPrintf(_hkeyRoot, L"Software\\Classes\\%s", pszProgID);
if (SUCCEEDED(hr) && pszFileExtension)
{
hr = RegDeleteKeyPrintf(_hkeyRoot, L"Software\\Classes\\%s\\%s", pszFileExtension, pszProgID);
}
return hr;
}
// value names that do not require a value
// HKCR\<ProgID>
// NoOpen - display the "No Open" dialog for this file to disable double click
// IsShortcut - report SFGAO_LINK for this item type, should have a IShellLink handler
// NeverShowExt - never show the file extension
// AlwaysShowExt - always show the file extension
// NoPreviousVersions - don't display the "Previous Versions" verb for this file type
HRESULT CRegisterExtension::RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s", pszValueName, L"", pszProgID);
}
// value names that require a string value
// HKCR\<ProgID>
// NoOpen - display the "No Open" dialog for this file to disable double click, display this message
// FriendlyTypeName - localized resource
// ConflictPrompt
// FullDetails
// InfoTip
// QuickTip
// PreviewDetails
// PreviewTitle
// TileInfo
// ExtendedTileInfo
// SetDefaultsFor - right click.new will populate the file with these properties, example: "prop:System.Author;System.Document.DateCreated"
HRESULT CRegisterExtension::RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName, PCWSTR pszValue) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s", pszValueName, pszValue, pszProgID);
}
// value names that require a DWORD value
// HKCR\<ProgID>
// EditFlags
// ThumbnailCutoff
HRESULT CRegisterExtension::RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName, DWORD dwValue) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s", pszValueName, dwValue, pszProgID);
}
// NeverDefault
// LegacyDisable
// Extended
// OnlyInBrowserWindow
// ProgrammaticAccessOnly
// SeparatorBefore
// SeparatorAfter
// CheckSupportedTypes, used SupportedTypes that is a file type filter registered under AppPaths (I think)
HRESULT CRegisterExtension::RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shell\\%s", pszValueName, L"", pszProgID, pszVerb);
}
// MUIVerb=@dll,-resid
// MultiSelectModel=Single|Player|Document
// Position=Bottom|Top
// DefaultAppliesTo=System.ItemName:"foo"
// HasLUAShield=System.ItemName:"bar"
// AppliesTo=System.ItemName:"foo"
HRESULT CRegisterExtension::RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName, PCWSTR pszValue) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shell\\%s", pszValueName, pszValue, pszProgID, pszVerb);
}
// BrowserFlags
// ExplorerFlags
// AttributeMask
// AttributeValue
// ImpliedSelectionModel
// SuppressionPolicy
HRESULT CRegisterExtension::RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName, DWORD dwValue) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\shell\\%s", pszValueName, dwValue, pszProgID, pszVerb);
}
// "open explorer" is an example
HRESULT CRegisterExtension::RegisterVerbDefaultAndOrder(PCWSTR pszProgID, PCWSTR pszVerbOrderFirstIsDefault) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\Shell", L"", pszVerbOrderFirstIsDefault, pszProgID);
}
// register a verb on an array of ProgIDs
HRESULT CRegisterExtension::RegisterPlayerVerbs(PCWSTR const rgpszAssociation[], UINT countAssociation,
PCWSTR pszVerb, PCWSTR pszTitle) const
{
HRESULT hr = RegisterAppAsLocalServer(pszTitle, NULL);
if (SUCCEEDED(hr))
{
// enable this handler to work with OpenSearch results, avoiding the downlaod
// and open behavior by indicating that we can accept all URL forms
hr = RegisterHandlerSupportedProtocols(L"*");
for (UINT i = 0; SUCCEEDED(hr) && (i < countAssociation); i++)
{
hr = RegisterExecuteCommandVerb(rgpszAssociation[i], pszVerb, pszTitle);
if (SUCCEEDED(hr))
{
hr = RegisterVerbAttribute(rgpszAssociation[i], pszVerb, L"NeverDefault");
if (SUCCEEDED(hr))
{
hr = RegisterVerbAttribute(rgpszAssociation[i], pszVerb, L"MultiSelectModel", L"Player");
}
}
}
}
return hr;
}
// this is where the file assocation is being taken over
HRESULT CRegisterExtension::RegisterExtensionWithProgID(PCWSTR pszFileExtension, PCWSTR pszProgID) const
{
// HKCR\<.ext>=<ProgID>
// "Content Type"
// "PerceivedType"
// TODO: to be polite if there is an existing mapping of extension to ProgID make sure it is
// added to the OpenWith list so that users can get back to the old app using OpenWith
// TODO: verify that HKLM/HKCU settings do not already exist as if they do they will
// get in the way of the setting being made here
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s", L"", pszProgID, pszFileExtension);
}
// adds the ProgID to a file extension assuming that this ProgID will have
// the "open" verb under it that will be used in Open With
HRESULT CRegisterExtension::RegisterOpenWith(PCWSTR pszFileExtension, PCWSTR pszProgID) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\OpenWithProgIds", pszProgID, L"", pszFileExtension);
}
HRESULT CRegisterExtension::RegisterNewMenuNullFile(PCWSTR pszFileExtension, PCWSTR pszProgID) const
{
// there are 2 forms of this
// HKCR\<.ext>\ShellNew
// HKCR\<.ext>\ShellNew\<ProgID> - only
// ItemName
// NullFile
// Data - REG_BINARY:<binary data>
// File
// command
// iconpath
// another way that this works
// HKEY_CLASSES_ROOT\.doc\Word.Document.8\ShellNew
HRESULT hr;
if (pszProgID)
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\%s\\ShellNew", L"NullFile", L"", pszFileExtension, pszProgID);
}
else
{
hr = RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\%s\\ShellNew", L"NullFile", L"", pszFileExtension);
}
return hr;
}
HRESULT CRegisterExtension::RegisterNewMenuData(PCWSTR pszFileExtension, PCWSTR pszProgID, PCSTR pszBase64) const
{
HRESULT hr;
if (pszProgID)
{
hr = RegSetKeyValueBinaryPrintf(_hkeyRoot, L"Software\\Classes\\%s\\%s\\ShellNew", L"Data", pszBase64, pszFileExtension, pszProgID);
}
else
{
hr = RegSetKeyValueBinaryPrintf(_hkeyRoot, L"Software\\Classes\\%s\\ShellNew", L"Data", pszBase64, pszFileExtension);
}
return hr;
}
// define the kind of a file extension. this is a multi-value property, see
// HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\KindMap
HRESULT CRegisterExtension::RegisterKind(PCWSTR pszFileExtension, PCWSTR pszKindValue) const
{
return RegSetKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap", pszFileExtension, pszKindValue);
}
HRESULT CRegisterExtension::UnRegisterKind(PCWSTR pszFileExtension) const
{
return RegDeleteKeyValuePrintf(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\KindMap", pszFileExtension);
}
// when indexing it is possible to override some of the file system property values, that includes the following
// use this registration helper to set the override flag for each
//
// System.ItemNameDisplay
// System.SFGAOFlags
// System.Kind
// System.FileName
// System.ItemPathDisplay
// System.ItemPathDisplayNarrow
// System.ItemFolderNameDisplay
// System.ItemFolderPathDisplay
// System.ItemFolderPathDisplayNarrow
HRESULT CRegisterExtension::RegisterPropertyHandlerOverride(PCWSTR pszProperty) const
{
return RegSetKeyValuePrintf(_hkeyRoot, L"Software\\Classes\\CLSID\\%s\\OverrideFileSystemProperties", pszProperty, 1, _szCLSID);
}
HRESULT CRegisterExtension::RegisterAppShortcutInSendTo() const
{
WCHAR szPath[MAX_PATH];
HRESULT hr = GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)) ? S_OK : ResultFromKnownLastError();
if (SUCCEEDED(hr))
{
// Set the shortcut target
IShellLink *psl;
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&psl));
if (SUCCEEDED(hr))
{
hr = psl->SetPath(szPath);
if (SUCCEEDED(hr))
{
WCHAR szName[MAX_PATH];
StringCchCopy(szName, ARRAYSIZE(szName), PathFindFileName(szPath));
PathRenameExtension(szName, L".lnk");
hr = SHGetFolderPath(NULL, CSIDL_SENDTO, NULL, 0, szPath);
if (SUCCEEDED(hr))
{
hr = PathAppend(szPath, szName) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
IPersistFile *ppf;
hr = psl->QueryInterface(IID_PPV_ARGS(&ppf));
if (SUCCEEDED(hr))
{
hr = ppf->Save(szPath, TRUE);
ppf->Release();
}
}
}
}
psl->Release();
}
}
return hr;
}
HRESULT CRegisterExtension::RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, PCWSTR pszValue, ...) const
{
va_list argList;
va_start(argList, pszValue);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegSetKeyValueW(hkey, szKeyName, pszValueName, REG_SZ, pszValue,
lstrlen(pszValue) * sizeof(*pszValue)));
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return hr;
}
HRESULT CRegisterExtension::RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, DWORD dwValue, ...) const
{
va_list argList;
va_start(argList, dwValue);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegSetKeyValueW(hkey, szKeyName, pszValueName, REG_DWORD, &dwValue, sizeof(dwValue)));
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return hr;
}
HRESULT CRegisterExtension::RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, const unsigned char pc[], DWORD dwSize, ...) const
{
va_list argList;
va_start(argList, pc);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegSetKeyValueW(hkey, szKeyName, pszValueName, REG_BINARY, pc, dwSize));
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return hr;
}
HRESULT CRegisterExtension::RegSetKeyValueBinaryPrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, PCSTR pszBase64, ...) const
{
va_list argList;
va_start(argList, pszBase64);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
DWORD dwDecodedImageSize, dwSkipChars, dwActualFormat;
hr = CryptStringToBinaryA(pszBase64, NULL, CRYPT_STRING_BASE64, NULL,
&dwDecodedImageSize, &dwSkipChars, &dwActualFormat) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
BYTE *pbDecodedImage = (BYTE*)LocalAlloc(LPTR, dwDecodedImageSize);
hr = pbDecodedImage ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
hr = CryptStringToBinaryA(pszBase64, lstrlenA(pszBase64), CRYPT_STRING_BASE64,
pbDecodedImage, &dwDecodedImageSize, &dwSkipChars, &dwActualFormat) ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegSetKeyValueW(hkey, szKeyName, pszValueName, REG_BINARY, pbDecodedImage, dwDecodedImageSize));
}
}
}
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return hr;
}
__inline HRESULT MapNotFoundToSuccess(HRESULT hr)
{
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr ? S_OK : hr;
}
HRESULT CRegisterExtension::RegDeleteKeyPrintf(HKEY hkey, PCWSTR pszKeyFormatString, ...) const
{
va_list argList;
va_start(argList, pszKeyFormatString);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegDeleteTree(hkey, szKeyName));
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return MapNotFoundToSuccess(hr);
}
HRESULT CRegisterExtension::RegDeleteKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValue, ...) const
{
va_list argList;
va_start(argList, pszKeyFormatString);
WCHAR szKeyName[512];
HRESULT hr = StringCchVPrintf(szKeyName, ARRAYSIZE(szKeyName), pszKeyFormatString, argList);
if (SUCCEEDED(hr))
{
hr = HRESULT_FROM_WIN32(RegDeleteKeyValueW(hkey, szKeyName, pszValue));
}
va_end(argList);
_UpdateAssocChanged(hr, pszKeyFormatString);
return MapNotFoundToSuccess(hr);
}
void CRegisterExtension::_UpdateAssocChanged(HRESULT hr, PCWSTR pszKeyFormatString) const
{
static const WCHAR c_szProgIDPrefix[] = L"Software\\Classes\\%s";
if (SUCCEEDED(hr) && !_fAssocChanged &&
(StrCmpNIC(pszKeyFormatString, c_szProgIDPrefix, ARRAYSIZE(c_szProgIDPrefix) - 1) == 0 ||
StrStrI(pszKeyFormatString, L"PropertyHandlers") ||
StrStrI(pszKeyFormatString, L"KindMap")))
{
const_cast<CRegisterExtension*>(this)->_fAssocChanged = true;
}
}

Просмотреть файл

@ -0,0 +1,117 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include <windows.h>
// production code should use an installer technology like MSI to register its handlers
// rather than this class.
// this class is used for demontration purpouses, it encapsulate the different types
// of handler registrations, schematizes those by provding methods that have parameters
// that map to the supported extension schema and makes it easy to create self registering
// .exe and .dlls
class CRegisterExtension
{
public:
CRegisterExtension(REFCLSID clsid = CLSID_NULL, HKEY hkeyRoot = HKEY_CURRENT_USER);
~CRegisterExtension();
void SetHandlerCLSID(REFCLSID clsid);
void SetInstallScope(HKEY hkeyRoot);
HRESULT SetModule(PCWSTR pszModule);
HRESULT SetModule(HINSTANCE hinst);
HRESULT RegisterInProcServer(PCWSTR pszFriendlyName, PCWSTR pszThreadingModel) const;
HRESULT RegisterInProcServerAttribute(PCWSTR pszAttribute, DWORD dwValue) const;
// register the COM local server for the current running module
// this is for self registering applications
HRESULT RegisterAppAsLocalServer(PCWSTR pszFriendlyName, PCWSTR pszCmdLine = NULL) const;
HRESULT RegisterElevatableLocalServer(PCWSTR pszFriendlyName, UINT idLocalizeString, UINT idIconRef) const;
HRESULT RegisterElevatableInProcServer(PCWSTR pszFriendlyName, UINT idLocalizeString, UINT idIconRef) const;
// remove a COM object registration
HRESULT UnRegisterObject() const;
// this enables drag drop directly onto the .exe, useful if you have a
// shortcut to the exe somewhere (or the .exe is accessable via the send to menu)
HRESULT RegisterAppDropTarget() const;
// create registry entries for drop target based static verb.
// the specified clsid will be
HRESULT RegisterCreateProcessVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszCmdLine, PCWSTR pszVerbDisplayName) const;
HRESULT RegisterDropTargetVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const;
HRESULT RegisterExecuteCommandVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const;
HRESULT RegisterExplorerCommandVerb(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszVerbDisplayName) const;
HRESULT RegisterExplorerCommandStateHandler(PCWSTR pszProgID, PCWSTR pszVerb) const;
HRESULT RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName) const;
HRESULT RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName, PCWSTR pszValue) const;
HRESULT RegisterVerbAttribute(PCWSTR pszProgID, PCWSTR pszVerb, PCWSTR pszValueName, DWORD dwValue) const;
HRESULT RegisterVerbDefaultAndOrder(PCWSTR pszProgID, PCWSTR pszVerbOrderFirstIsDefault) const;
HRESULT RegisterPlayerVerbs(PCWSTR const rgpszAssociation[], UINT countAssociation,
PCWSTR pszVerb, PCWSTR pszTitle) const;
HRESULT UnRegisterVerb(PCWSTR pszProgID, PCWSTR pszVerb) const;
HRESULT UnRegisterVerbs(PCWSTR const rgpszAssociation[], UINT countAssociation, PCWSTR pszVerb) const;
HRESULT RegisterContextMenuHandler(PCWSTR pszProgID, PCWSTR pszDescription) const;
HRESULT RegisterRightDragContextMenuHandler(PCWSTR pszProgID, PCWSTR pszDescription) const;
HRESULT RegisterAppShortcutInSendTo() const;
HRESULT RegisterThumbnailHandler(PCWSTR pszExtension) const;
HRESULT RegisterPropertyHandler(PCWSTR pszExtension) const;
HRESULT UnRegisterPropertyHandler(PCWSTR pszExtension) const;
HRESULT RegisterLinkHandler(PCWSTR pszProgID) const;
HRESULT RegisterProgID(PCWSTR pszProgID, PCWSTR pszTypeName, UINT idIcon) const;
HRESULT UnRegisterProgID(PCWSTR pszProgID, PCWSTR pszFileExtension) const;
HRESULT RegisterExtensionWithProgID(PCWSTR pszFileExtension, PCWSTR pszProgID) const;
HRESULT RegisterOpenWith(PCWSTR pszFileExtension, PCWSTR pszProgID) const;
HRESULT RegisterNewMenuNullFile(PCWSTR pszFileExtension, PCWSTR pszProgID) const;
HRESULT RegisterNewMenuData(PCWSTR pszFileExtension, PCWSTR pszProgID, PCSTR pszBase64) const;
HRESULT RegisterKind(PCWSTR pszFileExtension, PCWSTR pszKindValue) const;
HRESULT UnRegisterKind(PCWSTR pszFileExtension) const;
HRESULT RegisterPropertyHandlerOverride(PCWSTR pszProperty) const;
HRESULT RegisterHandlerSupportedProtocols(PCWSTR pszProtocol) const;
HRESULT RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName) const;
HRESULT RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName, PCWSTR pszValue) const;
HRESULT RegisterProgIDValue(PCWSTR pszProgID, PCWSTR pszValueName, DWORD dwValue) const;
// this should probably be private but they are useful
HRESULT RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, PCWSTR pszValue, ...) const;
HRESULT RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, DWORD dwValue, ...) const;
HRESULT RegSetKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, const unsigned char pc[], DWORD dwSize, ...) const;
HRESULT RegSetKeyValueBinaryPrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValueName, PCSTR pszBase64, ...) const;
HRESULT RegDeleteKeyPrintf(HKEY hkey, PCWSTR pszKeyFormatString, ...) const;
HRESULT RegDeleteKeyValuePrintf(HKEY hkey, PCWSTR pszKeyFormatString, PCWSTR pszValue, ...) const;
PCWSTR GetCLSIDString() const { return _szCLSID; };
bool HasClassID() const { return _clsid != CLSID_NULL ? true : false; };
private:
HRESULT _EnsureModule() const;
bool _IsBaseClassProgID(PCWSTR pszProgID) const;
HRESULT _EnsureBaseProgIDVerbIsNone(PCWSTR pszProgID) const;
void _UpdateAssocChanged(HRESULT hr, PCWSTR pszKeyFormatString) const;
CLSID _clsid;
HKEY _hkeyRoot;
WCHAR _szCLSID[39];
WCHAR _szModule[MAX_PATH];
bool _fAssocChanged;
};

Просмотреть файл

@ -0,0 +1,277 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#define STRICT_TYPED_ITEMIDS // in case you do IDList stuff you want this on for better type saftey
#define UNICODE 1
#include <windows.h>
#include <windowsx.h> // for WM_COMMAND handling macros
#include <shlobj.h> // shell stuff
#include <shlwapi.h> // QISearch, easy way to implement QI
#include <propkey.h>
#include <propvarutil.h>
#include <strsafe.h>
#include <objbase.h>
#pragma comment(lib, "shlwapi.lib") // link to this
#pragma comment(lib, "comctl32.lib") // link to this
#pragma comment(lib, "propsys.lib") // link to this
// set up common controls v6 the easy way
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
__inline HRESULT ResultFromKnownLastError() { const DWORD err = GetLastError(); return err == ERROR_SUCCESS ? E_FAIL : HRESULT_FROM_WIN32(err); }
// map Win32 APIs that follow the return BOOL/set last error protocol
// into HRESULT
//
// example: MoveFileEx()
__inline HRESULT ResultFromWin32Bool(BOOL b)
{
return b ? S_OK : ResultFromKnownLastError();
}
#if (NTDDI_VERSION >= NTDDI_VISTA)
__inline HRESULT ShellExecuteItem(HWND hwnd, PCWSTR pszVerb, IShellItem *psi)
{
// how to activate a shell item, use ShellExecute().
PIDLIST_ABSOLUTE pidl;
HRESULT hr = SHGetIDListFromObject(psi, &pidl);
if (SUCCEEDED(hr))
{
SHELLEXECUTEINFO ei = { sizeof(ei) };
ei.fMask = SEE_MASK_INVOKEIDLIST;
ei.hwnd = hwnd;
ei.nShow = SW_NORMAL;
ei.lpIDList = pidl;
ei.lpVerb = pszVerb;
hr = ResultFromWin32Bool(ShellExecuteEx(&ei));
CoTaskMemFree(pidl);
}
return hr;
}
__inline HRESULT GetItemFromView(IFolderView2 *pfv, int iItem, REFIID riid, void **ppv)
{
*ppv = NULL;
HRESULT hr = S_OK;
if (iItem == -1)
{
hr = pfv->GetSelectedItem(-1, &iItem); // Returns S_FALSE if none selected
}
if (S_OK == hr)
{
hr = pfv->GetItem(iItem, riid, ppv);
}
else
{
hr = E_FAIL;
}
return hr;
}
// set the icon for your window using WM_SETICON from one of the set of stock system icons
// caller must call ClearDialogIcon() to free the HICON that is created
__inline void SetDialogIcon(HWND hdlg, SHSTOCKICONID siid)
{
SHSTOCKICONINFO sii = {sizeof(sii)};
if (SUCCEEDED(SHGetStockIconInfo(siid, SHGFI_ICON | SHGFI_SMALLICON, &sii)))
{
SendMessage(hdlg, WM_SETICON, ICON_SMALL, (LPARAM) sii.hIcon);
}
if (SUCCEEDED(SHGetStockIconInfo(siid, SHGFI_ICON | SHGFI_LARGEICON, &sii)))
{
SendMessage(hdlg, WM_SETICON, ICON_BIG, (LPARAM) sii.hIcon);
}
}
#endif
// free the HICON that was set using SetDialogIcon()
__inline void ClearDialogIcon(HWND hdlg)
{
DestroyIcon((HICON)SendMessage(hdlg, WM_GETICON, ICON_SMALL, 0));
DestroyIcon((HICON)SendMessage(hdlg, WM_GETICON, ICON_BIG, 0));
}
__inline HRESULT SetItemImageImageInStaticControl(HWND hwndStatic, IShellItem *psi)
{
HBITMAP hbmp = NULL;
HRESULT hr = S_OK;
if (psi)
{
IShellItemImageFactory *psiif;
hr = psi->QueryInterface(IID_PPV_ARGS(&psiif));
if (SUCCEEDED(hr))
{
RECT rc;
GetWindowRect(hwndStatic, &rc);
const UINT dxdy = min(rc.right - rc.left, rc.bottom - rc.top); // make it square
const SIZE size = { dxdy, dxdy };
hr = psiif->GetImage(size, SIIGBF_RESIZETOFIT, &hbmp);
psiif->Release();
}
}
if (SUCCEEDED(hr))
{
HGDIOBJ hgdiOld = (HGDIOBJ) SendMessage(hwndStatic, STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) hbmp);
if (hgdiOld)
{
DeleteObject(hgdiOld); // if there was an old one clean it up
}
}
return hr;
}
__inline HRESULT SHILCloneFull(PCUIDLIST_ABSOLUTE pidl, PIDLIST_ABSOLUTE *ppidl)
{
*ppidl = ILCloneFull(pidl);
return *ppidl ? S_OK : E_OUTOFMEMORY;
}
__inline HRESULT SHILClone(PCUIDLIST_RELATIVE pidl, PIDLIST_RELATIVE *ppidl)
{
*ppidl = ILClone(pidl);
return *ppidl ? S_OK : E_OUTOFMEMORY;
}
__inline HRESULT SHILCombine(PCIDLIST_ABSOLUTE pidl1, PCUIDLIST_RELATIVE pidl2, PIDLIST_ABSOLUTE *ppidl)
{
*ppidl = ILCombine(pidl1, pidl2);
return *ppidl ? S_OK : E_OUTOFMEMORY;
}
__inline HRESULT GetItemAt(IShellItemArray *psia, DWORD i, REFIID riid, void **ppv)
{
*ppv = NULL;
IShellItem *psi = NULL; // avoid error C4701
HRESULT hr = psia ? psia->GetItemAt(i, &psi) : E_NOINTERFACE;
if (SUCCEEDED(hr))
{
hr = psi->QueryInterface(riid, ppv);
psi->Release();
}
return hr;
}
#define MAP_ENTRY(x) {L#x, x}
__inline HRESULT ShellAttributesToString(SFGAOF sfgaof, PWSTR *ppsz)
{
*ppsz = NULL;
static const struct { PCWSTR pszName; SFGAOF sfgaof; } c_rgItemAttributes[] =
{
// note, SFGAO_HASSUBFOLDER is too expesnive to compute
// and has been excluded from this list
MAP_ENTRY(SFGAO_STREAM),
MAP_ENTRY(SFGAO_FOLDER),
MAP_ENTRY(SFGAO_FILESYSTEM),
MAP_ENTRY(SFGAO_FILESYSANCESTOR),
MAP_ENTRY(SFGAO_STORAGE),
MAP_ENTRY(SFGAO_STORAGEANCESTOR),
MAP_ENTRY(SFGAO_LINK),
MAP_ENTRY(SFGAO_CANCOPY),
MAP_ENTRY(SFGAO_CANMOVE),
MAP_ENTRY(SFGAO_CANLINK),
MAP_ENTRY(SFGAO_CANRENAME),
MAP_ENTRY(SFGAO_CANDELETE),
MAP_ENTRY(SFGAO_HASPROPSHEET),
MAP_ENTRY(SFGAO_DROPTARGET),
MAP_ENTRY(SFGAO_ENCRYPTED),
MAP_ENTRY(SFGAO_ISSLOW),
MAP_ENTRY(SFGAO_GHOSTED),
MAP_ENTRY(SFGAO_SHARE),
MAP_ENTRY(SFGAO_READONLY),
MAP_ENTRY(SFGAO_HIDDEN),
MAP_ENTRY(SFGAO_REMOVABLE),
MAP_ENTRY(SFGAO_COMPRESSED),
MAP_ENTRY(SFGAO_BROWSABLE),
MAP_ENTRY(SFGAO_NONENUMERATED),
MAP_ENTRY(SFGAO_NEWCONTENT),
};
WCHAR sz[512] = {};
PWSTR psz = sz;
size_t cch = ARRAYSIZE(sz);
StringCchPrintfEx(psz, cch, &psz, &cch, 0, L"0x%08X", sfgaof);
for (int i = 0; i < ARRAYSIZE(c_rgItemAttributes); i++)
{
if (c_rgItemAttributes[i].sfgaof & sfgaof)
{
StringCchPrintfEx(psz, cch, &psz, &cch, 0, L", %s", c_rgItemAttributes[i].pszName);
}
}
return SHStrDup(sz, ppsz);
}
template <class T> void SafeRelease(T **ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
}
// assign an interface pointer, release old, capture ref to new, can be used to set to zero too
template <class T> HRESULT SetInterface(T **ppT, IUnknown *punk)
{
SafeRelease(ppT);
return punk ? punk->QueryInterface(ppT) : E_NOINTERFACE;
}
// remote COM methods are dispatched in the context of an exception handler that consumes
// all SEH exceptions including crahses and C++ exceptions. this is undesirable as it
// means programs will continue to run after such an exception has been thrown,
// leaving the process in a inconsistent state.
//
// this applies to COM methods like IDropTarget::Drop()
//
// this code turns off that behavior
__inline void DisableComExceptionHandling()
{
IGlobalOptions *pGlobalOptions;
HRESULT hr = CoCreateInstance(CLSID_GlobalOptions, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGlobalOptions));
if (SUCCEEDED(hr))
{
#if (NTDDI_VERSION >= NTDDI_WIN7)
hr = pGlobalOptions->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE_ANY);
#else
hr = pGlobalOptions->Set(COMGLB_EXCEPTION_HANDLING, COMGLB_EXCEPTION_DONOT_HANDLE);
#endif
pGlobalOptions->Release();
}
}
__inline void GetWindowRectInClient(HWND hwnd, RECT *prc)
{
GetWindowRect(hwnd, prc);
MapWindowPoints(GetDesktopWindow(), GetParent(hwnd), (POINT*)prc, 2);
}
// retrieve the HINSTANCE for the current DLL or EXE using this symbol that
// the linker provides for every module, avoids the need for a global HINSTANCE variable
// and provides access to this value for static libraries
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
__inline HINSTANCE GetModuleHINSTANCE() { return (HINSTANCE)&__ImageBase; }

Просмотреть файл

@ -0,0 +1,166 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "dll.h"
typedef HRESULT (*PFNCREATEINSTANCE)(REFIID riid, void **ppvObject);
struct CLASS_OBJECT_INIT
{
const CLSID *pClsid;
PFNCREATEINSTANCE pfnCreate;
};
// add classes supported by this module here
const CLASS_OBJECT_INIT c_rgClassObjectInit[] =
{
{ &__uuidof(CExplorerCommandVerb), CExplorerCommandVerb_CreateInstance },
{ &__uuidof(CExplorerCommandStateHandler), CExplorerCommandStateHandler_CreateInstance },
};
long g_cRefModule = 0;
// Handle the the DLL's module
HINSTANCE g_hInst = NULL;
// Standard DLL functions
STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, void *)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hInst = hInstance;
DisableThreadLibraryCalls(hInstance);
}
return TRUE;
}
STDAPI DllCanUnloadNow()
{
// Only allow the DLL to be unloaded after all outstanding references have been released
return (g_cRefModule == 0) ? S_OK : S_FALSE;
}
void DllAddRef()
{
InterlockedIncrement(&g_cRefModule);
}
void DllRelease()
{
InterlockedDecrement(&g_cRefModule);
}
class CClassFactory : public IClassFactory
{
public:
static HRESULT CreateInstance(REFCLSID clsid, const CLASS_OBJECT_INIT *pClassObjectInits, size_t cClassObjectInits, REFIID riid, void **ppv)
{
*ppv = NULL;
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
for (size_t i = 0; i < cClassObjectInits; i++)
{
if (clsid == *pClassObjectInits[i].pClsid)
{
IClassFactory *pClassFactory = new (std::nothrow) CClassFactory(pClassObjectInits[i].pfnCreate);
hr = pClassFactory ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
hr = pClassFactory->QueryInterface(riid, ppv);
pClassFactory->Release();
}
break; // match found
}
}
return hr;
}
CClassFactory(PFNCREATEINSTANCE pfnCreate) : _cRef(1), _pfnCreate(pfnCreate)
{
DllAddRef();
}
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void ** ppv)
{
static const QITAB qit[] =
{
QITABENT(CClassFactory, IClassFactory),
{ 0 }
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) AddRef()
{
return InterlockedIncrement(&_cRef);
}
IFACEMETHODIMP_(ULONG) Release()
{
long cRef = InterlockedDecrement(&_cRef);
if (cRef == 0)
{
delete this;
}
return cRef;
}
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
{
return punkOuter ? CLASS_E_NOAGGREGATION : _pfnCreate(riid, ppv);
}
IFACEMETHODIMP LockServer(BOOL fLock)
{
if (fLock)
{
DllAddRef();
}
else
{
DllRelease();
}
return S_OK;
}
private:
~CClassFactory()
{
DllRelease();
}
long _cRef;
PFNCREATEINSTANCE _pfnCreate;
};
STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **ppv)
{
return CClassFactory::CreateInstance(clsid, c_rgClassObjectInit, ARRAYSIZE(c_rgClassObjectInit), riid, ppv);
}
HRESULT RegisterUnregister(bool fRegister)
{
HRESULT hr = CExplorerCommandStateHandler_RegisterUnRegister(fRegister);
if (SUCCEEDED(hr))
{
hr = CExplorerCommandVerb_RegisterUnRegister(fRegister);
}
return hr;
}
STDAPI DllRegisterServer()
{
return RegisterUnregister(true);
}
STDAPI DllUnregisterServer()
{
return RegisterUnregister(false);
}

Просмотреть файл

@ -0,0 +1,41 @@
Explorer Command Verb Sample
================================
Demonstrates how implement a shell verb using the ExplorerCommand and ExplorerCommandState methods.
Sample Language Implementations
===============================
C++
Files:
=============================================
dll.cpp
dll.def
dll.h
ExplorerCommandStateHandler.cpp
ExplorerCommandVerb.cpp
ExplorerCommandVerb.sln
ExplorerCommandVerb.vcproj
RegisterExtension.cpp
RegisterExtension.h
ShellHelpers.h
To build the sample using the command prompt:
=============================================
1. Open the Command Prompt window and navigate to the ExplorerCommandVerb directory.
2. Type msbuild ExplorerCommandVerb.sln.
To build the sample using Visual Studio (preferred method):
===========================================================
1. Open Windows Explorer and navigate to the ExplorerCommandVerb directory.
2. Double-click the icon for the ExplorerCommandVerb.sln file to open the file in Visual Studio.
3. In the Build menu, select Build Solution. The application will be built in the default \Debug or \Release directory.
To run the sample:
=================
1. Navigate to the directory that contains ExplorerCommandVerb.dll using the command prompt. Make sure you use 64-bit dll on 64-bit Windows.
2. Type regsvr32 ExplorerCommandVerb.dll.
3. Two new verbs will be shown on the context menu when you right-click a .txt file.