Jump to content

[Feature request] Set custom app files (plugins) folder


Recommended Posts

I use Paint.NET on multiple machines where I put app files (plugins) in my personal OneDrive, so I don't have to maintain this manually on all the devices.

 

For machines without Known Folder Move (KFM) with OneDrive for Business, it has worked fine to create a directory symbolic link from "%USERPROFILE%\Documents\Paint.NET App Files" to "%ONEDRIVECONSUMER%\_Share\AppData\Paint.net\AppFiles", where I have the folders "Effects", "FileTypes" and "Shapes".

  • The "_Share" folder in my OneDrive is set to always be available offline, so no "Files on-deman" causing issues here.
  • Running v4.2.16 from Microsoft Store, but don't think that's relevant here.
  • Here is the CMD (as admin) command I used, if anyone is interested:
    mklink /D "%USERPROFILE%\Documents\Paint.NET App Files" "%ONEDRIVECONSUMER%\_Share\AppData\Paint.net\AppFiles"

     

I think this failed this time due to my company using known folder move (KFM) with OneDrive for Business, as I see Paint.NET have created a "paint.net App Files" folder inside "%ONEDRIVECOMMERCIAL%\Documents". But symbolic linking from one OneDrive to another makes changes one place being uploaded to both OneDrives, so I'd rather avoid that if I could.

 

Then I thought: It would be nice if it was possible to set a different directory for Paint.NET app files. Then I could just set this settings to the folder in my OneDrive.

Edited by olavrb
Link to comment
Share on other sites

I looked into this, as I got several request for it when I added the paint.net App Files plugin loading. IIRC, I couldn't find a good API for determining the right OneDrive folder. Maybe I'm remembering wrong.

 

Does anyone know what OneDrive API to use the get the location(s) of its folder(s)? Or maybe it's just the %ONEDRIVE*% environment variables...

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

16 hours ago, olavrb said:

I use Paint.NET on multiple machines where I put app files (plugins) in my personal OneDrive, so I don't have to maintain this manually on all the devices.

 

Woah. I did not realize you could do that. </impressed> 🤯

Link to comment
Share on other sites

I think I've come up with a workable solution that isn't also a Lovecraftian security disaster waiting to happen.

 

The problem with adding the ability to install/load plugins via OneDrive is that a remote attacker/hacker who got control of your OneDrive account could literally push malware onto your system. No need to get access to your physical system, they could be anywhere in the world. So, this definitely can't be enabled by default.

 

Here's what I'm implementing for 4.3, which involves 2 registry keys (there's no UI for this):

  1. Set HKEY_LOCAL_MACHINE \ Software \ paint.net \ "Plugins/AllowAdditionalPluginDirectoryRoots" (without the quotes) to true (as a string / REG_SZ).
  2. Set HKEY_CURRENT_USER \ Software \ paint.net \ "Plugins/AdditionalPluginDirectoryRoots" to a semicolon-delimited list of directories (just like setting PATH). Within those directories you can then create the usual subdirectories of FileTypes, Effects, and Shapes. You can use environment variables here, so something like %OneDrive%\Documents\paint.net Plugins is perfectly valid.

Having the enablement of this tucked behind a registry key that requires administrator privilege helps ensure that local malware can't enable a remote attacker to have the ability to push code to your system.

 

The portable version of the app can't participate in this, as it has no notion of a SystemWide settings hive (JSON file), but that's okay because you can just package your plugins next to the app itself. 

  • Like 1

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

  • 3 weeks later...

@Rick Brewster

 

Just saw 4.3 got installed through Microsoft Store today. Then had to check the forums. Then saw that you've implemented this feature request. Sweet. :)

 

I then went ahead to try it. Made following PowerShell script:

 

Spoiler
#Requires -RunAsAdministrator
#Requires -Version 5.1
<#
    .SYNOPSIS
        Sets additional plugin directories for Paint.NET

    .NOTES
        Author:   Olav Rønnestad Birkeland
        Created:  210923
        Modified: 210923

    .EXAMPLE
        & $psISE.'CurrentFile'.'FullPath'
#>


# Input parameters
[OutputType($null)]
Param()


# PowerShell preferences
$ErrorActionPreference = 'Stop'
$InformationPreference = 'Continue'


# Assets
$RegistryValues = [ordered]@{
    'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\paint.net' = [ordered]@{
        'Plugins/AllowAdditionalPluginDirectoryRoots' = [byte] 1
    }
    'Registry::HKEY_CURRENT_USER\SOFTWARE\paint.net' = [ordered]@{
        'Plugins/AdditionalPluginDirectoryRoots' = [string](
            '{0}\_Share\AppData\Paint.net\AppFiles' -f $env:OneDriveConsumer
        )
    }
}


# Set registry values
$RegistryValues.GetEnumerator().ForEach{
    $Path = [string] $_.'Name'
    if (-not (Test-Path -Path $Path -PathType 'Container')) {
        $null = New-Item -Path $Path -ItemType 'Directory' -Force
    }
    $_.'Value'.GetEnumerator().ForEach{
        $null = Set-ItemProperty -Path $Path -Name $_.'Name' -Value $_.'Value' -Type ($(if($_.'Value' -is [byte]){'DWord'}else{'String'})) -Force
    }
}

 

 

 

My "%OneDriveConsumer%\_Share\AppData\Paint.net\AppFiles" looks like attached picture. Inside there I have the MozJpeg plugins (https://github.com/0xC0000054/pdn-mozjpeg) amongst others.

 

But I can't save to Mozjpeg. So don't think I've done it right. Settings don't mention any errors in "Plugin Errors". Except the already reported "PaintDotNet.Effects.dll.

 

Do you see anything obious?

 

  • I assume the name for each registry key is like you wrote it "Plugins/AdditionalPluginDirectoryRoots", with forward slash and all.
  • For HKLM, you say true, registry don't have booleans, so I went with DWord.
  • For HKCU, I have absolute path, as you can see from the screenshot.

 

Spoiler

The folder HKCU points to

image.png

HKCU

image.png

HKLM

image.png

 

 

Edited by olavrb
Link to comment
Share on other sites

Quote

For HKLM, you say true, registry don't have booleans, so I went with DWord.

 

No; it needs to be a string (REG_SZ) whose value is "true" (without the quotes)

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

2 minutes ago, Rick Brewster said:

 

No; it needs to be a string (REG_SZ) whose value is "true" (without the quotes)

 

Ahh. That did it. Sweet. Thank you. :) 

Capture.PNG

 

Corrected PowerShell if anyone is interested.

 

Spoiler
#Requires -RunAsAdministrator
#Requires -Version 5.1
<#
    .SYNOPSIS
        Sets additional plugin directories for Paint.NET

    .NOTES
        Author:   Olav Rønnestad Birkeland
        Created:  210923
        Modified: 210923

    .EXAMPLE
        & $psISE.'CurrentFile'.'FullPath'
#>


# Input parameters
[OutputType($null)]
Param()


# PowerShell preferences
$ErrorActionPreference = 'Stop'
$InformationPreference = 'Continue'


# Assets
$RegistryValues = [ordered]@{
    'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\paint.net' = [ordered]@{
        'Plugins/AllowAdditionalPluginDirectoryRoots' = [string] 'true'
    }
    'Registry::HKEY_CURRENT_USER\SOFTWARE\paint.net' = [ordered]@{
        'Plugins/AdditionalPluginDirectoryRoots' = [string](
            '{0}\_Share\AppData\Paint.net\AppFiles' -f $env:OneDriveConsumer
        )
    }
}


# Set registry values
$RegistryValues.GetEnumerator().ForEach{
    $Path = [string] $_.'Name'
    if (-not (Test-Path -Path $Path -PathType 'Container')) {
        $null = New-Item -Path $Path -ItemType 'Directory' -Force
    }
    $_.'Value'.GetEnumerator().ForEach{
        $null = Set-ItemProperty -Path $Path -Name $_.'Name' -Value $_.'Value' -Type 'String' -Force
    }
}

 

 

Edited by olavrb
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...