I have a variable that will be either IMAGE.PNG or IMAGE.JPG, I need to verify that it exists and then send the correct file path to Bartender. Epicor won’t let me use System.IO to check. Anyone know how to do this?
Epicor will let you use use System.IO just fine it just kinda growls at you for a minute. They are just warnings
Weird, I was getting an error using it 5 minutes ago, used it in the same context after some modifications and it’s working fine now. I knew I had used it before, it’s too early
if (part != null && part["ImageID"].ToString().Length > 0) {
var image_folder = @"\\SERVER\EpicorData\attachments\";
var image_jpg = image_folder + part["ImageID"] + ".JPG";
var image_png = image_folder + part["ImageID"] + ".PNG";
image = File.Exists(image_jpg) ? image_jpg : image_png;
}
Thanks man
Yep, I use System.IO.File.Exists( string FilePath )
all the time.
This is the message I was getting. It can be ignored?
Update.Post.PrintActivity.cs(126,15): warning ECF1002: The 'System.IO.File.Exists(string?)' method cannot be called.
Yes I get that on any function or BPM in Kinetic when I save. Unless you’re on cloud, it can be ignored.
These are warnings but some of them will become errors, no?
These warnings will become errors in the future - Santiago Palacios/Epicor
If I understand Santiago, Epicor will provide safer ways to get the same functionality. Keep track of the places you do this in your source control system. (Sorry, it’s Friday - I don’t know what I was saying.) I think it’s the same code on-prem or in the cloud, so be prepared - just in case.
Did someone say my name?
The safer way has already been provided. We introduced a new Sandbox class for custom code that (among other things), allows you to access the file system in a way that is safe and portable as we continue to evolve how Kinetic is hosted.
I created a gist with code samples that show how to use this. You will see that the syntax is almost identical. You replace System.IO with Sandbox.IO. The biggest difference is that instead of working with arbitrary absolute paths, you need to create a FilePath object that abstracts the destination of the file.
A lot of the credit for the information in that gist goes to @JeffLeBert.
Without further ado, here’s the gist:
Thank you @Epic_Santiago
How are we supposed to write files to Azure for use with BarTender if we are limited to only User and Company Data folders now?
Also, I haven’t seen any communication on when these warnings will officially become errors and things wont compile anymore. Do you have any insight to that as well?
I’s be sticking that folder reference into user codes
Blob storage perhaps?
Note: Untested copilot examples.
Something like:
with System.IO
using System;
using System.IO;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
class Program
{
private const string blobServiceEndpoint = "<your_blob_service_endpoint>";
private const string storageAccountName = "<your_storage_account_name>";
private const string storageAccountKey = "<your_storage_account_key>";
private const string containerName = "<your_container_name>";
private const string blobName = "<your_blob_name>";
private const string localFilePath = "<your_local_file_path>";
static async Task Main(string[] args)
{
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(blobServiceEndpoint), new StorageSharedKeyCredential(storageAccountName, storageAccountKey));
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = containerClient.GetBlobClient(blobName);
using FileStream uploadFileStream = File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
Console.WriteLine("File uploaded to Azure Blob Storage successfully.");
}
}
Without System.IO
using System;
using System.Text;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
class Program
{
private const string blobServiceEndpoint = "<your_blob_service_endpoint>";
private const string storageAccountName = "<your_storage_account_name>";
private const string storageAccountKey = "<your_storage_account_key>";
private const string containerName = "<your_container_name>";
private const string blobName = "<your_blob_name>";
private const string fileContent = "<your_file_content>";
static async Task Main(string[] args)
{
BlobServiceClient blobServiceClient = new BlobServiceClient(new Uri(blobServiceEndpoint), new StorageSharedKeyCredential(storageAccountName, storageAccountKey));
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
BlobClient blobClient = containerClient.GetBlobClient(blobName);
byte[] byteArray = Encoding.UTF8.GetBytes(fileContent);
using MemoryStream memoryStream = new MemoryStream(byteArray);
await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders { ContentType = "text/plain" });
Console.WriteLine("File uploaded to Azure Blob Storage successfully.");
}
}
EDIT
and of course as @Mark_Wonsil clearly pointed out you would NOT do this and your store your secrets in real code. This is just an example of usage of the method.
We have an open ticket to add Azure file share to the list.
As for when the warnings will become errors, there is no date as of yet. Whenever we turn any warnings into errors, this will be communicated before hand.
Coincidentally, a new application security book is out from Tanya Janca, and one of the things she mentions: Stack Overflow examples and LLM responses usually have poor security practices. For example, the code above would have one put the shared secret in the source code.
We now return you to your sandbox.