Add Ext and GUI projects to solution

This commit is contained in:
Ivan Stošić 2022-09-19 10:41:19 +02:00
parent 10c49d7041
commit 988dda89c2
42 changed files with 1660 additions and 2 deletions

View File

@ -461,6 +461,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileLocksmith", "FileLocksm
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithExt", "src\modules\FileLocksmith\FileLocksmithExt\FileLocksmithExt.vcxproj", "{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithGUI", "src\modules\FileLocksmith\FileLocksmithGUI\FileLocksmithGUI.vcxproj", "{BBD45704-F220-4774-9C92-D55D822C9E75}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64 Debug|ARM64 = Debug|ARM64
@ -1546,8 +1550,8 @@ Global
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|ARM64.Build.0 = Release|ARM64 {04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|ARM64.Build.0 = Release|ARM64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.ActiveCfg = Release|x64 {04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.ActiveCfg = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.Build.0 = Release|x64 {04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x64.Build.0 = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|Any CPU {04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.ActiveCfg = Release|x64
{04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = Release|Any CPU {04B193D7-3E21-46B8-A958-89B63A8A69DE}.Release|x86.Build.0 = Release|x64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.ActiveCfg = Debug|ARM64 {F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.ActiveCfg = Debug|ARM64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.Build.0 = Debug|ARM64 {F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|ARM64.Build.0 = Debug|ARM64
{F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x64.ActiveCfg = Debug|x64 {F44934A8-36F3-49B0-9465-3831BE041CDE}.Debug|x64.ActiveCfg = Debug|x64
@ -1862,6 +1866,26 @@ Global
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.ActiveCfg = Release|x64 {8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.ActiveCfg = Release|x64
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.Build.0 = Release|x64 {8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x64.Build.0 = Release|x64
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x86.ActiveCfg = Release|x64 {8290CF58-0E97-45C4-AB41-F3C7C3128AEC}.Release|x86.ActiveCfg = Release|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.ActiveCfg = Debug|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.Build.0 = Debug|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.ActiveCfg = Debug|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.Build.0 = Debug|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x86.ActiveCfg = Debug|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|ARM64.ActiveCfg = Release|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|ARM64.Build.0 = Release|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x64.ActiveCfg = Release|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x64.Build.0 = Release|x64
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Release|x86.ActiveCfg = Release|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|ARM64.ActiveCfg = Debug|arm64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|ARM64.Build.0 = Debug|arm64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x64.ActiveCfg = Debug|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x64.Build.0 = Debug|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Debug|x86.ActiveCfg = Debug|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|ARM64.ActiveCfg = Release|arm64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|ARM64.Build.0 = Release|arm64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x64.ActiveCfg = Release|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x64.Build.0 = Release|x64
{BBD45704-F220-4774-9C92-D55D822C9E75}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -2020,6 +2044,8 @@ Global
{B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} {B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC} {AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{8290CF58-0E97-45C4-AB41-F3C7C3128AEC} = {AB82E5DD-C32D-4F28-9746-2C780846188E} {8290CF58-0E97-45C4-AB41-F3C7C3128AEC} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
{BBD45704-F220-4774-9C92-D55D822C9E75} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View File

@ -0,0 +1,80 @@
#include "pch.h"
#include "ClassFactory.h"
#include "ExplorerCommand.h"
#include "dllmain.h"
// Class ctor/dtors
ClassFactory::ClassFactory(_In_ REFCLSID clsid) :
m_ref_count(1),
m_clsid(clsid)
{
++globals::ref_count;
}
ClassFactory::~ClassFactory()
{
--globals::ref_count;
}
// Implementations of inherited IUnknown methods
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(ClassFactory, IClassFactory),
{ 0, 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
{
return ++m_ref_count;
}
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
{
auto result = --m_ref_count;
if (result == 0)
{
delete this;
}
return result;
}
// Implementations of inherited IClassFactory methods
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
{
*ppvObject = NULL;
HRESULT hr;
if (pUnkOuter)
{
hr = CLASS_E_NOAGGREGATION;
}
else if (m_clsid == __uuidof(ExplorerCommand))
{
hr = ExplorerCommand::s_CreateInstance(pUnkOuter, riid, ppvObject);
}
else
{
hr = CLASS_E_CLASSNOTAVAILABLE;
}
return hr;
}
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
++globals::ref_count;
}
else
{
--globals::ref_count;
}
return S_OK;
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "pch.h"
class ClassFactory : public IClassFactory
{
public:
ClassFactory(_In_ REFCLSID clsid);
~ClassFactory();
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
IFACEMETHODIMP_(ULONG) AddRef() override;
IFACEMETHODIMP_(ULONG) Release() override;
// IClassFactory
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject) override;
IFACEMETHODIMP LockServer(BOOL fLock) override;
private:
std::atomic<ULONG> m_ref_count;
IID m_clsid;
};

View File

@ -0,0 +1,28 @@
#pragma once
#include "pch.h"
// Localizable constants, these should be converted to resources
namespace constants::localizable
{
// Text shown in the context menu
constexpr WCHAR CommandTitle[] = L"What's using this file?";
}
// Non-localizable constants
namespace constants::nonlocalizable
{
// Description of the registry key
constexpr WCHAR RegistryKeyDescription[] = L"File Locksmith Shell Extension";
// File name of the DLL
constexpr WCHAR FileNameDLL[] = L"ContextMenuEntry.dll";
// File name of the UI executable
constexpr WCHAR FileNameUIExe[] = L"FileLocksmithGUI\\FileLocksmithGUI.exe";
}
// Macros, non-localizable
// Description of the registry key
#define REGISTRY_CONTEXT_MENU_KEY L"FileLocksmithExt"

View File

@ -0,0 +1,275 @@
#include "pch.h"
#include "ExplorerCommand.h"
#include "Constants.h"
#include "dllmain.h"
// Implementations of inherited IUnknown methods
IFACEMETHODIMP ExplorerCommand::QueryInterface(REFIID riid, void** ppv)
{
static const QITAB qit[] = {
QITABENT(ExplorerCommand, IExplorerCommand),
QITABENT(ExplorerCommand, IShellExtInit),
QITABENT(ExplorerCommand, IContextMenu),
{ 0, 0 },
};
return QISearch(this, qit, riid, ppv);
}
IFACEMETHODIMP_(ULONG) ExplorerCommand::AddRef()
{
return ++m_ref_count;
}
IFACEMETHODIMP_(ULONG) ExplorerCommand::Release()
{
auto result = --m_ref_count;
if (result == 0)
{
delete this;
}
return result;
}
// Implementations of inherited IExplorerCommand methods
IFACEMETHODIMP ExplorerCommand::GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName)
{
return SHStrDup(constants::localizable::CommandTitle, ppszName);
}
IFACEMETHODIMP ExplorerCommand::GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon)
{
// Path to the icon should be computed relative to the path of this module
ppszIcon = NULL;
return E_NOTIMPL;
}
IFACEMETHODIMP ExplorerCommand::GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip)
{
// No tooltip for now
return E_NOTIMPL;
}
IFACEMETHODIMP ExplorerCommand::GetCanonicalName(GUID* pguidCommandName)
{
*pguidCommandName = __uuidof(this);
return S_OK;
}
IFACEMETHODIMP ExplorerCommand::GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState)
{
// This should depend on the settings
// For now we'll just keep it always enabled.
*pCmdState = ECS_ENABLED;
return S_OK;
}
IFACEMETHODIMP ExplorerCommand::Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc)
{
// This should call the main exe.
// For now we'll just show a message box.
MessageBoxW(NULL, L"OK", L"OK", MB_OK);
return S_OK;
}
IFACEMETHODIMP ExplorerCommand::GetFlags(EXPCMDFLAGS* pFlags)
{
*pFlags = ECF_DEFAULT;
return S_OK;
}
IFACEMETHODIMP ExplorerCommand::EnumSubCommands(IEnumExplorerCommand** ppEnum)
{
*ppEnum = NULL;
return E_NOTIMPL;
}
// Implementations of inherited IShellExtInit methods
IFACEMETHODIMP ExplorerCommand::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID)
{
m_data_obj = pdtobj;
m_data_obj->AddRef();
return S_OK;
}
// Implementations of inherited IContextMenu methods
IFACEMETHODIMP ExplorerCommand::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
{
HRESULT hr = E_UNEXPECTED;
if (m_data_obj && !(uFlags & (CMF_DEFAULTONLY | CMF_VERBSONLY | CMF_OPTIMIZEFORINVOKE)))
{
MENUITEMINFO mii;
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID | MIIM_STATE;
mii.wID = idCmdFirst++;
mii.fType = MFT_STRING;
hr = SHStrDupW(constants::localizable::CommandTitle, &mii.dwTypeData);
if (FAILED(hr))
{
return hr;
}
mii.fState = MFS_ENABLED;
// TODO icon from file
if (!InsertMenuItem(hmenu, indexMenu, TRUE, &mii))
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
else
{
hr = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1);
}
}
return hr;
}
IFACEMETHODIMP ExplorerCommand::InvokeCommand(CMINVOKECOMMANDINFO* pici)
{
ipc::Writer writer;
if (HRESULT result = writer.start(); FAILED(result))
{
return result;
}
if (HRESULT result = LaunchUI(pici, &writer); FAILED(result))
{
return result;
}
IShellItemArray* shell_item_array;
HRESULT result = SHCreateShellItemArrayFromDataObject(m_data_obj, __uuidof(IShellItemArray), reinterpret_cast<void**>(&shell_item_array));
if (SUCCEEDED(result))
{
DWORD num_items;
shell_item_array->GetCount(&num_items);
for (DWORD i = 0; i < num_items; i++)
{
IShellItem* item;
result = shell_item_array->GetItemAt(i, &item);
if (SUCCEEDED(result))
{
LPWSTR file_path;
result = item->GetDisplayName(SIGDN_FILESYSPATH, &file_path);
if (SUCCEEDED(result))
{
// TODO Aggregate items and send to UI
writer.add_path(file_path);
CoTaskMemFree(file_path);
}
item->Release();
}
}
shell_item_array->Release();
}
return S_OK;
}
IFACEMETHODIMP ExplorerCommand::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pReserved, CHAR* pszName, UINT cchMax)
{
return E_NOTIMPL;
}
HRESULT ExplorerCommand::s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject)
{
*ppvObject = NULL;
HRESULT hr = E_OUTOFMEMORY;
ExplorerCommand* pNew = new (std::nothrow) ExplorerCommand;
if (pNew)
{
hr = pNew->QueryInterface(riid, ppvObject);
pNew->Release();
}
return hr;
}
ExplorerCommand::~ExplorerCommand()
{
if (m_data_obj)
{
m_data_obj->Release();
}
}
// Implementation taken from src/common/utils
// TODO reference that function
inline std::wstring get_module_folderpath(HMODULE mod = nullptr, const bool removeFilename = true)
{
wchar_t buffer[MAX_PATH + 1];
DWORD actual_length = GetModuleFileNameW(mod, buffer, MAX_PATH);
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
const DWORD long_path_length = 0xFFFF; // should be always enough
std::wstring long_filename(long_path_length, L'\0');
actual_length = GetModuleFileNameW(mod, long_filename.data(), long_path_length);
PathRemoveFileSpecW(long_filename.data());
long_filename.resize(std::wcslen(long_filename.data()));
long_filename.shrink_to_fit();
return long_filename;
}
if (removeFilename)
{
PathRemoveFileSpecW(buffer);
}
return { buffer, (UINT)lstrlenW(buffer) };
}
HRESULT ExplorerCommand::LaunchUI(CMINVOKECOMMANDINFO* pici, ipc::Writer* writer)
{
// Compute exe path
std::wstring exe_path = get_module_folderpath(globals::instance);
exe_path += L'\\';
exe_path += constants::nonlocalizable::FileNameUIExe;
HANDLE read_handle = writer->get_read_handle();
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo, sizeof(STARTUPINFO));
startupInfo.cb = sizeof(STARTUPINFO);
startupInfo.hStdInput = read_handle;
startupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (pici)
{
startupInfo.wShowWindow = pici->nShow;
}
else
{
startupInfo.wShowWindow = SW_SHOWNORMAL;
}
PROCESS_INFORMATION processInformation;
std::wstring command_line = L"\"";
command_line += exe_path;
command_line += L"\"\0";
CreateProcessW(
NULL,
command_line.data(),
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&startupInfo,
&processInformation);
// Discard handles
CloseHandle(processInformation.hProcess);
CloseHandle(processInformation.hThread);
return S_OK;
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "pch.h"
// File Locksmith library
#include "../FileLocksmithLib/IPC.h"
#define EXPLORER_COMMAND_UUID_STR "84d68575-e186-46ad-b0cb-baeb45ee29c0"
class __declspec(uuid(EXPLORER_COMMAND_UUID_STR)) ExplorerCommand : public IExplorerCommand, public IShellExtInit, public IContextMenu
{
public:
// IUnknown
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
IFACEMETHODIMP_(ULONG) AddRef() override;
IFACEMETHODIMP_(ULONG) Release() override;
// IExplorerCommand
IFACEMETHODIMP GetTitle(IShellItemArray* psiItemArray, LPWSTR* ppszName) override;
IFACEMETHODIMP GetIcon(IShellItemArray* psiItemArray, LPWSTR* ppszIcon) override;
IFACEMETHODIMP GetToolTip(IShellItemArray* psiItemArray, LPWSTR* ppszInfotip) override;
IFACEMETHODIMP GetCanonicalName(GUID* pguidCommandName) override;
IFACEMETHODIMP GetState(IShellItemArray* psiItemArray, BOOL fOkToBeSlow, EXPCMDSTATE* pCmdState) override;
IFACEMETHODIMP Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc) override;
IFACEMETHODIMP GetFlags(EXPCMDFLAGS* pFlags) override;
IFACEMETHODIMP EnumSubCommands(IEnumExplorerCommand** ppEnum) override;
// IShellExtInit
IFACEMETHODIMP Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject* pdtobj, HKEY hkeyProgID) override;
// IContextMenu
IFACEMETHODIMP QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
IFACEMETHODIMP InvokeCommand(CMINVOKECOMMANDINFO* pici) override;
IFACEMETHODIMP GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pReserved, CHAR* pszName, UINT cchMax) override;
// Static member to create an instance
static HRESULT s_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppvObject);
// Destructor
~ExplorerCommand();
private:
// Helpers
HRESULT LaunchUI(CMINVOKECOMMANDINFO* pici, ipc::Writer* writer);
std::atomic<ULONG> m_ref_count = 1;
IDataObject* m_data_obj = NULL;
};

View File

@ -0,0 +1,172 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{57175ec7-92a5-4c1e-8244-e3fbca2a81de}</ProjectGuid>
<RootNamespace>FileLocksmithExt</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;FILELOCKSMITHEXT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;FILELOCKSMITHLIB_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>dll.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="ClassFactory.h" />
<ClInclude Include="Constants.h" />
<ClInclude Include="dllmain.h" />
<ClInclude Include="ExplorerCommand.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="Registry.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClassFactory.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="ExplorerCommand.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="Registry.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="dll.def" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FileLocksmithLib\FileLocksmithLib.vcxproj">
<Project>{8290cf58-0e97-45c4-ab41-f3c7c3128aec}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ExplorerCommand.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Constants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ClassFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Registry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="dllmain.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="pch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ExplorerCommand.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClassFactory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Registry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="dll.def">
<Filter>Source Files</Filter>
</None>
</ItemGroup>
</Project>

View File

@ -0,0 +1,114 @@
#include "pch.h"
#include "Registry.h"
#include "ExplorerCommand.h"
#include "Constants.h"
#include "dllmain.h"
#define HKEY_ROOT HKEY_CURRENT_USER
bool registry_write_string(LPCWSTR path, LPCWSTR property, LPCWSTR value)
{
HKEY key;
LSTATUS result = RegCreateKeyExW(
HKEY_ROOT,
path,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&key,
NULL
);
if (result != ERROR_SUCCESS)
{
return false;
}
if (value != NULL)
{
result = RegSetValueExW(key, property, 0, REG_SZ, reinterpret_cast<const BYTE*>(value), sizeof(WCHAR) * (1ull + lstrlenW(value)));
}
RegCloseKey(key);
return result == ERROR_SUCCESS;
}
bool registry_delete_tree(LPCWSTR path)
{
LSTATUS result = RegDeleteTreeW(HKEY_ROOT, path);
return result == ERROR_SUCCESS;
}
bool add_registry_keys()
{
if (!registry_write_string(
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}",
NULL,
constants::nonlocalizable::RegistryKeyDescription
))
{
return false;
}
if (!registry_write_string(
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}",
L"ContextMenuOptIn",
L""
))
{
return false;
}
static WCHAR module_file_name[MAX_PATH];
DWORD result = GetModuleFileNameW(globals::instance, module_file_name, ARRAYSIZE(module_file_name));
if (result == 0)
{
return false;
}
if (!registry_write_string(
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}\\InprocServer32",
NULL,
module_file_name
))
{
return false;
}
if (!registry_write_string(
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR L"}\\InprocServer32",
L"ThreadingModel",
L"Apartment"
))
{
return false;
}
if (!registry_write_string(
L"Software\\Classes\\AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\" REGISTRY_CONTEXT_MENU_KEY,
L"",
L"{" EXPLORER_COMMAND_UUID_STR L"}"
))
{
return false;
}
return true;
}
bool delete_registry_keys()
{
bool ok = true;
ok &= registry_delete_tree(
L"Software\\Classes\\CLSID\\{" EXPLORER_COMMAND_UUID_STR "}"
);
ok &= registry_delete_tree(
L"Software\\Classes\\AllFileSystemObjects\\ShellEx\\ContextMenuHandlers\\" REGISTRY_CONTEXT_MENU_KEY
);
return ok;
}

View File

@ -0,0 +1,6 @@
#pragma once
#include "pch.h"
bool add_registry_keys();
bool delete_registry_keys();

View File

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

View File

@ -0,0 +1,80 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
// Additional libraries to link
#pragma comment(lib, "shlwapi")
#include "Registry.h"
#include "ClassFactory.h"
namespace globals
{
HMODULE instance;
std::atomic<ULONG> ref_count;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
globals::instance = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
STDAPI DllRegisterServer()
{
if (!add_registry_keys())
{
// Best effort here
delete_registry_keys();
return E_FAIL;
}
return S_OK;
}
STDAPI DllUnregisterServer()
{
return delete_registry_keys() ? S_OK : E_FAIL;
}
STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void** ppv)
{
HRESULT result = E_FAIL;
*ppv = NULL;
ClassFactory* class_factory = new (std::nothrow) ClassFactory(clsid);
if (class_factory)
{
result = class_factory->QueryInterface(riid, ppv);
class_factory->Release();
}
return result;
}
STDAPI DllCanUnloadNow(void)
{
return globals::ref_count == 0 ? S_OK : S_FALSE;
}
// Things to implement:
// 1. (DONE) A class which implements IExplorerCommand
// 2. (DONE) A class which implements IClassFactory
// 3. (DONE) DLL register/unregister functions which will create registry entries
// 4. (DONE) Other DLL exported functions
// 5. (DONE) Implement IShellExtInit in ExplorerCommand
// 6. (DONE) Implement IContextMenu in ExplorerCommand
// 7. (DONE) Extract useful functions from HandlesExperiment to a static library
// 8. (DONE) Implement IPC in Lib - to be used between UI and DLL
// 9. Implement UI

View File

@ -0,0 +1,9 @@
#pragma once
#include "pch.h"
namespace globals
{
extern HMODULE instance;
extern std::atomic<ULONG> ref_count;
}

View File

@ -0,0 +1,5 @@
// pch.cpp: source file corresponding to the pre-compiled header
#include "pch.h"
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.

View File

@ -0,0 +1,12 @@
#pragma once
// add headers that you want to pre-compile here
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <Windows.h>
#include <Shlwapi.h>
#include <ShlObj_core.h>
// C++ Standard library
#include <atomic>
#include <string>

View File

@ -0,0 +1,3 @@
namespace FileLocksmithGUI
{
}

View File

@ -0,0 +1,15 @@
<Application
x:Class="FileLocksmithGUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FileLocksmithGUI">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>

View File

@ -0,0 +1,46 @@
#include "pch.h"
#include "App.xaml.h"
#include "MainWindow.xaml.h"
using namespace winrt;
using namespace Windows::Foundation;
using namespace Microsoft::UI::Xaml;
using namespace Microsoft::UI::Xaml::Controls;
using namespace Microsoft::UI::Xaml::Navigation;
using namespace FileLocksmithGUI;
using namespace FileLocksmithGUI::implementation;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)
{
if (IsDebuggerPresent())
{
auto errorMessage = e.Message();
__debugbreak();
}
});
#endif
}
/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs const&)
{
window = make<MainWindow>();
window.Activate();
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "App.xaml.g.h"
namespace winrt::FileLocksmithGUI::implementation
{
struct App : AppT<App>
{
App();
void OnLaunched(Microsoft::UI::Xaml::LaunchActivatedEventArgs const&);
private:
winrt::Microsoft::UI::Xaml::Window window{ nullptr };
};
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props')" />
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" />
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
<MinimalCoreWin>true</MinimalCoreWin>
<ProjectGuid>{bbd45704-f220-4774-9c92-d55d822c9e75}</ProjectGuid>
<ProjectName>FileLocksmithGUI</ProjectName>
<RootNamespace>FileLocksmithGUI</RootNamespace>
<!--
$(TargetName) should be same as $(RootNamespace) so that the produced binaries (.exe/.pri/etc.)
have a name that matches the .winmd
-->
<TargetName>$(RootNamespace)</TargetName>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>16.0</MinimumVisualStudioVersion>
<AppContainerApplication>false</AppContainerApplication>
<AppxPackage>false</AppxPackage>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
<UseWinUI>true</UseWinUI>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>None</WindowsPackageType>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<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="Debug|arm64">
<Configuration>Debug</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|arm64">
<Configuration>Release</Configuration>
<Platform>arm64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<DesktopCompatible>true</DesktopCompatible>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
<WarningLevel>Level4</WarningLevel>
<AdditionalOptions>%(AdditionalOptions) /bigobj</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup Condition="'$(WindowsPackageType)'!='None' and Exists('Package.appxmanifest')">
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Manifest Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
<ClInclude Include="App.xaml.h">
<DependentUpon>App.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="MainWindow.xaml.h">
<DependentUpon>MainWindow.xaml</DependentUpon>
</ClInclude>
<ClInclude Include="ProcessEntry.xaml.h">
<DependentUpon>ProcessEntry.xaml</DependentUpon>
<SubType>Code</SubType>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
<Page Include="MainWindow.xaml" />
<Page Include="ProcessEntry.xaml">
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="App.xaml.cpp">
<DependentUpon>App.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="MainWindow.xaml.cpp">
<DependentUpon>MainWindow.xaml</DependentUpon>
</ClCompile>
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
<ClCompile Include="ProcessEntry.xaml.cpp">
<DependentUpon>ProcessEntry.xaml</DependentUpon>
<SubType>Code</SubType>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Midl Include="App.idl">
<SubType>Code</SubType>
<DependentUpon>App.xaml</DependentUpon>
</Midl>
<Midl Include="MainWindow.idl">
<SubType>Code</SubType>
<DependentUpon>MainWindow.xaml</DependentUpon>
</Midl>
<Midl Include="ProcessEntry.idl">
<DependentUpon>ProcessEntry.xaml</DependentUpon>
<SubType>Code</SubType>
</Midl>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt">
<DeploymentContent>false</DeploymentContent>
</Text>
</ItemGroup>
<ItemGroup>
<Image Include="Assets\LockScreenLogo.scale-200.png" />
<Image Include="Assets\SplashScreen.scale-200.png" />
<Image Include="Assets\Square150x150Logo.scale-200.png" />
<Image Include="Assets\Square44x44Logo.scale-200.png" />
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Image Include="Assets\StoreLogo.png" />
<Image Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FileLocksmithLib\FileLocksmithLib.vcxproj">
<Project>{8290cf58-0e97-45c4-ab41-f3c7c3128aec}</Project>
</ProjectReference>
</ItemGroup>
<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" />
<Import Project="..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets')" />
<Import Project="..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
</ImportGroup>
<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\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22000.194\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.props'))" />
<Error Condition="!Exists('..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.WindowsAppSDK.1.1.5\build\native\Microsoft.WindowsAppSDK.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ApplicationDefinition Include="App.xaml" />
</ItemGroup>
<ItemGroup>
<Page Include="MainWindow.xaml" />
<Page Include="ProcessEntry.xaml" />
</ItemGroup>
<ItemGroup>
<Midl Include="App.idl" />
<Midl Include="MainWindow.idl" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp" />
<ClCompile Include="$(GeneratedFilesDir)module.g.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="pch.h" />
</ItemGroup>
<ItemGroup>
<Image Include="Assets\Wide310x150Logo.scale-200.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\StoreLogo.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\Square150x150Logo.scale-200.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\Square44x44Logo.scale-200.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\SplashScreen.scale-200.png">
<Filter>Assets</Filter>
</Image>
<Image Include="Assets\LockScreenLogo.scale-200.png">
<Filter>Assets</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Filter Include="Assets">
<UniqueIdentifier>{bbd45704-f220-4774-9c92-d55d822c9e75}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="readme.txt" />
</ItemGroup>
<ItemGroup>
<Manifest Include="app.manifest" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,8 @@
namespace FileLocksmithGUI
{
[default_interface]
runtimeclass MainWindow : Microsoft.UI.Xaml.Window
{
MainWindow();
}
}

View File

@ -0,0 +1,13 @@
<Window
x:Class="FileLocksmithGUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FileLocksmithGUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<ScrollViewer>
<StackPanel x:Name="stackPanel" Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</ScrollViewer>
</Window>

View File

@ -0,0 +1,84 @@
#include "pch.h"
#include "MainWindow.xaml.h"
#if __has_include("MainWindow.g.cpp")
#include "MainWindow.g.cpp"
#endif
#include "../FileLocksmithLib/IPC.h"
#include "../FileLocksmithLib/FileLocksmith.h"
#pragma comment(lib, "shcore") // GetDpiForMonitor
using namespace winrt;
using namespace Microsoft::UI;
using namespace Microsoft::UI::Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace winrt::FileLocksmithGUI::implementation
{
MainWindow::MainWindow()
{
place_and_resize();
InitializeComponent();
find_processes();
}
void MainWindow::find_processes()
{
auto paths = ipc::read_paths_from_stdin();
m_process_info = find_processes_recursive(paths);
// TODO move to another thread
stackPanel().Children().Clear();
for (const auto& process : m_process_info)
{
ProcessEntry entry(process.name, process.pid, process.num_files);
stackPanel().Children().Append(entry);
}
}
void MainWindow::place_and_resize()
{
// Get native handle
auto windowNative{ this->try_as<::IWindowNative>() };
winrt::check_bool(windowNative);
HWND hwnd{ 0 };
windowNative->get_WindowHandle(&hwnd);
// Get mouse cursor position
POINT cursorPosition{0, 0};
GetCursorPos(&cursorPosition);
::Windows::Graphics::PointInt32 point{ cursorPosition.x, cursorPosition.y };
// Get monitor area for mouse position
auto display_area = Windowing::DisplayArea::GetFromPoint(point, Windowing::DisplayAreaFallback::Nearest);
HMONITOR monitor = MonitorFromPoint(cursorPosition, MONITOR_DEFAULTTOPRIMARY);
MONITORINFOEXW monitor_info;
monitor_info.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfoW(monitor, &monitor_info);
UINT dpi_x, dpi_y;
GetDpiForMonitor(monitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
UINT window_dpi = GetDpiForWindow(hwnd);
int width = 720;
int height = 405;
winrt::Windows::Graphics::RectInt32 rect;
// Scale window size
rect.Width = (int32_t)(width * (float)window_dpi / dpi_x);
rect.Height = (int32_t)(height * (float)window_dpi / dpi_y);
// Center to screen
rect.X = display_area.WorkArea().X + display_area.WorkArea().Width / 2 - width / 2;
rect.Y = display_area.WorkArea().Y + display_area.WorkArea().Height / 2 - height / 2;
// Get app window
auto window_id = GetWindowIdFromWindow(hwnd);
auto app_window = Windowing::AppWindow::GetFromWindowId(window_id);
app_window.MoveAndResize(rect);
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "MainWindow.g.h"
#include "../FileLocksmithLib/FileLocksmith.h"
namespace winrt::FileLocksmithGUI::implementation
{
struct MainWindow : MainWindowT<MainWindow>
{
MainWindow();
private:
std::vector<ProcessResult> m_process_info;
void find_processes();
void place_and_resize();
};
}
namespace winrt::FileLocksmithGUI::factory_implementation
{
struct MainWindow : MainWindowT<MainWindow, implementation::MainWindow>
{
};
}

View File

@ -0,0 +1,48 @@
<?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:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="fc28f10c-afe2-4208-b33c-e6b9d0d19af3"
Publisher="CN=Admin"
Version="1.0.0.0" />
<Properties>
<DisplayName>FileLocksmithGUI</DisplayName>
<PublisherDisplayName>Admin</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.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="FileLocksmithGUI"
Description="FileLocksmithGUI"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@ -0,0 +1,8 @@
namespace FileLocksmithGUI
{
[default_interface]
runtimeclass ProcessEntry : Microsoft.UI.Xaml.Controls.UserControl
{
ProcessEntry(String process, UInt32 pid, UInt64 num_files);
}
}

View File

@ -0,0 +1,26 @@
<UserControl
x:Class="FileLocksmithGUI.ProcessEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:FileLocksmithGUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal" Width="720">
<BitmapIcon Name="processIcon"></BitmapIcon>
<StackPanel Orientation="Vertical" Width="600">
<TextBlock Margin="4" FontSize="28" Name="processName" MaxWidth="600"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="4" FontSize="12" Name="processPid" HorizontalAlignment="Left"/>
<TextBlock Grid.Column="1" Margin="4" FontSize="12" Name="processFileCount" HorizontalAlignment="Center"/>
</Grid>
</StackPanel>
<Button Click="killProcessClick">Kill process</Button>
</StackPanel>
</UserControl>

View File

@ -0,0 +1,46 @@
#include "pch.h"
#include "ProcessEntry.xaml.h"
#if __has_include("ProcessEntry.g.cpp")
#include "ProcessEntry.g.cpp"
#endif
using namespace winrt;
using namespace Microsoft::UI::Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace winrt::FileLocksmithGUI::implementation
{
ProcessEntry::ProcessEntry(const winrt::hstring& process, DWORD pid, uint64_t num_files)
{
InitializeComponent();
processName().Text(process);
auto processPidStr = L"Process ID: " + std::to_wstring(pid);
auto processFileCountStr = L"Files used: " + std::to_wstring(num_files);
processPid().Text(processPidStr);
processFileCount().Text(processFileCountStr);
m_pid = pid;
}
void ProcessEntry::killProcessClick(Windows::Foundation::IInspectable const&, RoutedEventArgs const&)
{
HANDLE process = OpenProcess(PROCESS_TERMINATE, FALSE, m_pid);
if (!process || !TerminateProcess(process, 1))
{
MessageBoxW(NULL, L"Failed to kill process.", L"Error", MB_OK);
return;
}
CloseHandle(process);
auto siblings = Parent().as<Controls::StackPanel>().Children();
if (uint32_t index; siblings.IndexOf(*this, index))
{
siblings.RemoveAt(index);
}
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "winrt/Microsoft.UI.Xaml.h"
#include "winrt/Microsoft.UI.Xaml.Markup.h"
#include "winrt/Microsoft.UI.Xaml.Controls.Primitives.h"
#include "ProcessEntry.g.h"
namespace winrt::FileLocksmithGUI::implementation
{
struct ProcessEntry : ProcessEntryT<ProcessEntry>
{
ProcessEntry(const winrt::hstring& process, DWORD pid, uint64_t num_files);
void killProcessClick(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e);
private:
DWORD m_pid;
};
}
namespace winrt::FileLocksmithGUI::factory_implementation
{
struct ProcessEntry : ProcessEntryT<ProcessEntry, implementation::ProcessEntry>
{
};
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="FileLocksmithGUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- The combination of below two tags have the following effect:
1) Per-Monitor for >= Windows 10 Anniversary Update
2) System < Windows 10 Anniversary Update
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Windows.CppWinRT" version="2.0.210806.1" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.211019.2" targetFramework="native" />
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22000.194" targetFramework="native" />
<package id="Microsoft.WindowsAppSDK" version="1.1.5" targetFramework="native" />
</packages>

View File

@ -0,0 +1 @@
#include "pch.h"

View File

@ -0,0 +1,29 @@
#pragma once
#include <windows.h>
#include <unknwn.h>
#include <restrictederrorinfo.h>
#include <hstring.h>
#include <ShellScalingApi.h>
// Undefine GetCurrentTime macro to prevent
// conflict with Storyboard::GetCurrentTime
#undef GetCurrentTime
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.ApplicationModel.Activation.h>
#include <winrt/Microsoft.UI.Composition.h>
#include <winrt/Microsoft.UI.Interop.h>
#include <winrt/Microsoft.UI.Xaml.h>
#include <winrt/Microsoft.UI.Xaml.Controls.h>
#include <winrt/Microsoft.UI.Xaml.Controls.Primitives.h>
#include <winrt/Microsoft.UI.Xaml.Data.h>
#include <winrt/Microsoft.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Xaml.Markup.h>
#include <winrt/Microsoft.UI.Xaml.Media.h>
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
#include <winrt/Microsoft.UI.Xaml.Shapes.h>
#include <winrt/Microsoft.UI.Dispatching.h>
#include <winrt/Microsoft.UI.Windowing.h>
#include <wil/cppwinrt_helpers.h>
#include <microsoft.ui.xaml.window.h>

View File

@ -0,0 +1,27 @@
========================================================================
FileLocksmithGUI Project Overview
========================================================================
This project demonstrates how to get started writing WinUI3 apps directly
with standard C++, using the Windows App SDK and C++/WinRT packages and
XAML compiler support to generate implementation headers from interface
(IDL) files. These headers can then be used to implement the local
Windows Runtime classes referenced in the app's XAML pages.
Steps:
1. Create an interface (IDL) file to define any local Windows Runtime
classes referenced in the app's XAML pages.
2. Build the project once to generate implementation templates under
the "Generated Files" folder, as well as skeleton class definitions
under "Generated Files\sources".
3. Use the skeleton class definitions for reference to implement your
Windows Runtime classes.
========================================================================
Learn more about Windows App SDK here:
https://docs.microsoft.com/windows/apps/windows-app-sdk/
Learn more about WinUI3 here:
https://docs.microsoft.com/windows/apps/winui/winui3/
Learn more about C++/WinRT here:
http://aka.ms/cppwinrt/
========================================================================