How can I wait for a media file to become available before running an Update command?

Former Member
Former Member

I am getting the following error message when I try to Update a media file right after it is created. How can I check or wait for the file to become available before calling the Update command? 

System.IO.IOException: The process cannot access the file '\\?\C:\Pl\filestorage\telligent.evolution.components.attachments\13\01\00\00\00\00\01\15\Pl-0454.jpg' because it is being used by another process.





Edited
[edited by: IbrahimK at 12:29 PM (GMT 0) on Tue, Mar 30 2021]
Parents Reply Children
  • Former Member
    0 Former Member in reply to Ben Tiedt

    It is the Media gallery - Drag and Drop - finalize script shown below. I make calls to a widget extension in the code.

    #if ($core_v2_page.IsPost)
    	$core_v2_page.SetContentType('application/json')
    
    	#set($fileName = $core_v2_page.GetFormValue('FileName'))
    	#set($galleryId = $core_v2_utility.ParseInt($core_v2_page.GetFormValue('GalleryId')))
    	#set($fileContextId = false)
    	#set($fileContextId = $core_v2_page.GetFormValue('FileContextId'))
    
    	#set($options = "%{}")
    	$options.Add('Name', $fileName)
    	#set($contentType = $core_v2_ui.GetMimeType($fileName))
    	$options.Add('FileUploadContext',$fileContextId)
    	$options.Add('FileName',$file.Name)
    	$options.Add('ContentType', $contentType)
    	$options.Add('_ExtendedAttributes', $contentType)
    
    	#set($media = false)
    	#set($media = $core_v2_media.Create($galleryId, $fileName, $contentType, $fileName, $options))
    	
    	$options.Add('IsApproved', false)
    	$options.Add('_ExtendedAttributes_WatermarkedVersion', $media.id)
    	
    	#set($mediaDownload = $core_v2_media.Create($galleryId, $fileName, $contentType, $fileName, $options))
    	
        #set($byteArray = $ibby_v1_ImageManipulation.AddWatermark($media.File.FileUrl))
        #set($title = $ibby_v1_ImageManipulation.ExtractTitle($media.File.FileUrl))
        #set($tags = $ibby_v1_ImageManipulation.ExtractKeywords($media.File.FileUrl))
        
        #if($title == '')
            $title = $fileName
        #end
    	
    	#set($media1 = $core_v2_media.Update($galleryId, $media.Id, "%{ ContentType = $contentType, FileName = $fileName, FileData = $byteArray, Name = $title, _ExtendedAttributes_DownloadVersion = $mediaDownload.Id, Tags = $tags }"))
    
    	#if($media.HasErrors())
    		$core_v2_page.SendJsonError($media.Errors)
    	#end
    	
    	#if ($media.IsApproved)
    		$core_v2_media.SetSubscribed($media.Id, true)
    	#end
    	
    	{"redirectUrl":"$core_v2_encoding.JavascriptEncode($media.Url)"}
    #end

  • The double core_v2_media.Create calls and core_v2_media.Update with a byte array seem to work fine in my tests. The ibby_v1_ImageManipulation API is custom. Is it possible that these APIs are not properly managing files (disposing of file streams, for example)?

  • Former Member
    0 Former Member in reply to Ben Tiedt
    Is it possible that these APIs are not properly managing files (disposing of file streams, for example)?

    It is possible. Please take a look and let me know if you spot anything suspicious:

          public string ExtractTitle(string url)
            {
    
                ICentralizedFile file = null;
    
                if (CentralizedFileStorage.IsCentralizedFileUrl(url))
                    file = CentralizedFileStorage.GetCentralizedFileByUrl(url);
    
    
                string path = ConfigurationManager.ConnectionStrings["FileStorage"] + file.FileStoreKey + "\\" + file.Path.Replace(".", "\\") + "\\" + file.FileName;
    
                var adapter = new JpegMetadataAdapter(path);
    
                return adapter.Metadata.Title;
            }
       
    
            public string ExtractKeywords(string url)
            {
    
                ICentralizedFile file = null;
    
                if (CentralizedFileStorage.IsCentralizedFileUrl(url))
                    file = CentralizedFileStorage.GetCentralizedFileByUrl(url);
    
    
                string path = ConfigurationManager.ConnectionStrings["FileStorage"] + file.FileStoreKey + "\\" + file.Path.Replace(".", "\\") + "\\" + file.FileName;
    
                var adapter = new JpegMetadataAdapter(path);
    
                return String.Join(", ", adapter.Metadata.Keywords);
            }
    		
    		public static byte[] DrawMultilineWatermark(string url)
        {
    
            ICentralizedFile file = null;
    
            if (CentralizedFileStorage.IsCentralizedFileUrl(url))
                file = CentralizedFileStorage.GetCentralizedFileByUrl(url);
    
    
            using (var bitmap = new Bitmap(file.OpenReadStream()))
            using (var gr = bitmap.GetAdvancedGraphics())
            using (var textPath = new Path())
            {
                var watermarkColor = new RgbColor(255, 255, 255, 145);
    
                var fontSize = UnitConverter.ConvertPixelsToUnits(bitmap.DpiY, bitmap.Height, Unit.Point) / 20.0f;
    
                var watermarkText = string.Format("<span style=\"font-size:{0}pt\">© {1} Stock Photo Site.</span>", (int)(fontSize / 2), DateTime.Now.Year);
    
                var text = new PlainText(watermarkText, gr.CreateFont("Arial", fontSize));
                text.Alignment = TextAlignment.Right;
                text.Leading = 1;
    
                textPath.DrawText(text);
    
                var rect = new RectangleF(0, 0, bitmap.Width, bitmap.Height);
    
                float offset = text.GetBlackBox().Width / 2;
    
                using (var tiledTextPath = TilePathText(textPath, rect, offset))
                {
                    gr.FillPath(new SolidBrush(watermarkColor), tiledTextPath);
                    /*
                    for (float i = offset; i < bitmap.Width; i += offset / 2)
                    {
                        gr.DrawEllipse(new Pen(watermarkColor, 3), -i, rect.Height - i, i * 2, i * 2);
                        gr.DrawEllipse(new Pen(watermarkColor, 3), rect.Width - i, rect.Height - i, i * 2, i * 2);
                    }*/
                }
    
                System.IO.MemoryStream stream = new System.IO.MemoryStream();
                bitmap.Save(stream, new Aurigma.GraphicsMill.Codecs.BmpSettings());
    
                return stream.ToArray();
            }
        }

  • Debugging custom code and 3rd party components is out of scope for support here, but, I will note a few things to consider:

    1. Disable the metadata calls and try the completion script with no calls and then try each call individually to see if it is an issue with a specific call.
    2. Looking at your custom code, I would recommend using stream instead of ever trying to recreate a local file path -- that path generation logic is not supported and could change.