Skip to content

Commit

Permalink
Fix icon missing issue due to file system permissions
Browse files Browse the repository at this point in the history
Fix #2, Close #6
  • Loading branch information
GurliGebis authored and donho committed Mar 28, 2023
1 parent 5e8aac9 commit e4f9037
Show file tree
Hide file tree
Showing 13 changed files with 135 additions and 44 deletions.
32 changes: 32 additions & 0 deletions AclHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "pch.h"
#include "AclHelper.h"

AclHelper::AclHelper()
{
emptyAcl = (PACL)malloc(sizeof(ACL));

if (emptyAcl)
{
InitializeAcl(emptyAcl, sizeof(ACL), ACL_REVISION);
}
}

AclHelper::~AclHelper()
{
if (emptyAcl)
{
free(emptyAcl);
}
}

DWORD AclHelper::ResetAcl(const wstring& path)
{
if (emptyAcl)
{
return SetNamedSecurityInfoW(const_cast<LPWSTR>(path.c_str()), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION, NULL, NULL, emptyAcl, NULL);
}
else
{
return ERROR_OUTOFMEMORY;
}
}
13 changes: 13 additions & 0 deletions AclHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

class AclHelper
{
public:
AclHelper();
~AclHelper();

DWORD ResetAcl(const wstring& path);

private:
PACL emptyAcl;
};
21 changes: 11 additions & 10 deletions EditWithNppExplorerCommandHandler.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
#include "pch.h"
#include "EditWithNppExplorerCommandHandler.h"

#include "Helpers.h"
#include "PathHelper.h"

using namespace NppShell::CommandHandlers;
using namespace NppShell::Helpers;

const wstring EditWithNppExplorerCommandHandler::GetNppExecutableFullPath()
{
const wstring path = GetInstallationPath();
const wstring path = GetApplicationPath();
const wstring fileName = L"\\notepad++.exe";

return L"\"" + path + fileName + L"\"";
return path + fileName;
}

const wstring EditWithNppExplorerCommandHandler::Title()
Expand All @@ -26,12 +26,12 @@ const wstring EditWithNppExplorerCommandHandler::Icon()
return fileName;
}

const wstring EditWithNppExplorerCommandHandler::GetCommandLine()
const wstring EditWithNppExplorerCommandHandler::GetCommandLine(const wstring& itemName)
{
const wstring fileName = GetNppExecutableFullPath();
const wstring parameters = L"\"%1\"";
const wstring parameters = L"\"" + itemName + L"\"";

return fileName + L" " + parameters;
return L"\"" + fileName + L"\" " + parameters;
}

IFACEMETHODIMP EditWithNppExplorerCommandHandler::Invoke(IShellItemArray* psiItemArray, IBindCtx* pbc) noexcept try
Expand All @@ -54,8 +54,8 @@ IFACEMETHODIMP EditWithNppExplorerCommandHandler::Invoke(IShellItemArray* psiIte
psiItemArray->GetItemAt(i, &psi);
RETURN_IF_FAILED(psi->GetDisplayName(SIGDN_FILESYSPATH, &itemName));

std::wstring cmdline = this->GetCommandLine();
cmdline = cmdline.replace(cmdline.find(L"%1"), 2, itemName);
const wstring applicationName = GetNppExecutableFullPath();
const wstring commandLine = GetCommandLine(itemName);

STARTUPINFO si;
PROCESS_INFORMATION pi;
Expand All @@ -64,9 +64,10 @@ IFACEMETHODIMP EditWithNppExplorerCommandHandler::Invoke(IShellItemArray* psiIte
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));

wchar_t* command = (LPWSTR)cmdline.c_str();
wchar_t* application = (LPWSTR)applicationName.c_str();
wchar_t* command = (LPWSTR)commandLine.c_str();

if (!CreateProcess(nullptr, command, nullptr, nullptr, false, CREATE_NEW_PROCESS_GROUP, nullptr, nullptr, &si, &pi))
if (!CreateProcessW(application, command, nullptr, nullptr, false, CREATE_NEW_PROCESS_GROUP, nullptr, nullptr, &si, &pi))
{
return S_OK;
}
Expand Down
2 changes: 1 addition & 1 deletion EditWithNppExplorerCommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ namespace NppShell::CommandHandlers

private:
const wstring GetNppExecutableFullPath();
const wstring GetCommandLine();
const wstring GetCommandLine(const wstring& itemName);
};
}
13 changes: 0 additions & 13 deletions Helpers.cpp

This file was deleted.

31 changes: 25 additions & 6 deletions Installer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "Installer.h"

#include "EditWithNppExplorerCommandHandler.h"
#include "PathHelper.h"
#include "AclHelper.h"

#define GUID_STRING_SIZE 40

Expand Down Expand Up @@ -126,7 +128,7 @@ LRESULT CreateRegistryKey(const HKEY hive, const wstring& key, const wstring& na
return lResult;
}

LRESULT CleanupRegistry(const wstring guid)
LRESULT CleanupRegistry(const wstring& guid)
{
constexpr int bufferSize = MAX_PATH + GUID_STRING_SIZE;
WCHAR buffer[bufferSize];
Expand Down Expand Up @@ -233,12 +235,24 @@ HRESULT MoveFileToTempAndScheduleDeletion(const wstring& filePath)
return S_OK;
}

HRESULT ResetAclPermissionsOnApplicationFolder()
{
// First we get the path where Notepad++ is installed.
const wstring applicationPath = GetApplicationPath();

// Create a new AclHelper
AclHelper aclHelper;

// Reset the ACL of the folder where Notepad++ is installed.
aclHelper.ResetAcl(applicationPath);
}

HRESULT NppShell::Installer::RegisterSparsePackage()
{
PackageManager packageManager;
AddPackageOptions options;

const wstring externalLocation = GetInstallationPath();
const wstring externalLocation = GetContextMenuPath();
const wstring sparsePkgPath = externalLocation + L"\\NppShell.msix";

Uri externalUri(externalLocation);
Expand Down Expand Up @@ -290,12 +304,15 @@ HRESULT NppShell::Installer::UnregisterSparsePackage()
break;
}

// After unregistering the sparse package, we reset the folder permissions of the folder where we are installed.
ResetAclPermissionsOnApplicationFolder();

return S_OK;
}

HRESULT NppShell::Installer::RegisterOldContextMenu()
{
const wstring installationPath = GetInstallationPath();
const wstring installationPath = GetContextMenuPath();
const wstring guid = GetCLSIDString();

CreateRegistryKey(HKEY_LOCAL_MACHINE, ShellKey, L"ExplorerCommandHandler", guid.c_str());
Expand Down Expand Up @@ -340,9 +357,11 @@ HRESULT NppShell::Installer::Install()
result = RegisterOldContextMenu();
}

// Ensure NppModernShell files have been moved away.
MoveFileToTempAndScheduleDeletion(GetInstallationPath() + L"\\NppModernShell.dll");
MoveFileToTempAndScheduleDeletion(GetInstallationPath() + L"\\NppModernShell.msix");
// Ensure NppModernShell and NppShell files have been moved away from the main program directory.
MoveFileToTempAndScheduleDeletion(GetApplicationPath() + L"\\NppShell.dll");
MoveFileToTempAndScheduleDeletion(GetApplicationPath() + L"\\NppShell.msix");
MoveFileToTempAndScheduleDeletion(GetApplicationPath() + L"\\NppModernShell.dll");
MoveFileToTempAndScheduleDeletion(GetApplicationPath() + L"\\NppModernShell.msix");

SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);

Expand Down
6 changes: 2 additions & 4 deletions Installer.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#pragma once
#include "pch.h"

#include "Helpers.h"

namespace NppShell::Installer
{
HRESULT RegisterOldContextMenu();
Expand All @@ -13,6 +11,6 @@ namespace NppShell::Installer

HRESULT Install();
HRESULT Uninstall();
}

STDAPI CleanupDll();
}
STDAPI CleanupDll();
6 changes: 4 additions & 2 deletions NppShell.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -255,19 +255,21 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="AclHelper.h" />
<ClInclude Include="EditWithNppExplorerCommandHandler.h" />
<ClInclude Include="ExplorerCommandBase.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="Helpers.h" />
<ClInclude Include="PathHelper.h" />
<ClInclude Include="Installer.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="SimpleFactory.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="AclHelper.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="EditWithNppExplorerCommandHandler.cpp" />
<ClCompile Include="ExplorerCommandBase.cpp" />
<ClCompile Include="Helpers.cpp" />
<ClCompile Include="PathHelper.cpp" />
<ClCompile Include="Installer.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
Expand Down
17 changes: 15 additions & 2 deletions NppShell.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
<Filter Include="Factories">
<UniqueIdentifier>{a0f353df-9c6f-4612-a2d1-98aa7a6d6893}</UniqueIdentifier>
</Filter>
<Filter Include="Helpers">
<UniqueIdentifier>{9c186a78-bd74-4ac7-b560-e61aeb6d2350}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="EditWithNppExplorerCommandHandler.h">
Expand All @@ -22,11 +25,16 @@
<Filter>Installer</Filter>
</ClInclude>
<ClInclude Include="pch.h" />
<ClInclude Include="Helpers.h" />
<ClInclude Include="framework.h" />
<ClInclude Include="SimpleFactory.h">
<Filter>Factories</Filter>
</ClInclude>
<ClInclude Include="PathHelper.h">
<Filter>Helpers</Filter>
</ClInclude>
<ClInclude Include="AclHelper.h">
<Filter>Helpers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="EditWithNppExplorerCommandHandler.cpp">
Expand All @@ -39,8 +47,13 @@
<Filter>Installer</Filter>
</ClCompile>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="Helpers.cpp" />
<ClCompile Include="pch.cpp" />
<ClCompile Include="PathHelper.cpp">
<Filter>Helpers</Filter>
</ClCompile>
<ClCompile Include="AclHelper.cpp">
<Filter>Helpers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down
26 changes: 26 additions & 0 deletions PathHelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "pch.h"
#include "PathHelper.h"

using namespace NppShell::Helpers;
using namespace std::filesystem;

extern HMODULE thisModule;

const path GetThisModulePath()
{
wchar_t pathBuffer[FILENAME_MAX] = { 0 };
GetModuleFileName(thisModule, pathBuffer, FILENAME_MAX);
return path(pathBuffer);
}

const wstring NppShell::Helpers::GetApplicationPath()
{
path modulePath = GetThisModulePath();
return modulePath.parent_path().parent_path().wstring();
}

const wstring NppShell::Helpers::GetContextMenuPath()
{
path modulePath = GetThisModulePath();
return modulePath.parent_path().wstring();
}
3 changes: 2 additions & 1 deletion Helpers.h → PathHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

namespace NppShell::Helpers
{
const wstring GetInstallationPath();
const wstring GetApplicationPath();
const wstring GetContextMenuPath();
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ They need to be there, since the DLL is looking for notepad++.exe in the same di
## The installer should, upon installation, install the package.
When the installer is running, after all the files has been copied into the program files directory, the follow command should be be run to run the register function to register the package:
```
regsvr32.exe /s .\NppShell.dll
regsvr32.exe /s .\contextmenu\NppShell.dll
```

Remember to wait for the regsvr32 process to exit before continuing.

## The installer should, upon uninstallation, uninstall the package.
When the uninstaller is running, it should run this command to unregister the package:
```
regsvr32.exe /s /u .\NppShell.dll
regsvr32.exe /s /u .\contextmenu\NppShell.dll
```

Here we need to wait for regsvr32 to finish, since if it isn't finished, the dll file will be locked by explorer.
5 changes: 2 additions & 3 deletions framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
#include <pathcch.h>
#include <aclapi.h>
#include <shlwapi.h>
#include <shlobj.h>
#include <shobjidl_core.h>
Expand All @@ -22,5 +22,4 @@

// Link libraries
#pragma comment(lib, "shlwapi.lib")
#pragma comment(lib, "runtimeobject.lib")
#pragma comment(lib, "pathcch.lib")
#pragma comment(lib, "runtimeobject.lib")

0 comments on commit e4f9037

Please sign in to comment.