Add Icon to Zero Touch Node

Hello forum!

I am developing a custom package full of Zero Touch Nodes and currently, I am struggling with adding icons to my Dynamo nodes.

I am dealing with DynamoSandbox 2.19.3.6994 version.

Before doing anything, I had a look at three different resources and I noticed they are mostly different.

  1. https://www.youtube.com/watch?v=eKosaLv3V84&t=632s&ab_channel=AussieBIMGuru by @GavinCrump where I could see he refers to a custom node instead of a Zero Touch Node.
  2. Creating Icons for Custom Nodes · DynamoDS/Dynamo Wiki · GitHub I reckon this guide is what @GavinCrump explains in his YouTube video with slight differences.
  3. Add Icons for a Zero Touch Assembly or NodeModel assembly · DynamoDS/Dynamo Wiki · GitHub This is supposed to be the guide to add icons within our Zero Touch Nodes.

So… what have I tried so far?

Firstly, I tried with Add Icons for a Zero Touch Assembly or NodeModel assembly · DynamoDS/Dynamo Wiki · GitHub following these steps:

  1. Add > New Item > JuanMCillerLibraryImages.resx resource file. Important to highlight that the name of my project is JuanMCillerLibrary.
  2. I select in my Solution Explorer the .resx file and clear Custom Tool.
  3. Within the .resx file, Add Resource > Add Existing File.
    3.1 JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Large.png where:
    3.1.1. JuanMCillerLibrary is the name of my project.
    3.1.2. DynamoGeometries the name of my namespace.
    3.1.3. MyLine the name of the class.
    3.1.4. CreateLine the name of my method.
    3.2 JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Small.png where:
    3.2.1 same as above.
  4. Within the .resx file, I select both images and change the Persitante into Embedded in .resx.
  5. I open the .csproj file and I insert these lines of code:
  <Target Name="AfterBuild">
    <!-- Get System.Drawing.dll -->
    <GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v4.8">
      <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
    </GetReferenceAssemblyPaths>
    <!-- Get assembly -->
    <GetAssemblyIdentity AssemblyFiles="$(OutDir)$(TargetName).dll">
      <Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
    </GetAssemblyIdentity>
    <!-- Generate customization dll -->
    <GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resx" OutputResources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resources" OutputAssembly="$(OutDir)JuanMCillerLibraryImages.customization.dll" Version="%(AssemblyInfo.Version)" />
    <ItemGroup>
      <Dlls Include="$(OutDir)*.dll" />
      <Pdbs Include="$(OutDir)*.pdb" />
      <Xmls Include="$(OutDir)*.xml" />
      <Configs Include="$(OutDir)*.config" />
      <PkgJson Include="$(ProjectDir)/*pkg.json" />
      <DocFiles Include="$(SolutionDir)doc\**\*" />
      <SourcePackage Include="$(SolutionDir)dist\$(PackageName)\**\*" />
    </ItemGroup>
    <!-- This copies every file to a dist folder on the solutions directory -->
    <Copy SourceFiles="@(Dlls)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Pdbs)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Xmls)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Configs)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(PkgJson)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)" />
    <Copy SourceFiles="@(DocFiles)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\doc" />
    <MakeDir Directories="$(SolutionDir)dist\$(ProjectName)\dyf" />
    <MakeDir Directories="$(SolutionDir)dist\$(ProjectName)\extra" />
    <!-- This copies the distributed package on dist folder to the Dynamo Packages folder. -->
    <Copy SourceFiles="@(SourcePackage)" DestinationFolder="$(AppData)\Dynamo\Dynamo Core\2.19\packages\$(PackageName)\%(RecursiveDir)" />
  </Target>

It is also important to highlight that I only added this piece of code in the .csproj file:

    <!-- Get System.Drawing.dll -->
    <GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v4.8">
      <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
    </GetReferenceAssemblyPaths>
    <!-- Get assembly -->
    <GetAssemblyIdentity AssemblyFiles="$(OutDir)$(TargetName).dll">
      <Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
    </GetAssemblyIdentity>
    <!-- Generate customization dll -->
    <GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resx" OutputResources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)\Resources\JuanMCillerLibraryImages.resources" OutputAssembly="$(OutDir)JuanMCillerLibraryImages.customization.dll" Version="%(AssemblyInfo.Version)" />

The rest of the lines were previously added to deploy the distribution package accordingly.

The NET Framework that I am using in my project is 4.8.

If I save everything, reload the project and I either Build or Rebuild the solution, I am getting this error:

Severity	Code	Description	Project	File	Line	Suppression State
Error		This is an unhandled exception in MSBuild -- PLEASE UPVOTE AN EXISTING ISSUE OR FILE A NEW ONE AT https://aka.ms/msbuild/unhandled
    Microsoft.Build.Framework.InternalErrorException: MSB0001: Internal MSBuild Error: There should be resource files to process
   at Microsoft.Build.Shared.ErrorUtilities.ThrowInternalError(String message, Exception innerException, Object[] args)
   at Microsoft.Build.Tasks.GenerateResource.TransformResourceFilesUsingResGen(List`1 inputsToProcess, List`1 outputsToProcess)
   at Microsoft.Build.Tasks.GenerateResource.GenerateResourcesUsingResGen(List`1 inputsToProcess, List`1 outputsToProcess)
   at Microsoft.Build.Tasks.GenerateResource.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__26.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.TaskBuilder.<InitializeAndExecuteTask>d__24.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteBucket>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteTask>d__18.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteTask>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Build.BackEnd.TargetEntry.<ProcessBucket>d__51.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Build.BackEnd.TargetEntry.<ExecuteTarget>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Build.BackEnd.TargetBuilder.<ProcessTargetStack>d__23.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.TargetBuilder.<BuildTargets>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.RequestBuilder.<BuildProject>d__68.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Build.BackEnd.RequestBuilder.<BuildAndReport>d__59.MoveNext()	JuanMCillerLibrary			

The funny thing is that if I insert this BeforeBuild coming from this page Creating Icons for Custom Nodes · DynamoDS/Dynamo Wiki · GitHub instead of the AfterBuild I attached before, the Package.customization.dll file is created in the bin folder.

  <Target Name="BeforeBuild">
    <GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v2.0">
      <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
    </GetReferenceAssemblyPaths>
	<GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)PackageImages.resx" OutputResources="$(ProjectDir)PackageImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <GenerateResource UseSourcePath="true" Sources="$(ProjectDir)PackageImages.resx" OutputResources="$(ProjectDir)PackageImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <AL TargetType="library" EmbedResources="$(ProjectDir)PackageImages.resources" OutputAssembly="$(OutDir)Package.customization.dll" />
  </Target>
  <Target Name="AfterBuild">
  </Target>

Thanks in advance for the help.

Cheers.

Might this be a potential solution?

@chuongmep , could you please tell me how you addressed it?

Cheers.

Well, today I tried the solution shown above from GitHub with no success.

I expose my steps:

  1. I create my PackageImages.resx file.
  2. I clear Custom Tool within PackageImages.resx.
  3. I add two images for my specific node. These images are:
    3.1. JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Large.png
    3.2. JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Small.png
  4. Within the .resx file, I select both images and change the Persitante into Embedded in .resx.
  5. I open the .csproj file and I insert these lines of code alongside the rest of the .csproj configuration I used to have:
  <Target Name="GenerateCustomization" BeforeTargets="Build">
    <GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v2.0">
      <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
    </GetReferenceAssemblyPaths>
    <GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)PackageImages.resx" OutputResources="$(ProjectDir)PackageImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)PackageImages.resources" OutputAssembly="$(OutDir)Package.customization.dll" />
  </Target>
  1. If I either Build Solution or Rebuild Solution now the Package.customization.dll file is created but when I copy and paste it in my

C:\Users\Juan\AppData\Roaming\Dynamo\Dynamo Core\2.19\packages\JuanMCillerLibrary\bin
nothing shows up in Dynamo Sandbox for my JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine node.

This is my repo in GitHub just in case anyone wanna have a look at it:
ZeroTouchNodeJMCiller/JuanMCillerLibrary at addIcon · juanmciller/ZeroTouchNodeJMCiller · GitHub

Hi @JMCiller , as a link your mentioned, the first you need to do is choose framework version first before you work into new upgrade, may be this link will more make sence to you : Add Icons for a Zero Touch Assembly or Node Model assembly, Not work with NET6 SDK Style · Issue #13199 · DynamoDS/Dynamo · GitHub

When I’m try look to your github repo, it still follow with old style SDK.

1 Like

Hi @chuongmep , thank you so much for your reply. Appreciate it.

Truth be told, I do not know what you exactly mean. I am already targeting .NET Framework 4.8:



Do you mean I should match this template within the .csproj file?

If so, is there any way of avoiding these changes manually?

Following this link: c# - How to create an SDK-style .NET Framework project in VS? - Stack Overflow is there a way of working in a NET Framework project with a SDK style?

Cheers.

Any thoughts on this? @Thomas_Mahon , @jacob.small , @john_pierson

I also tried to change the .csproj file with the SDK template but the project became unstable and I lost, for instance, the References and became Dependencies. It seems it switched from the .NET Framework DLL template to .NET Standard.

Thanks.

I can’t say I have had to switch before… might be worth starting new and then bringing stuff over into the new project rather than trying to reconfigure…

  1. Target Framework doesn’t exist. Its net48.
  2. Your after build looks incorrect: match this and change it to match your solution names:
	<Target Name="CreateNodeIcons" AfterTargets="PostBuildEvent">
		<!-- Get System.Drawing.dll     -->
		<GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v4.8">
			<Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
		</GetReferenceAssemblyPaths>
		<!-- Get assembly -->
		<GetAssemblyIdentity AssemblyFiles="$(OutDir)$(TargetName).dll">
			<Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
		</GetAssemblyIdentity>
		<!-- Generate customization dll -->
		<GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)BimorphNodesImages.resx" OutputResources="$(ProjectDir)BimorphNodesImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
		<AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)BimorphNodesImages.resources" OutputAssembly="$(OutDir)BimorphNodes.customization.dll" Version="%(AssemblyInfo.Version)" />
	</Target>
  1. Make sure your PackageImages.resources is [package name].resx in your project.
  2. resx must be set to Embedded resource
  3. Make sure your images in your resx are set to Linked at compile time for their Persistence property.
1 Like

Hi @Thomas_Mahon , thank you so much for your reply.

I carried out the steps you wrote but I still cannot see my images. Let me write the steps I took.

  1. I created JuanMCilerLibraryImages.resx file.
  2. I clear Custom Tool within .resx file.
  3. I add two images to the Resource folder. These images are called JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Large and JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Small.
  4. With both images selected, I set their Persistance to Linked at compile time.
  5. I modify my .csproj file pasting the snippet you shared with me:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{24228BF0-444E-45C3-884E-38DB7312E787}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>JuanMCillerLibrary</RootNamespace>
    <AssemblyName>JuanMCillerLibrary</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>bin\Debug\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
    <DocumentationFile>bin\Debug\JuanMCillerLibrary.xml</DocumentationFile>
    <PlatformTarget>x64</PlatformTarget>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Analysis, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\Analysis.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="CoreNodeModels, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\CoreNodeModels.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DesignScriptBuiltin, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DesignScriptBuiltin.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DSCoreNodes, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\DSCoreNodes.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DSCPython, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DSCPython.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoApplications, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoApplications.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoCore, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoCore.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoInstallDetective, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoInstallDetective.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoPackages, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoPackages.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoServices, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoServices.2.19.3.6394\lib\netstandard2.0\DynamoServices.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoShapeManager, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoShapeManager.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoUnits, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.ZeroTouchLibrary.2.19.3.6394\lib\net48\DynamoUnits.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="DynamoUtilities, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\DynamoUtilities.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="GeometryColor, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\GeometryColor.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Microsoft.Expression.Interactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Prism.4.1.0.0\lib\NET40\Microsoft.Expression.Interactions.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Microsoft.Practices.Prism, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Prism.4.1.0.0\lib\NET40\Microsoft.Practices.Prism.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Microsoft.Practices.Prism.Interactivity, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Prism.4.1.0.0\lib\NET40\Microsoft.Practices.Prism.Interactivity.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
      <HintPath>packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="nunit.framework, Version=2.6.3.13283, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
      <HintPath>packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="ProtoCore, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\ProtoCore.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="ProtoGeometry, Version=2.18.0.2485, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.ZeroTouchLibrary.2.19.3.6394\lib\net48\ProtoGeometry.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Collections.Immutable, Version=1.2.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>packages\System.Collections.Immutable.1.7.1\lib\net461\System.Collections.Immutable.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Core" />
    <Reference Include="System.Drawing" />
    <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
      <HintPath>packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Numerics" />
    <Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
      <HintPath>packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
      <HintPath>packages\Prism.4.1.0.0\lib\NET40\System.Windows.Interactivity.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
    <Reference Include="UnitsNodeModels, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\UnitsNodeModels.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="VMDataBridge, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.Core.2.19.3.6394\lib\net48\VMDataBridge.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="Watch3DNodeModels, Version=2.19.3.6394, Culture=neutral, processorArchitecture=AMD64">
      <HintPath>packages\DynamoVisualProgramming.DynamoCoreNodes.2.19.3.6394\lib\net48\Watch3DNodeModels.dll</HintPath>
      <Private>False</Private>
    </Reference>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="CsharpBasics\BreakContinue.cs" />
    <Compile Include="CsharpBasics\Car.cs" />
    <Compile Include="CsharpBasics\Dictionaries.cs" />
    <Compile Include="CsharpBasics\ForLoop.cs" />
    <Compile Include="CsharpBasics\IFStatement.cs" />
    <Compile Include="CsharpBasics\MyFirstNode.cs" />
    <Compile Include="CsharpBasics\Numbers.cs" />
    <Compile Include="CsharpBasics\Strings.cs" />
    <Compile Include="CsharpBasics\Switch.cs" />
    <Compile Include="CsharpBasics\TryCatch.cs" />
    <Compile Include="CsharpBasics\WhileLoop.cs" />
    <Compile Include="DynamoGeometries\CreatePoint.cs" />
    <Compile Include="DynamoGeometries\MyLine.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <ItemGroup>
    <Content Include="images\logo.png" />
    <None Include="Resources\JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Small.png" />
    <None Include="Resources\JuanMCillerLibrary.DynamoGeometries.MyLine.CreateLine.Large.png" />
  </ItemGroup>
  <ItemGroup>
    <None Include="app.config" />
    <None Include="doc\DynamoGeometries.MyLine.CreateLine.md" />
    <None Include="packages.config" />
    <None Include="pkg.json" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="JuanMCillerLibraryImages.resx" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
  <PropertyGroup>
    <PostBuildEvent>
    </PostBuildEvent>
  </PropertyGroup>
  <Target Name="CreateNodeIcons" AfterTargets="PostBuildEvent">
    <!-- Get System.Drawing.dll     -->
    <GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v4.8">
      <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
    </GetReferenceAssemblyPaths>
    <!-- Get assembly -->
    <GetAssemblyIdentity AssemblyFiles="$(OutDir)$(TargetName).dll">
      <Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
    </GetAssemblyIdentity>
    <!-- Generate customization dll -->
    <GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)JuanMCillerLibraryImages.resx" OutputResources="$(ProjectDir)JuanMCillerLibraryImages.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
    <AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)JuanMCillerLibraryImages.resources" OutputAssembly="$(OutDir)JuanMCillerLibrary.customization.dll" Version="%(AssemblyInfo.Version)" />
  </Target>
  <Target Name="AfterBuild">
    <ItemGroup>
      <Dlls Include="$(OutDir)*.dll" />
      <Pdbs Include="$(OutDir)*.pdb" />
      <Xmls Include="$(OutDir)*.xml" />
      <Configs Include="$(OutDir)*.config" />
      <PkgJson Include="$(ProjectDir)/*pkg.json" />
      <DocFiles Include="$(SolutionDir)doc\**\*" />
      <SourcePackage Include="$(SolutionDir)dist\$(PackageName)\**\*" />
    </ItemGroup>
    <!-- This copies every file to a dist folder on the solutions directory -->
    <Copy SourceFiles="@(Dlls)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Pdbs)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Xmls)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(Configs)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\bin\" />
    <Copy SourceFiles="@(PkgJson)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)" />
    <Copy SourceFiles="@(DocFiles)" DestinationFolder="$(SolutionDir)dist\$(ProjectName)\doc" />
    <MakeDir Directories="$(SolutionDir)dist\$(ProjectName)\dyf" />
    <MakeDir Directories="$(SolutionDir)dist\$(ProjectName)\extra" />
    <!-- This copies the distributed package on dist folder to the Dynamo Packages folder. -->
    <Copy SourceFiles="@(SourcePackage)" DestinationFolder="$(AppData)\Dynamo\Dynamo Core\2.19\packages\$(PackageName)\%(RecursiveDir)" />
  </Target>
</Project>

I synced my changes in my GitHub repo under the addIcon branch.
ZeroTouchNodeJMCiller/JuanMCillerLibrary/JuanMCillerLibrary.csproj at addIcon · juanmciller/ZeroTouchNodeJMCiller · GitHub

Cheers.

Hi @JMCiller , you can reference this link to upgrade your project to latest sdk style, good for maintain : Overview of the .NET Upgrade Assistant - .NET Core | Microsoft Learn

1 Like

Hi @chuongmep , thank you again for your help.

I already did that. It is funny because on my main laptop, the .csproj file could not be converted into SDK style but I tried it again on a secondary laptop and it worked fine :joy:.

I realized that after upgrading into SDK style, my References converted into Dependencies.
image

If I keep diving into the “References” (now called Dependencies), I notice that I lost the feature that you set when you are setting up your References after installing them selecting Copy Local > False.
image

My point here is. If someone wants to develop a professional package full of Zero Touch Nodes, among other features, custom icons shall be inserted for each node created. I see that when we want to add custom icons to our Zero Touch Nodes:

  • All the documentation on the internet is out of date due to the fact that they started setting up the project with an old .csproj template?
  • Should all that documentation be updated to show how to work with SDK style rather than old .csproj template?
  • These documentations also show that when you install your References and you set Copy Local > False. This is pointless as you will end up shifting from old .csproj into SDK new style and you’ll lose these functionalities.

I reckon I am going to leave for now the icon addition in my project. I do not see any consistent workflow to be followed. I see many different solutions that the users carried out regardless of the documentation published on the DynamoDS GitHub and might be a little bit confusing.

Cheers.

I’m refer you can try quick look to the project opensource I updated recenly here : GitHub - chuongmep/OpenMEP: A package for MEP, Computational Design, Generative Design inside Dynamo Revit , Sandbox , AutoCAD, Civil3D & more. At the moment all the target Autodesk is upgrade from .NET Framework to .NET 8 as I know. Revit 2025 and Autocad 2025 also follow with .NET8 and new SDK Style.

I made it work!

image

I will post the different steps I took throughout the workflow so the community has available thew approach to be followed… I ended up mixing steps from different messages :rofl: :rofl:

Thank you so much @chuongmep for your help again!

2 Likes

Cheers !

Might make a great PR to the developer chapters of the Dynamo Primer! FYI @solamour

2 Likes

@jacob.small , @solamour , this might be insightful for future documentation and for the community.

I am all ears regarding any sort of suggestion to improve it.

Cheers,

4 Likes

Hello again, @jacob.small , @solamour , @chuongmep , @Thomas_Mahon

After giving it a try a month ago we could see that for NET Framework 4.8 it was working fine. We only had to add this piece of code to the .csproj file where targeting NET Framework 4.8.

<Target Name="CreateNodeIcons" AfterTargets="PostBuildEvent">
		<!-- Get System.Drawing.dll     -->
		<GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v4.8">
			<Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="FrameworkAssembliesPath" />
		</GetReferenceAssemblyPaths>
		<!-- Get assembly -->
		<GetAssemblyIdentity AssemblyFiles="$(OutDir)$(TargetName).dll">
			<Output TaskParameter="Assemblies" ItemName="AssemblyInfo" />
		</GetAssemblyIdentity>
		<!-- Generate customization dll -->
		<GenerateResource SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" UseSourcePath="true" Sources="$(ProjectDir)ClassLibrary1Images.resx" OutputResources="$(ProjectDir)ClassLibrary1Images.resources" References="$(FrameworkAssembliesPath)System.Drawing.dll" />
		<AL SdkToolsPath="$(TargetFrameworkSDKToolsDirectory)" TargetType="library" EmbedResources="$(ProjectDir)ClassLibrary1Images.resources" OutputAssembly="$(OutDir)ClassLibrary1.customization.dll" Version="%(AssemblyInfo.Version)" />
	</Target>

Currently, I am trying to add custom icons targeting NET8.0 and when I pasted in the .csproj file the code attached above, I only modified this line of code from 4.8 to 8.0:

<GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v8.0">

When building the solution, this error displays in the console which does not make sense to me since my solution is compiling for NET8.0 before adding the custom icon approach and nodes were visible in DynamoSandbox 3.1.0…

Were you able to find another solution for NET8.0 to add custom icons to Dynamo nodes?

Cheers.

Did you install SDK 8.0 ?

Hello @chuongmep ,

Yes, I did. In fact, I can see it when creating a new project in VS:


I’m confuse why you still keep

<GetReferenceAssemblyPaths TargetFrameworkMoniker=".NETFramework, Version=v8.0">

.NETFramework in case want set target for .NET 8, it not is .NET Framework