You are viewing limited content. For full access, please sign in.

Question

Question

Deploying a custom workflow activity (Redux)

asked on March 8, 2017

Eventually, I need to post a bunch of stuff I've learned while working on my current project but I still have some nagging deployment questions.  My project has some custom built Icons.  I can specify the icons in my proxy file like this:

[ActivityImageAttribute("c:\\...\\project path\\myCustomIcon.ico", true)]

So far, no problem.  However, on deployment, this path might not (most likely will not) be the same.  I tried to tackle the problem like this:

[ActivityImageAttribute(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "myCustomIcon.ico"), true)]

The compiler doesn't like this because:

An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type

Am I stuck with a fixed path?  Maybe not... one of the Arguments for the ActivityImageAttribute is a string value for the resourceId.  I can add a resource to my project, call it "myCustomIcon", make it public, and rewrite my attribute like this:

[ActivityImageAttribute("myCustomIcon")]

Now, I get the following error:

'Laserfiche.Custom.Activities.Design.ActivityImageAttribute.ActivityImageAttribute(string)' is inaccessible due to its protection level

I'm hoping that I just didn't make something public that needs to be public or that I'm just using the wrong ID. I don't use resource files often so it is likely I'm messing this up.  

It is also odd that when I type "ActivityImageAttribute(", four overloads show up including the resourceId overload.  As soon as I type anything else, the overloads drop to three and the resourceId overload is gone.

Any ideas on how to implement this?  I'm open to other workarounds as well.

0 0

Answer

SELECTED ANSWER
replied on March 13, 2017

Peter,

Here is my 'workaround' to dynamically load the activity icon from the actual assembly executing path;

Since the ActivityImageAttribute is an attribute class I just created a new subclass that inherits it.  In the constructor for the new subclass I am calling the MyBase constructor with the path for the executing assembly and image filename (similar to what you were trying).  Here is the new class;

Imports System.Reflection
Imports System.IO
Imports Laserfiche.Custom.Activities.Design

<AttributeUsage(AttributeTargets.Class, Inherited:=False, AllowMultiple:=False)>
Public Class DynamicActivityImageAttribute
    Inherits ActivityImageAttribute

    Public Sub New(ByVal imageFilename As String, ByVal isIcon As Boolean)
        MyBase.New(Path.Combine(Path.GetDirectoryName((New Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath), imageFilename), isIcon)
    End Sub

End Class

 

Here is a screen snip of the original proxy code using the default Laserfiche class attribute;

 

Here is a screen snip of the proxy code using the new class attribute;

0 0
replied on March 16, 2017

Thanks Cliff,

For anyone using c#, here's how I did it:

First, add the subclass...

    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public class DynamicActivityImageAttribute : ActivityImageAttribute
    {

        public DynamicActivityImageAttribute(string imageFilename, bool isIcon)
            : base(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), imageFilename), true)
        {
        }

    }

The rest is a matter of replacing this

[ActivityImageAttribute("myCustomIcon.ico", true)]

With this

[DynamicActivityImage("myCustomIcon.ico", true)]

I'm not sure if there are any benefits of using your method to derive the path over mine but both seem to work.

1 0

Replies

You are not allowed to reply in this post.
You are not allowed to follow up in this post.

Sign in to reply to this post.