Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of contents

Expand
titleClick here to expand the table of contents
Table of Contents
exclude^Оглавление$

Description

This action allows you to insert pieces of code written in the popular programming language C# into the project and thereby repeatedly expand the functionality of ZennoPoster and the scope of its use.

C# is an object-oriented language, but this action does not take full advantage of this approach (classes, inheritance) and the code is executed sequentially, except for the use of classes and public variables from the using directive and shared code

How to add an action to a project?

Via context menu Add Action -> Custom code -> C# code

Or use smart search .

Where can it be applied?

  • Almost any action of the cubes can be replaced with similar ones executed in C#, thus accelerating the development and efficiency of code execution.

  • Use of any development in C# in your project.

  • Integration of third-party libraries and their application in code.


How to work with an action?

The " Custom C# Code " cube is a regular text editor with basic code highlighting.

You can use any project variables ( Variables processing ), and the result can also be saved in variables, text files, tables and databases. To use the methods and properties of the project, the project entity is used, and to work with the browser, the instance entity is used.

If you want to use a project variable in your code, you must call it like this - project.Variables ["counter"]. Value, where counter is the name of the variable.


Context menu

Right-clicking on the cube window opens a context menu that has the following options:

Undo-Redo

Undoes the last change in the code. If the cancellation was done incorrectly, you can redo the canceled entry. It is important to note that these actions only work in the C # window code and do not cause changes in other cubes. For a similar function in the workspace for working with cubes, there are similar actions on the ProjectMaker toolbar.

Cut-Copy-Paste-Delete

Standard actions for working with code as text.

Comment-Undo comment

Code commenting is extremely useful functionality. Especially in large projects or when debugging code. Comments can contain information about changes, links, functionality of lines or parts of code. Comments can quickly enable/disable individual lines or pieces of code for error checking and testing. To comment out a part of the code, you need to select it and click this item.

Line numbering

Enables/disables line numbering, which is important for quick navigation through the code, for finding errors after receiving information about an error in the logs. But on small projects, numbering can be turned off to expand the workspace.

In the program settings, you can set behavior by default.

Wrap lines

Setting enabled

Setting disabled

In the program settings, you can set behavior by default.

Go to line

In large projects, it is important to quickly find the erroneous section of the code. Errors are displayed in the program logs. Clicking on this menu item opens a dialog box where you can enter the line number and column number. When you confirm the entry, the cursor moves exactly to the specified place in the cube code.

Search

Opens a search box for the code of this action. You can search based on parameters: case-sensitive or not, whole word, reverse search direction, and use regular expressions or wildcards when searching. By pressing the “ Find Next ” button, the cursor moves to the first found value, repeated pressing moves the cursor to the next found value, etc.

Replacement

Almost the same as “Search”, but immediately after finding the desired value, it is replaced with the entered value. It can work in a step-by-step mode, or immediately replace all found occurrences by clicking the "Replace All" button

Insert C# snippet

The entire contents of the selected file will be inserted into the place where the cursor is currently located.

Initially, this menu item is not displayed, so that it appears, you need to add at least one file to the C# Snippets Directory or save a code fragment using the Save in C# snippet function (described below).
Files in a directory can be moved to folders and thus it is convenient to group them.

Save snippet in C#

Allows you to save the selected code fragment to a TXT-file as a snippet for further use and quick insertion in other projects.

The directory where snippets will be saved can be changed in the program settings.

Set the value from the variable

When you hover the cursor over this context menu item, a list of all “Custom” and “Auto-generated” project variables opens. Selecting the required variable in the editor appears a construction of the form project.Variables ["myVar"]. Value , which is the value of the variable myVar .
This value always has a string type and conversion is necessary to use it as other types.

Do not return a value

Disabling this checkbox allows you to pass the result of code execution using the return statement .

Save the result to the variable

From this list, you can substitute any variable into which the value will be saved according to the result of the return execution, of course, if the checkbox from the previous paragraph is disabled.

Each C # line must end with a semicolon ; ... This helps the compiler determine where the line ends. Without this symbol, the project will simply throw an error at startup.


Settings

To set the default settings for the C# cube, use this part of the project settings (Project settings)


Converting actions to code

It is important to note that ZennoPoster has functionality that allows beginners to quickly get used to C# and start using this language at the very beginning of their work with the program. Almost any action/cube can be converted to C# code and then work with the resulting code similar in functionality to the cube. To do this, after creating a cube and setting its properties, click on “ Convert to C# ” in the context menu and then paste the copied code into the “ C# code ” cube.


Debugging C #

In complex and large pieces of C#, it is often difficult to quickly find an error. Therefore, it is necessary to debug C# code with step-by-step monitoring of changes in variables and data in lists, tables and databases. As with the main ZennoPoster project, each C# action can be debugged in Project Maker by setting one or more breakpoints.

To add a breakpoint, click in the field to the left of the code editor opposite the required line. After that, by clicking "Next", we start the execution of the cube and then using the navigation in the panel above the code editor in step-by-step mode or in the mode until the next breakpoint we check the work of the code, look at the changes in the variables in Project variables and it helps to efficiently correct errors.

Image RemovedImage Added

Examples of using

Learning to program in C# is beyond the scope of this document, however, it is possible to give you some tips and practical examples, which are often used in the practice of ZennoPoster users when working with C#.

Integer arithmetic

Code Block
languagec#
int value1 = Convert.ToInt32(project.Variables["value1"].Value);
int value2 = Convert.ToInt32(project.Variables["value2"].Value);
int value3 = value1 + value2; //или value1 - value2 or value1 * value2 etc.
return value3.ToString(); //the sum of two numbers

Rounding the result of division

Code Block
languagec#
float value1 = Convert.ToSingle(project.Variables["value1"].Value);
float value2 = Convert.ToSingle(project.Variables["value2"].Value);
return Math.Ceiling(value1/value2); // round up
//or
return Math.Ground(value1/value2); // round down

Create a list with random numbers from 1 to 10

Note that in this example, the C# action does not return anything, unlike the two examples above, where the final value is returned to the variable specified by the cube using the return operator . Here the result of the work is saved in the list.

In this example, the var keyword refers to the type in an implicit way. This is an alias of any type. The real type will be determined by the C# compiler

Code Block
languagec#
var list = project.Lists ["numbers"]; // we refer to the list of project lists to get the essence of one of them.
list.Clear (); // clear the list before filling
int value; // explaining an integer variable
List <string> tempList = new List <string> (); // create a new list of strings, but this list exists only within this action and will be destroyed after the action for (int i = 0; i <10; = "" i ++) = "" {// loop = "" from = "" 10 = "" iterations = "" value = "i; // assign" value = "" counter = "" cycle = "" so that = "" not = "" change = "" it = "" value ++ ; // increase = "" by = "" 1 = "" value = "" variable = "" templist.add (value.tostring ()); // add = "" to = "" temporary = "" list = "" string = "" value = "" numbers = ""} // repeat = "" so = "" 10 = "" times = "" templist.shuffle (); // shuffle = "" list = "" list .addrange (templist); // add = "" to = "" result = "" list = "" mixed = "" list = "" numbers = "" from = "" 1 = "" to = "" 10] ] = ""> </ ac: plain-text-body> </ ac: structured-macro> <h3> Getting a random string from a file with access to accounts and splitting it into a username and password </h3> < ac: structured-macro ac: name = "info" ac: schema-version = "1" ac: macro-id = "a6c84dbf-782d-4da5-854b-93031e07d735"> <ac: rich-text-body> <p > The <code> return statement </code> can be used to return <strong> null </strong>. The <strong> null </strong> keyword is a literal representing a null reference that does not refer to an object. When <strong> null is </strong> returned, the <strong> C # </strong> action will exit on the red line, which is often useful for creating relationships with other cubes. In the example below, with an empty list of accounts, you can display a warning (although the same can be done inside <strong> C # </strong> using the <code> project.SendInfoToLog (& quot; Empty list & quot ;, true ); </code> method) and fill the empty list from TXT with new accesses. </p> </ ac: rich-text-body> </ ac: structured-macro> <ac: structured-macro ac: name = "code" ac: schema-version = "1" ac: macro-id = "dc6aca72-07c3-4c9b-8279-b60452f17731"> <ac: plain-text-body> <! [CDATA [IZennoList list = project. Lists ["accounts"]; // get a list with an attached TXT file in which accesses are stored line by line in the login: password format
if (list.Count == 0) return null; // If the list is empty, then exit the cube along the red line
Random rnd = new Random (); // create a random number generator
string str = list [rnd.Next (0, list.Count)]; // calculate a random purely from 0 to the number of elements in the list (not inclusive) and assign the value of the found index to a string variable
string [] arr = str.Split (':'); // form an array of strings by splitting the variable using a delimiter:
project.Variables ["login"]. Value = arr [0]; // take the first element of the array, which is the login (indices of arrays, lists always start from 0) and assign this value to the login variable
project.Variables ["password"]. Value = arr [1]; // the second element of the array will be the password

Getting a random string from a file with access to accounts and splitting it into a username and password

The return operator can be used to return null. The null keyword is a literal representing a null reference that does not refer to an object. When null is returned, the C # action will exit on the red line, and this is often useful for creating relationships with other cubes. In the example below, with an empty list of accounts, you can display a warning (although the same can be done inside C# using the project.SendInfoToLog ("Empty list", true); method) and fill the empty list from TXT with new accesses.

Code Block
languagec#
IZennoList list = project.Lists ["accounts"]; // get a list with an attached TXT file in which accesses are stored line by line in the login: password format
if (list.Count == 0) return null; // If the list is empty, then exit the cube along the red line
Random rnd = new Random (); // create a random number generator
string str = list [rnd.Next (0, list.Count)]; // calculate a random purely from 0 to the number of elements in the list (not inclusive) and assign the value of the found index to a string variable
string [] arr = str.Split (':'); // form an array of strings by splitting the variable using a delimiter:
project.Variables ["login"]. Value = arr [0]; // take the first element of the array, which is the login (indices of arrays, lists always start from 0) and assign this value to the login variable
project.Variables ["password"]. Value = arr [1]; // the second element of the array will be the password

Working with HTML elements

Through C#, you can work with instace object methods in the same way as with standard cubes, but at a higher level. In the example below, we get a collection of HTML elements and add links from their children to the list.

To quickly get the values of the attributes of HTML elements, it is convenient to first use the " Action Designer " Action Designer and XPath Search add a cube for working with this element, and then using the " Convert to C# " functionality, get the code that needs minimal edits.

Code Block
languagec#
var list = project.Lists ["urls"]; // list into which we will add links
HtmlElementCollection hec = instance.ActiveTab.GetDocumentByAddress ("0"). FindElementsByAttribute ("li", "class", "pageNav-page", "regexp"); // get a collection of HTML elements with the "li" tag in the class name text "pageNav-page"
for (int i = 0; i <hec.Count; i ++) {
HtmlElement he = hec.GetByNumber (i); // iterate over all elements of the collection in a loop
if (he.IsVoid) break; // if the element is not available, then we break the loop using the break command
string attribute = he.FirstChild.GetAttribute ("href"); // get the value of the "href" attribute - the URL to the page
list.Add (attribute); // add URL to the list
}

Working with files: getting the resolution (width x height) of an image

The @ in front of a line means that the compiler will literally use the line after it, not as an escape sequence. If you remove this symbol, then for the path in the example below to be correct, you would have to put a double slash instead of a single slash for the code to work correctly.

Code Block
languagec#
Image img = Image.FromFile (project.Directory + @ "/ temp.jpg"); // get an image from a file
int width = img.Width; // get the width of the image
int height = img.Height; // and height
return width.ToString () + "x" + height.ToString (); // form a string with data

Working with CustomCode and Images: Overlaying a semi-transparent "watermark" in the center

In practice, it is often required to take out some C# functions in a separate place and access them from different actions. This is served by CustomCode.
In this class, you can insert a function that will be available from the cubes. This function can take parameters (arguments) and it will return the results of these calculations.

The example below creates a SetImageOpacity function that takes an image and a value to change its transparency to, and sends the changed image as output. This function requires using System.Drawing.Imaging;

Code Block
languagec#
Image original = Image.FromFile (project.Directory + @ "/ image.jpg"); // original image to be watermarked

int w = original.Width; // Dimensions of the original image
int h = original.Height;

int w_wm = (int) w / 10; // the width of the watermark, in this case this width is 10 of the original image

Image wm = OwnCode.CommonCode.SetImageOpacity (Image.FromFile (project.Directory + @ "/ wm.png"), .5F); // in one line we get the image from the file and process it (apply the translucency effect) using the function SetImageOpacity, which is in the common code class
float scale = (float) wm.Height / wm.Width; // proportions of the watermark
int h_wm = (int) (w_wm * scale); // calculate the new height of the watermark depending on the new width and aspect ratio
int x = (int) (w / 2 - w_wm / 2); // x position of the watermark (middle of the main image minus the middle of the new width of the watermark
int y = (int) (h / 2 - h_wm / 2); // y position of the watermark

Graphics gr = Graphics.FromImage (original); // create a graphic object from the original image
gr.DrawImage (wm, x, y, w_wm, h_wm); // draw a watermark over the original image with previously calculated coordinates and new dimensions

original.Save (project.Directory + @ "/ image_result.jpg", System.Drawing.Imaging.ImageFormat.Jpeg); // save the picture in JPEG format at the specified path
original.Dispose (); // we destroy objects that are no longer needed so that they do not take up memory
wm.Dispose ();
gr.Dispose ();

And the actual SetImageOpacity class, which needs to be inserted in the OwnCode.CommonCode class

Code Block
languagec#
using System.Drawing.Imaging;
public static Image SetImageOpacity (Image image, float opacity)
{
    try {
Bitmap bmp = new Bitmap (image.Width, image.Height);
        // create graphics from a picture
        using (Graphics gfx = Graphics.FromImage (bmp)) {
            // create a color matrix object
            ColorMatrix matrix = new ColorMatrix ();
            // set transparency
            matrix.Matrix33 = opacity;
            // create new attributes
            ImageAttributes attributes = new ImageAttributes ();
            // set the transparency color of the picture
            attributes.SetColorMatrix (matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            // draw the picture
            gfx.DrawImage (image, new Rectangle (0, 0, bmp.Width, bmp.Height), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
        }
        return bmp;
    }
    catch (Exception ex)
    {
        return null;
    }
}

Working with Regex

With the help of regular expressions, which C# fully supports, it is convenient to parse data, find the desired values, process and assign data to variables, and clean up garbage from texts.
In the example below, the task is to clear all HTML tags from the content of some element.

Code Block
languagec#
string html = project.Variables ["value1"]. Value; // assign the value to the variable containing the source code of the element
return Regex.Replace (html, @ "<. *?> & quot ;, String.Empty); // replace HTML tags with emptiness and return the result

Working with macros

The Macros object gives you access to a variety of file system or word processing functions. For example, it is possible in C# to organize Spintax processing similar to the corresponding cube.

Code Block
return Macros.TextProcessing.Spintax ("{0 | 1 | 2}"); // will randomly output one of the three values