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

Question

Question

The "Essay/Rattrapage" object does not work with the "Script" object.

asked on September 26, 2023

Hello.
In one of my workflows, via the "Script" object (C#), I need to copy/paste a PDF file from a Windows folder "A" to another Windows folder "B".

 

The problem I'm encountering is that the same PDF file is already being used by another process, which generates an error.

 

The process cannot access the 'C:\...' file because it is in use by another process.

 

I've tried to work around this with the "Try/Catch" tool, but it doesn't seem to work.

 

Here is the C# code

namespace WorkflowActivity.Scripting.CopieNATIFfromPIXItoLF
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using System.IO;

    /// <summary>
    /// Offre une ou plusieurs méthodes qui peuvent être exécutées au moment de l'exécution de l'activité de scriptage du flux de travail.
    /// </summary>
    public class Script1 : ScriptClass90
    {
        /// <summary>
        /// Cette méthode est exécutée quand l'activité est effectuée.
        /// </summary>
        protected override void Execute()
        {
            // Ecrivez ici votre code.
            // Get the token values for source filename, source path, and target path...
            String sourcePath = this.GetTokenValue("SourcePathN").ToString();
            String sourceFileName = this.GetTokenValue("SourceFileNameN").ToString();
            String targetPath = this.GetTokenValue("TargetPathN").ToString();
            String sourcePathAndName = Path.Combine(sourcePath, sourceFileName);
            String targetPathAndName = Path.Combine(targetPath, sourceFileName);
            Boolean fileExists = false;

            try
            {
                // Check to see if the source file exists...
                if (File.Exists(sourcePathAndName))
                {
                    fileExists = true;

                    // Check to see if the target path exists.  If not then create it...
                    if (Directory.Exists(targetPath) == false)
                    {
                        Directory.CreateDirectory(targetPath);
                    }

                    // Copy the souorce file to the target directory...
                    File.Copy(sourcePathAndName, targetPathAndName, true);
                }

            }
            catch (System.Exception e)
            {
                this.WorkflowApi.TrackError(e.Message);
            }

            // Set the result token for later processing...
            this.SetTokenValue("FileExists", fileExists);
        }
    }
}

How can I resolve this please ?

Thanks in advance.

Regards

0 0

Replies

replied on September 27, 2023

There is nothing for the Catch branch to do because your script is catching the exception and converting it into a log entry. So the script activity is successful. You'd have to rethrow the exception after logging it. Or remove the catch altogether and let the exception propagate out.

 

0 0
replied on September 28, 2023

Hello Miruna.

Sorry, I didn't quite understand.

My problem is that I want to copy/paste a file from a Windows A folder to a Windows B folder but I get an error because the file is being used by another process. I thought the "Try/Catch" solution would help, but it doesn't seem to be the right solution.

Do you have a solution to suggest?

0 0
replied on September 29, 2023 Show version history

Try/Catch would help, but your script is deliberately handling the error so there is nothing for the Catch branch to do anymore since no errors get out of the script.

0 0
replied on September 29, 2023 Show version history

Got it. In that case, I'd have to be able to put some kind of C# try/catch in my script, right?

// Check to see if the source file exists AND if the source file is not already used by another process
if (File.Exists(sourcePathAndName) and ???)
                {...

 

0 0
replied on October 2, 2023

Or not catch the errors.

0 0
replied on October 2, 2023

If I don't detect errors, my files won't be processed.

0 0
replied on October 2, 2023

I've modified my code to include a file check. If the file is used by another process, we wait a moment before trying again.

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.IO;
using System.Threading; // Ajoutez cette directive pour utiliser la classe Thread

namespace WorkflowActivity.Scripting.CopieNATIFfromPIXItoLF
{
    /// <summary>
    /// Offre une ou plusieurs méthodes qui peuvent être exécutées au moment de l'exécution de l'activité de scriptage du flux de travail.
    /// </summary>
    public class Script1 : ScriptClass90
    {
        /// <summary>
        /// Cette méthode est exécutée quand l'activité est effectuée.
        /// </summary>
        protected override void Execute()
        {
            // Ecrivez ici votre code.
            // Get the token values for source filename, source path, and target path...
            String sourcePath = this.GetTokenValue("SourcePathN").ToString();
            String sourceFileName = this.GetTokenValue("SourceFileNameN").ToString();
            String targetPath = this.GetTokenValue("TargetPathN").ToString();
            String sourcePathAndName = Path.Combine(sourcePath, sourceFileName);
            String targetPathAndName = Path.Combine(targetPath, sourceFileName);
            Boolean fileExists = false;

            int maxAttempts = 10; // Nombre maximal de tentatives
            int delayBetweenAttempts = 60000; // Délai entre chaque tentative en millisecondes

            for (int attempt = 0; attempt < maxAttempts; attempt++)
            {
                try
                {
                    // Check to see if the source file exists...
                    if (File.Exists(sourcePathAndName))
                    {
                        using (FileStream fileStream = File.Open(sourcePathAndName, FileMode.Open, FileAccess.Read, FileShare.None))
                        {
                            fileExists = true;

                            // Check to see if the target path exists.  If not then create it...
                            if (Directory.Exists(targetPath) == false)
                            {
                                Directory.CreateDirectory(targetPath);
                            }

                            // Copy the source file to the target directory...
                            File.Copy(sourcePathAndName, targetPathAndName, true);
                        }
                        break;
                    }
                }
                catch (IOException)
                {
                    // Le fichier est verrouillé par un autre processus, attendre avant de réessayer.
                    Thread.Sleep(delayBetweenAttempts);
                }
                catch (System.Exception e)
                {
                    this.WorkflowApi.TrackError(e.Message);
                    break;
                }
            }

            // Set the result token for later processing...
            this.SetTokenValue("FileExists", fileExists);
        }
    }
}

 

0 0
replied on October 3, 2023

That is going to be very inefficient if multiple instances of this workflow need to run at the same time as the instance will stay actively running for the entire minute Thread.Sleep is running and prevent other instances from running.

Try-Catch is better to delay the instance because it would allow Workflow to run other instances while this one is in a wait state.

Your catch for IOException might be too generic. I think if the disk is full or not available, you'd also get an IOException.

2 0
replied on October 12, 2023

That's why I only make a few attempts and then stop.

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

Sign in to reply to this post.