Add new icon as well as telemetry (#563)

* Update icon and add telemetry calls

This change adds the new PowerRename icon and includes telemetry calls

* Ensure string is freed

* Update event naming convention

* Delete PowerRenameDemo.gif

Deleting this gif as I added it with a separate commit with the README.md update for PowerRename
This commit is contained in:
Chris Davis 2019-10-28 10:14:59 -07:00 committed by GitHub
parent a1669fd34e
commit b892e731d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 185 additions and 14 deletions

View File

@ -3,6 +3,7 @@
#include <PowerRenameUI.h> #include <PowerRenameUI.h>
#include <PowerRenameItem.h> #include <PowerRenameItem.h>
#include <PowerRenameManager.h> #include <PowerRenameManager.h>
#include <trace.h>
#include "resource.h" #include "resource.h"
extern HINSTANCE g_hInst; extern HINSTANCE g_hInst;
@ -88,23 +89,24 @@ HRESULT CPowerRenameMenu::QueryContextMenu(HMENU hMenu, UINT index, UINT uIDFirs
HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici) HRESULT CPowerRenameMenu::InvokeCommand(_In_ LPCMINVOKECOMMANDINFO pici)
{ {
// Check if we have disabled ourselves
if (!IsEnabled())
return E_FAIL;
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
if ((IS_INTRESOURCE(pici->lpVerb)) && if (IsEnabled() &
(IS_INTRESOURCE(pici->lpVerb)) &&
(LOWORD(pici->lpVerb) == 0)) (LOWORD(pici->lpVerb) == 0))
{ {
Trace::Invoked();
IStream* pstrm = nullptr; IStream* pstrm = nullptr;
if (SUCCEEDED(CoMarshalInterThreadInterfaceInStream(__uuidof(m_spdo), m_spdo, &pstrm))) hr = CoMarshalInterThreadInterfaceInStream(__uuidof(m_spdo), m_spdo, &pstrm);
if (SUCCEEDED(hr))
{ {
if (!SHCreateThread(s_PowerRenameUIThreadProc, pstrm, CTF_COINIT | CTF_PROCESS_REF, nullptr)) if (!SHCreateThread(s_PowerRenameUIThreadProc, pstrm, CTF_COINIT | CTF_PROCESS_REF, nullptr))
{ {
pstrm->Release(); // if we failed to create the thread, then we must release the stream pstrm->Release(); // if we failed to create the thread, then we must release the stream
hr = E_FAIL;
} }
} }
Trace::InvokedRet(hr);
} }
return hr; return hr;
@ -114,22 +116,27 @@ DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
{ {
IStream* pstrm = static_cast<IStream*>(pData); IStream* pstrm = static_cast<IStream*>(pData);
CComPtr<IDataObject> spdo; CComPtr<IDataObject> spdo;
if (SUCCEEDED(CoGetInterfaceAndReleaseStream(pstrm, IID_PPV_ARGS(&spdo)))) HRESULT hr = CoGetInterfaceAndReleaseStream(pstrm, IID_PPV_ARGS(&spdo));
if (SUCCEEDED(hr))
{ {
// Create the smart rename manager // Create the smart rename manager
CComPtr<IPowerRenameManager> spsrm; CComPtr<IPowerRenameManager> spsrm;
if (SUCCEEDED(CPowerRenameManager::s_CreateInstance(&spsrm))) hr = CPowerRenameManager::s_CreateInstance(&spsrm);
if (SUCCEEDED(hr))
{ {
// Create the factory for our items // Create the factory for our items
CComPtr<IPowerRenameItemFactory> spsrif; CComPtr<IPowerRenameItemFactory> spsrif;
if (SUCCEEDED(CPowerRenameItem::s_CreateInstance(nullptr, IID_PPV_ARGS(&spsrif)))) hr = CPowerRenameItem::s_CreateInstance(nullptr, IID_PPV_ARGS(&spsrif));
if (SUCCEEDED(hr))
{ {
// Pass the factory to the manager // Pass the factory to the manager
if (SUCCEEDED(spsrm->put_smartRenameItemFactory(spsrif))) hr = spsrm->put_smartRenameItemFactory(spsrif);
if (SUCCEEDED(hr))
{ {
// Create the smart rename UI instance and pass the smart rename manager // Create the smart rename UI instance and pass the smart rename manager
CComPtr<IPowerRenameUI> spsrui; CComPtr<IPowerRenameUI> spsrui;
if (SUCCEEDED(CPowerRenameUI::s_CreateInstance(spsrm, spdo, false, &spsrui))) hr = CPowerRenameUI::s_CreateInstance(spsrm, spdo, false, &spsrui);
if (SUCCEEDED(hr))
{ {
// Call blocks until we are done // Call blocks until we are done
spsrui->Show(); spsrui->Show();
@ -143,5 +150,7 @@ DWORD WINAPI CPowerRenameMenu::s_PowerRenameUIThreadProc(_In_ void* pData)
} }
} }
Trace::UIShownRet(hr);
return 0; return 0;
} }

View File

@ -1,6 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "PowerRenameExt.h" #include "PowerRenameExt.h"
#include <interface/powertoy_module_interface.h> #include <interface/powertoy_module_interface.h>
#include <trace.h>
#include <common/settings_objects.h> #include <common/settings_objects.h>
DWORD g_dwModuleRefCount = 0; DWORD g_dwModuleRefCount = 0;
@ -96,9 +97,11 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, void*)
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
g_hInst = hInstance; g_hInst = hInstance;
Trace::RegisterProvider();
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
Trace::RegisterProvider();
break; break;
} }
return TRUE; return TRUE;
@ -233,11 +236,13 @@ public:
void init_settings() void init_settings()
{ {
m_enabled = CPowerRenameMenu::IsEnabled(); m_enabled = CPowerRenameMenu::IsEnabled();
Trace::EnablePowerRename(m_enabled);
} }
void save_settings() void save_settings()
{ {
CPowerRenameMenu::SetEnabled(m_enabled); CPowerRenameMenu::SetEnabled(m_enabled);
Trace::EnablePowerRename(m_enabled);
} }
PowerRenameModule() PowerRenameModule()

View File

@ -98,6 +98,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -132,6 +133,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -148,6 +150,7 @@
<ClInclude Include="srwlock.h" /> <ClInclude Include="srwlock.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
<ClInclude Include="trace.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Helpers.cpp" /> <ClCompile Include="Helpers.cpp" />
@ -160,6 +163,7 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="trace.cpp" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@ -5,6 +5,8 @@
#include <shlobj.h> #include <shlobj.h>
#include "helpers.h" #include "helpers.h"
#include <filesystem> #include <filesystem>
#include "trace.h"
namespace fs = std::filesystem; namespace fs = std::filesystem;
extern HINSTANCE g_hInst; extern HINSTANCE g_hInst;
@ -407,6 +409,57 @@ LRESULT CPowerRenameManager::_WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM
return lRes; return lRes;
} }
void CPowerRenameManager::_LogOperationTelemetry()
{
UINT renameItemCount = 0;
UINT selectedItemCount = 0;
UINT totalItemCount = 0;
DWORD flags = 0;
GetItemCount(&totalItemCount);
GetSelectedItemCount(&selectedItemCount);
GetRenameItemCount(&renameItemCount);
get_flags(&flags);
// Enumerate extensions used into a map
std::map<std::wstring, int> extensionsMap;
for (UINT i = 0; i < totalItemCount; i++)
{
CComPtr<IPowerRenameItem> spItem;
if (SUCCEEDED(GetItemByIndex(i, &spItem)))
{
PWSTR originalName;
if (SUCCEEDED(spItem->get_originalName(&originalName)))
{
std::wstring extension = fs::path(originalName).extension().wstring();
std::map<std::wstring, int>::iterator it = extensionsMap.find(extension);
if (it == extensionsMap.end())
{
extensionsMap.insert({ extension, 1 });
}
else
{
it->second++;
}
CoTaskMemFree(originalName);
}
}
}
std::wstring extensionList = L"";
for (auto elem : extensionsMap)
{
extensionList.append(elem.first);
extensionList.append(L":");
extensionList.append(std::to_wstring(elem.second));
extensionList.append(L",");
}
Trace::RenameOperation(totalItemCount, selectedItemCount, renameItemCount, flags, extensionList.c_str());
}
HRESULT CPowerRenameManager::_PerformFileOperation() HRESULT CPowerRenameManager::_PerformFileOperation()
{ {
// Do we have items to rename? // Do we have items to rename?
@ -416,6 +469,8 @@ HRESULT CPowerRenameManager::_PerformFileOperation()
return E_FAIL; return E_FAIL;
} }
_LogOperationTelemetry();
// Wait for existing regex thread to finish // Wait for existing regex thread to finish
_WaitForRegExWorkerThread(); _WaitForRegExWorkerThread();

View File

@ -82,6 +82,8 @@ protected:
static LRESULT CALLBACK s_msgWndProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam); static LRESULT CALLBACK s_msgWndProc(_In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
LRESULT _WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam); LRESULT _WndProc(_In_ HWND hwnd, _In_ UINT msg, _In_ WPARAM wParam, _In_ LPARAM lParam);
void _LogOperationTelemetry();
HANDLE m_regExWorkerThreadHandle = nullptr; HANDLE m_regExWorkerThreadHandle = nullptr;
HANDLE m_startRegExWorkerEvent = nullptr; HANDLE m_startRegExWorkerEvent = nullptr;
HANDLE m_cancelRegExWorkerEvent = nullptr; HANDLE m_cancelRegExWorkerEvent = nullptr;

View File

@ -17,4 +17,6 @@
#include <shobjidl.h> #include <shobjidl.h>
#include <shellapi.h> #include <shellapi.h>
#include <ProjectTelemetry.h>
#include "PowerRenameInterfaces.h" #include "PowerRenameInterfaces.h"

View File

@ -0,0 +1,73 @@
#include "stdafx.h"
#include "trace.h"
TRACELOGGING_DEFINE_PROVIDER(
g_hProvider,
"Microsoft.PowerToys",
// {38e8889b-9731-53f5-e901-e8a7c1753074}
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
TraceLoggingOptionProjectTelemetry());
void Trace::RegisterProvider() noexcept
{
TraceLoggingRegister(g_hProvider);
}
void Trace::UnregisterProvider() noexcept
{
TraceLoggingUnregister(g_hProvider);
}
void Trace::Invoked() noexcept
{
TraceLoggingWrite(
g_hProvider,
"PowerRename_Invoked",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::InvokedRet(_In_ HRESULT hr) noexcept
{
TraceLoggingWrite(
g_hProvider,
"PowerRename_InvokedRet",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingHResult(hr),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::EnablePowerRename(_In_ bool enabled) noexcept
{
TraceLoggingWrite(
g_hProvider,
"PowerRename_EnablePowerRename",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingBoolean(enabled, "Enabled"));
}
void Trace::UIShownRet(_In_ HRESULT hr) noexcept
{
TraceLoggingWrite(
g_hProvider,
"PowerRename_UIShownRet",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingHResult(hr),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
}
void Trace::RenameOperation(_In_ UINT totalItemCount, _In_ UINT selectedItemCount, _In_ UINT renameItemCount, _In_ DWORD flags, _In_ PCWSTR extensionList) noexcept
{
TraceLoggingWrite(
g_hProvider,
"PowerRename_RenameOperation",
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
TraceLoggingUInt32(totalItemCount, "TotalItemCount"),
TraceLoggingUInt32(selectedItemCount, "SelectedItemCount"),
TraceLoggingUInt32(renameItemCount, "RenameItemCount"),
TraceLoggingInt32(flags, "Flags"),
TraceLoggingWideString(extensionList, "ExtensionList"));
}

View File

@ -0,0 +1,17 @@
#pragma once
class Trace {
public:
static void RegisterProvider() noexcept;
static void UnregisterProvider() noexcept;
static void Invoked() noexcept;
static void InvokedRet(_In_ HRESULT hr) noexcept;
static void EnablePowerRename(_In_ bool enabled) noexcept;
static void UIShownRet(_In_ HRESULT hr) noexcept;
static void RenameOperation(
_In_ UINT totalItemCount,
_In_ UINT selectedItemCount,
_In_ UINT renameItemCount,
_In_ DWORD flags,
_In_ PCWSTR extensionList) noexcept;
};

View File

@ -115,6 +115,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -155,6 +156,7 @@
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

View File

@ -128,7 +128,7 @@
// Icon with lowest ID value placed first to ensure application icon // Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems. // remains consistent on all systems.
IDI_RENAME ICON "Rename.ico" IDI_RENAME ICON "PowerRename.ico"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -115,6 +115,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
@ -152,6 +153,7 @@
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

View File

@ -116,7 +116,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
@ -156,7 +156,7 @@
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\;..\..\..\common;..\..\..\common\telemetry;..\..\;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<UseFullPaths>true</UseFullPaths> <UseFullPaths>true</UseFullPaths>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>