Maybe someone knows a simple solution to my problem.
I do not know the entry of the file so it's not a static value.
It can be changed through the BizTalk gui and there we have a URI through the receiveport. But I do not believe it's accessible that easy. What I want to do is write out the full path as the filename. It works well with the messageID where the file is given a specific filepath name. But the Path-Name where the file was dropped is not working that well.
I keep getting this error :
Message:
Object reference not set to an instance of an object.
the message resource is present but the message is not found in the string/message table
-Does not say me much
Below you can see a snip from my code
internal static string UpdateMacroPathProperty(IBaseMessage baseMessage, string macroPathProperty, string macroDefsFile)
{
if (macroName == "MessageID")
{
contextPropertyValue = baseMessage.MessageID.ToString();
}
else if (macroName == "SourceFileName")
{
contextPropertyValue = Directory.GetCurrentDirectory();
}
}
This is an specific created pipeline. Has anyone encountered this problem or can point me in the right way.
I know that BizTalk has a built in function for this, BizTalk Server: List of Macros as the %SourceFileName% but I'm trying to save this as logs in a specific map structure so that it does not get processed.
It's adapter dependent; some adapters will use the FILE adapter's namespace even though they're not the file adapter, but this is the kind of logic that I've used in the past for this:
string adapterType = (string)pInMsg.Context.Read("InboundTransportType",
"http://schemas.microsoft.com/BizTalk/2003/system-properties");
string filePath = null;
if (adapterType != null)
{
if (adapterType == "FILE")
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2003/file-properties");
}
else if (adapterType.Contians("SFTP") && !adapterType.Contains("nsoftware"))
// nsoftware uses the FTP schema
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2012/Adapter/sftp-properties");
}
else if (adapterType.Contains("FTP"))
{
filePath = (string)pInMsg.Context.Read("ReceivedFileName",
"http://schemas.microsoft.com/BizTalk/2003/ftp-properties");
}
}
And then you can just fall back to the MessageID if you can't get the file path from any of these.
Related
When I pass the value from the OpenFilePicker() method back to the button click method, I can utilize a debug string and ensure that the value is not null.
However, when I pass it to the GetCellValue() method, a 'FileNotFound' exception is thrown. Utilizing a debug statement here also shows that the value is not null and returns a valid file path of "C:\Test.xlsx".
Tried changing file permissions to RWX for all, attempted different folder locations. All permissions and folders seem to have the same issue.
public async void FileSelectButton_ClickAsync(object sender, RoutedEventArgs e)
{
string filePath = await openFilePicker();
//Debug.WriteLine("result:: " + filePath);
GetCellValue(filePath, "Sheet1", "A1");
}
public async Task<string> openFilePicker()
{
var archerReportPicker = new
Windows.Storage.Pickers.FileOpenPicker();
archerReportPicker.ViewMode =
Windows.Storage.Pickers.PickerViewMode.Thumbnail;
archerReportPicker.SuggestedStartLocation =
Windows.Storage.Pickers.PickerLocationId.Downloads;
archerReportPicker.FileTypeFilter.Add(".xlsx");
archerReportPicker.FileTypeFilter.Add(".xls"); // Default extensions
Windows.Storage.StorageFile archerReport = await archerReportPicker.PickSingleFileAsync(); //Get file
if (archerReport != null)
{
// Application now has read/write access to the picked file
this.fileTextBox.Text = archerReport.Name; // Load it up and throw the data in the textbox.
var filePath = archerReport.Path;
return filePath;
}
else
{
this.fileTextBox.Text = "";
return null;
}
}
public static string GetCellValue(string fileName, string sheetName, string addressName)
{
string value = null;
// Open the spreadsheet document for read-only access.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, false)) //Line where exception is thrown
{...}
Throws System.IO.FileNotFound Exception as opposed to opening valid file path.
The issue also occurs when filePath or fileName is defined using const string '#c:\test.xlsx'
The short answer to this question is here:
https://blogs.msdn.microsoft.com/wsdevsol/2012/12/04/skip-the-path-stick-to-the-storagefile/
The gist of it is that in UWP, Storage Pickers return a non-filesystem bound Windows.Storage object. You can glean the filesystem path from the object, but because you are performing an operation on a secondary object, the fact that the user gave permissions for the first object does not apply to the second, resulting in an Access Denied condition when attempting to open the file - even if NTFS permissions allow 'Everyone' access.
This can be confirmed by monitoring the application using Process Monitor from SystemInternals.
If I discover a work-around to this issue, I will update this answer, but I will likely move away from UWP back towards a Windows Forms Application to avoid this issue entirely.
I'm creating a game using C# and trying to incorporate a CSV for parsing previous scores into a leaderboard and also writing to the file when a player finishes their game.
This is the data stored relating to a score
If this was a sole project I would store the csv in the bin > Debug folder and pass the file path to a StreamReader. Although, this is a group project using Azure Devops/TFS as source control so I'm not too sure what way is best to do this.
I have tried storing the CSV in the Resources of the project but I didn't realise this embeds the file in the project and only allows for reading from the file.
The CSV is currently read like:
var file = Properties.Resources.highscores;
char[] splitter = "\r\n".ToCharArray();
string[] scoresCsv = Properties.Resources.highscores.Split(splitter);
foreach (string score in scoresCsv)
{
if(!String.IsNullOrEmpty(score))
{
var values = score.Split(',');
highScores.Add(new HighScore(values[0], Convert.ToInt32(values[1]), Convert.ToDateTime(values[2])));
}
}
this.highScores = highScores.OrderByDescending(x => x.Score).ToList();
Select the "Team Explorer" window and go to "Source Control Explorer"
Here you will see a global view of the project.
You can add files to your project in any folder you wish outside of the actual source. If you want to you can add your bin folder into the source control and keep that file in the bin folder.
Where-ever you put the file you just need to know the location to it from your project and you are able to map to it and edit it in runtime.
Another option is to create a folder in the C:\ProgramData folder for your game and you can write the leaderboards directly into their C drive when they run the game. People would be able to modify the leaderboards but, obviously the game is for learning purposes of coding and usually you wouldn't store the leaderboards on the client side anyway it would be on a server.
This assumes that the high score data is not shared, and stores it locally. It doesn't require the file to be added to source control.
public class ScoreFileHandler
{
private static string appPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "YourAppName");
private static string scoreFileName = "highscores.txt";
private static string filePath = Path.Combine(appPath, scoreFileName);
public string ReadFile()
{
if (!Directory.Exists(appPath))
{
Directory.CreateDirectory(appPath);
}
if (File.Exists(filePath))
{
return File.ReadAllText(filePath);
}
return string.Empty; // TODO - caller needs to handle this
}
public void WriteFile(string csvScoreData)
{
if (!Directory.Exists(appPath))
{
Directory.CreateDirectory(appPath);
}
File.WriteAllText(filePath, csvScoreData);
}
}
I'm running a program written in C# from the command line as administrator that should generate the batch file (which it does), and then it should sFTP the file to a remote site. I have verified the username and password are correct. When I run the utility (C# program) to do this it says it's transferring the file and then immediately gives me this
ERROR: Local to local copy not supported.
However, I can manually (through Filezilla) move the file from our server to their site. It's probably something silly, but I just can't seem to figure it out. Any help is appreciated!
There are many files to this program, but here is where the most of the FTP stuff is in the code. I hope it helps:
if (pars.ContainsKey("ftp"))
{
var env = (pars.ContainsKey("ftp") ? pars["ftp"] : null) ?? "default";
entities = entities ?? new SBLStagingEntities();
settings = settings ?? new SettingReader(entities, env).GetSetting();
var filename = Path.GetFileName(pars["path"]);
Console.WriteLine("Transfering {0} using sFTP ................................\t\t", filename);
var processors = new SblFtpTransport(settings);
processors.ProcessFile(pars["path"]);
Console.Write("sFTP Done\n");
}
///-----------------------a different class that is called from the first one------///
public SblFtpTransport(Settings settings)
{
_settings = settings;
}
/// <summary>
/// this method is called by file watcher for each new file dropped in the watched folder
/// </summary>
/// <param name="file"></param>
public void ProcessFile(string file)
{
var fileName = Path.GetFileName(file);
if (!File.Exists(file) || string.IsNullOrEmpty(fileName))
{
Console.Error.WriteLine("file does not exist");
return;
}
//ftp the file and record the result in db
var result = FtpFile(file);
Log(fileName, result);
Console.Write("{0}", result);
Archive(result, file);
}
///-------------------------------another class that is used--------------///
public class WatcherSettings
{
public IFileProcessor CreateProcessor()
{
return new SblFtpTransport(new Settings()
{
AchiveFolder = #"C:\Docs\place\Watcher\Archived",
FtpPort = "22",
FtpServer = "xxxxx.someplace.net",
FtpTargetPath = "/StudentBatchLoad_FW",
FtpUsername = "xxx",
Password = "xxxxxxx",
});
}
public string WatcherPath { get; set; }
}
As far as I can tell, you never call CreateProcessor(). And it appears you need to call that so the settings get created properly with the remote host, and that's why you get an error that you're trying to copy to local host. So change your code to call that.
But your code is extremely disjointed and hard to read. Spend some time cleaning it, and step through it with a debugger to see exactly what's happening.
I have an application written in C#, and I am seeking to write some information to the hidden ProgramData in order to access the same connection string from both the application's front end and back end.
I am accessing the directory using path variables as follows:
private bool ProgramDataWriteFile(string contentToWrite)
{
try
{
string strProgramDataPath = "%PROGRAMDATA%";
string directoryPath = Environment.ExpandEnvironmentVariables(strProgramDataPath) + "\\MyApp\\";
string path = Environment.ExpandEnvironmentVariables(strProgramDataPath)+"\\MyApp\\ConnectionInfo.txt";
if (Directory.Exists(directoryPath))
{
System.IO.StreamWriter file = new System.IO.StreamWriter(path);
file.Write(contentToWrite);
file.Close();
}
else
{
Directory.CreateDirectory(directoryPath);
System.IO.StreamWriter file = new System.IO.StreamWriter(path);
file.Write(contentToWrite);
file.Close();
}
return true;
}
catch (Exception e)
{
}
return false;
}
This seems to work correctly. However, my question is, when I used this path variable: %AllUsersProfile%(%PROGRAMDATA%)
instead, it expanded into an illegal(and redundant) file path : C:\ProgramData(C:\ProgramData)\
However, I thought that the latter path variable was the correct full name. Was I just using it incorrectly? I need to ensure that this connection info will be accessible to all users, will just using %PROGRAMDATA% allow that? I am using Windows 7 in case that is relevant.
From here:
FOLDERID_ProgramData / System.Environment.SpecialFolder.CommonApplicationData
The user would never want to browse here in Explorer, and settings changed here should affect every user on the machine. The default location is %systemdrive%\ProgramData, which is a hidden folder, on an installation of Windows Vista. You'll want to create your directory and set the ACLs you need at install time.
So, just use %PROGRAMDATA%, or better still:
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
I'm kinda new to working with C# .NET's System.IO namespace. So please forgive me for some basic questions.
I am writing an online interface that will allow a site owner to modify files and directories on the server.
I have gotten inconsistent performance out of System.IO.Directory.Delete(PathToDelete, true);. Sometimes it works great, sometimes it throws an error. My controller looks like this:
public ActionResult FileDelete(List<string> entity = null)
{
if (entity != null)
{
if (entity.Count() > 0)
foreach (string s in entity)
{
string CurrentFile = s.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
string FileToDelete = Server.MapPath(CurrentFile);
bool isDir = (System.IO.File.GetAttributes(FileToDelete) & FileAttributes.Directory) == FileAttributes.Directory;
if (isDir)
{
if (System.IO.Directory.Exists(FileToDelete))
{
//Problem line/////////////////////////////////
System.IO.Directory.Delete(FileToDelete, true);
}
}
else
{
if (System.IO.File.Exists(FileToDelete))
{
System.IO.File.Delete(FileToDelete);
string ThumbConfigDir = ConfigurationManager.AppSettings["ThumbnailSubdirectory"];
string ThumbFileToDelete = Path.GetDirectoryName(FileToDelete) + Path.DirectorySeparatorChar + ThumbConfigDir + Path.DirectorySeparatorChar + Path.GetFileName(FileToDelete);
if (System.IO.File.Exists(ThumbFileToDelete))
{
System.IO.File.Delete(ThumbFileToDelete);
}
}
}
}
}
return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri.ToString());
}
Sometimes, I get an error when tring to delete directories that says:
The directory is not empty.
Description: An unhandled exception occurred during the execution of the current
web request. Please review the stack trace for more information about the error
and where it originated in the code.
Exception Details: System.IO.IOException: The directory is not empty.
Source Error:
Line 137: if (System.IO.Directory.Exists(FileToDelete))
Line 138: {
Line 139: System.IO.Directory.Delete(FileToDelete, true);
Line 140: }
Line 141: }
I'm not sure what kind of defensive coding I can implement to avoid get errors like these. Any thoughts? Am I missunderstanding what it means to set recursive to true by saying System.IO.Directory.Delete(FileToDelete, true);?
If there's a file that's in use, the Delete won't empty the directory, and then will fail when it will try to delete the directory.
Try using FileInfo instead of the static methods, and use Refresh after you do any action on the file. (or DirectoryInfo for direcotries)
Similar problem
In general you just have to expect this sort of exceptions from file/folder manipulation code. There is large number of reasons why it could happen - some file in use, some process have working folder set to the directory, some files are not visible to your process due to permissions and so on.
Process monitor ( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) likely will show what causes the problem.
One of common reason if you create folder yourself for your temporary files and then try to delete it is to forget to dispose Stream objects related to files in such folder (could be indirect links by Reader and Writer objets, XmlDocument).