olavrb Posted August 29, 2021 Share Posted August 29, 2021 (edited) 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 August 29, 2021 by olavrb Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted August 29, 2021 Share Posted August 29, 2021 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... Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Ego Eram Reputo Posted August 30, 2021 Share Posted August 30, 2021 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> 🤯 Quote ebook: Mastering Paint.NET | resources: Plugin Index | Stereogram Tut | proud supporter of Codelab plugins: EER's Plugin Pack | Planetoid | StickMan | WhichSymbol+ | Dr Scott's Markup Renderer | CSV Filetype | dwarf horde plugins: Plugin Browser | ShapeMaker Link to comment Share on other sites More sharing options...
Rick Brewster Posted September 3, 2021 Share Posted September 3, 2021 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): Set HKEY_LOCAL_MACHINE \ Software \ paint.net \ "Plugins/AllowAdditionalPluginDirectoryRoots" (without the quotes) to true (as a string / REG_SZ). 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. 1 Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
Rick Brewster Posted September 3, 2021 Share Posted September 3, 2021 I just published a new alpha of 4.3 which has this functionality. Try it out and let me know how it goes: Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
olavrb Posted September 23, 2021 Author Share Posted September 23, 2021 (edited) @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 HKCU HKLM Edited September 23, 2021 by olavrb Quote Link to comment Share on other sites More sharing options...
Rick Brewster Posted September 23, 2021 Share Posted September 23, 2021 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) Quote The Paint.NET Blog: https://blog.getpaint.net/ Donations are always appreciated! https://www.getpaint.net/donate.html Link to comment Share on other sites More sharing options...
olavrb Posted September 23, 2021 Author Share Posted September 23, 2021 (edited) 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. 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 September 23, 2021 by olavrb 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.