I have a problem here and i need some help.
I work on a C# software in WPF, i have finished it, the program compile but do not run.
I've tried to search the problem using step by step run and it end on this line
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = Application.StartupPath + #"\Logs\" + DateTime.Now.DayOfYear + ".txt" };
and
var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
and i got this error : " Attempt to read or write protected memory. This often indicates that another memory is corrupted "
that happen randomly during execution but mostly while running theses lines of code.
If you got a solution i'll take it !
The WPF Application class does not have a StartupPath property.
You could add System.Windows.Forms as project reference and use System.Windows.Forms.Application.StartupPath
Alternative:
string appPath = System.Reflection.Assembly.GetExecutingAssembly()
.GetModules()[0].FullyQualifiedName;
string appDir = Path.GetDirectoryName(appPath);
To debug your code with finer granularity, you could rewrite it:
var fileName = Application.StartupPath;
fileName += #"\Logs\";
fileName += DateTime.Now.DayOfYear
fileName += ".txt";
var logfile = new NLog.Targets.FileTarget("logfile");
logFile.FileName = fileName;
Related
I try to display RTSP stream using Gstreamer in my WPF application.
So I did so far:
installed GStreamer into loal folder F:/gstreamer
Created new WPF application
Added glib-sharp and gstreamer-sharp as dependencies.
The code below I use to init the library:
Gst.Application.Init(); // (1)
mainLoop = new GLib.MainLoop();
mainGLibThread = new System.Threading.Thread(mainLoop.Run);
mainGLibThread.Start();
Element uriDecodeBin = ElementFactory.Make("playbin", "uriDecodeBin0"); // (2)
Unable to load DLL 'libgstreamer-1.0-0.dll': The specified module could not be found.
on line (1). If I copy all the gstreamer dlls into bin/Debug folder the exception gone but ElementFactory.Make in line (2) always returns null without any exception. If I try to do something like
Parse.Launch(#"videotestsrc ! videoconvert ! autovideosink")
to test the library functionality I get error:
no element "videotestsrc"
but if I run it from command line:
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink
that works as expected.
So my question - how to get GStreamer-sharp work?
Change path to GStream and add this code before start
string path = #"G:\gstreamer\1.0\x86\"; // path to your gstream
string pluginpath = #"G:\gstreamer\1.0\x86\lib\gstreamer-1.0\"; // path to your gstream
string registry = System.IO.Path.Combine(path, "registry.bin");
Environment.SetEnvironmentVariable("PATH", Environment.GetEnvironmentVariable("PATH") + ";" + path);
Environment.SetEnvironmentVariable("GST_PLUGIN_PATH", pluginpath + ";" + Environment.GetEnvironmentVariable("GST_PLUGIN_PATH"));
Environment.SetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH_1_0", pluginpath + ";" + Environment.GetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH_1_0"));
Environment.SetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH", pluginpath + ";" + Environment.GetEnvironmentVariable("GST_PLUGIN_SYSTEM_PATH"));
Environment.SetEnvironmentVariable("GST_DEBUG", "*:4");
Environment.SetEnvironmentVariable("GST_DEBUG_FILE", System.IO.Path.Combine(path, "gstreamer.log"));
Environment.SetEnvironmentVariable("GST_REGISTRY", registry);
I have been working on converting a GUI script from another language to C# in VS2017 for a customer. With help from the folks here I am 95% of the way there, but have run into a couple of snags; just not sure I am doing things in the best way. I'm including just the relevant portions of code below, please let me know if I am not providing enough:
The majority of the code is centered on the wpf form, which collects data for low level technicians to batch deploy a number of Virtual Machines into the VMware environment. This number could easily range into the dozens or even a hundred VMs at once. The information for each VM is specified in the form, then collected in a listview. Once the listview is fully populated it is exported to a csv. Up to this point everything works just fine.
I've next been working on actually launching the powershell/powerCLI script (also working) and capturing output. The log file is opened with a specific reader application the customer uses, which updates in real time, and the captured output is fed to the log. It is important for the technicians to see the output from the code line by line so they can react if there is an issue.
I started with something like this as a test:
string sPSScript = "C:\\Users\\Admin\\Desktop\\TestC#.ps1";
string logFile = "C:\\Users\\Admin\\Desktop\\My.log";
string logReader = "C:\\Users\\Admin\\Documents\\CMTrace.exe";
string standard_output;
System.Diagnostics.Process PSScript = new System.Diagnostics.Process();
PSScript.StartInfo.FileName =
Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) +
"\\WindowsPowerShell\\v1.0\\powershell.exe";
PSScript.StartInfo.Arguments = "-command . '" + sPSScript + "' " +
vCenter.Text;
PSScript.StartInfo.RedirectStandardOutput = true;
PSScript.StartInfo.UseShellExecute = false;
PSScript.Start();
System.Diagnostics.Process LogFile = new System.Diagnostics.Process();
LogFile.StartInfo.FileName = logReader;
LogFile.StartInfo.Arguments = logFile;
LogFile.Start(); while ((standard_output =
PSScript.StandardOutput.ReadLine()) != null)
{
if (standard_output != "")
{
using (StreamWriter file = new StreamWriter(logFile, append: true))
{
file.WriteLine(standard_output);
}
}
}
While this writes to the log file in real time as expected, it creates 100 instances of the logReader application. I understand why, since I am declaring a new StreamWriter object through every pass, but am unsure how better to go about this.
I tried creating the file outside the loop, like this:
StreamWriter file = new StreamWriter(logFile, append: true) { };
System.Diagnostics.Process LogFile = new System.Diagnostics.Process();
LogFile.StartInfo.FileName = logReader;
LogFile.StartInfo.Arguments = logFile;
System.Diagnostics.Process PSScript = new System.Diagnostics.Process();
PSScript.StartInfo.FileName = Environment.GetFolderPath(Environment.SpecialFolder.SystemX86) + "\\WindowsPowerShell\\v1.0\\powershell.exe";
PSScript.StartInfo.Arguments = "-command . '" + sPSScript + "' " + vCenter.Text;
PSScript.StartInfo.RedirectStandardOutput = true;
PSScript.StartInfo.UseShellExecute = false;
LogFile.Start();
PSScript.Start();
System.Threading.Thread.Sleep(1500);
while ((standard_output = PSScript.StandardOutput.ReadLine()) != null)
{
if (standard_output != "")
{
file.WriteLine(standard_output);
}
}
It doesn't create multiple instances, but it also does not update the log file in real time as the previous code does. It only updates once the script runs, and then only partially. The script produces ~1000 lines of output, and I consistently see only about 840 written to the log file.
I thought about doing something like this:
FileStream logFS;
logFS = new FileStream(logFile, FileMode.Append);
but it appears the only options available to me to write to the file are expecting a byte array.
I am sure that I am missing something stupid simple in this, but would appreciate any suggestions on the easiest way to create the log file, open it in the reader, and then update it with the standard output from the powershell script.
why did the previous code writes in real time?
because you are wrapping it with using. And at the end of using block its gonna call dispose which calls .Flush to write to disk
Your second code block calls WriteLine but never called Flush so it writes to the disk whenever the buffer is full. Just add a .Flush call after WriteLine and you will have real time logging
I have windows form app with the following part of code when the Form Loads
public MonitorMail()
{
InitializeComponent();
pathfile = Directory.GetCurrentDirectory();
pathfile = pathfile + #"\Log\Configuration.txt";
var Lista = LoadConfigFile.LoadConfig(pathfile);
if (Lista.Count > 0)
{
SwithMailText.Text = Lista[0];
Excel_Textbox.Text = Lista[1];
LogFileText.Text = Lista[2];
MailServerText.Text = Lista[3];
FromText.Text = Lista[4];
SslText.Text = Lista[5];
UserText.Text = Lista[6];
}
}
As you can see in this code i declare a List named as "Lista" which List takes the records of the Configuration file and fill some textboxes with the data of that Configuration file.
My problem is the following: when I run my program inside in Visual Studio, it loads the records correctly in those textboxes.
When I run my program runs outside of Visual Studio, it also loads the records correctly
BUT
When I try run my program from the command prompt (because this how it should be run) like MonitorMail.exe the program runs but does not show the data in the textboxes.
After trying to understand why is this happening I noticed that is has something to do with
pathfile = Directory.GetCurrentDirectory();
I concluded to that because I changed the pathfile to pathfile="complete path of the Configuration.txt" so when I hit it from cmd works as it should be.
Any idea why Directory.GetCurrentDirectory(); affects cmd? Or is something am I missing?
You wrote in the comments: "i need for every PC to get current directory that my .exe is", but that is not what Directory.GetCurrentDirectory() does...
You need
string myPath = System.Reflection.Assembly.GetEntryAssembly().Location;
instead. That gives you the full path including the file name. You can take the Location's Directory if that is what you need.
I have the following code contained within a Script Task in SSIS 2012.
public void Main()
{
string inputDir = (string) Dts.Variables["User::InputDirectory"].Value;
string CSVFolder = (string) Dts.Variables["User::CSVFolder"].Value;
string XMLFolder = (string) Dts.Variables["User::XMLFolder"].Value;
string XLSXFolder = (string) Dts.Variables["User::XLSXFolder"].Value;
bool isXMLFolderEmpty = (bool) Dts.Variables["User::isXMLFolderEmpty"].Value;
bool isCSVFolderEmpty = (bool)Dts.Variables["User::isCSVFolderEmpty"].Value;
bool isXLSXFolderEmpty = (bool)Dts.Variables["User::isXLSXFolderEmpty"].Value;
string[] fileNames = Directory.GetFiles(#inputDir);
if (fileNames.Length > 0)
{
foreach (string inputFile in fileNames)
{
string FileExtension = Path.GetExtension(inputFile);
if (FileExtension == ".csv")
{
File.Move(inputDir + "\\" + inputFile, CSVFolder + "\\" + inputFile);
isCSVFolderEmpty = false;
}
else if (FileExtension == ".xlsx")
{
File.Move(inputDir + "\\" + inputFile, XLSXFolder + "\\" + inputFile);
isXLSXFolderEmpty = false;
}
else if (FileExtension == ".xml")
{
File.Move(inputDir + "\\" + inputFile, XMLFolder + "\\" + inputFile);
isXMLFolderEmpty = false;
}
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
However when I execute the Script task I am getting the following error:
DTS Script Task has encountered an exception in User code: Exception has been thrown by the target of invocation.
Can anybody point out what is going wrong? All of variable names are correct.
File.Move is incorrect
You might also be interested in the Path.Combine as it will more gracefully handle building paths than your blind string concatenation route.
Directory.GetFile indicates
Returns the names of files (including their paths) in the specified directory
so inputFile is already going to be in the form of C:\ssisdata\so_35605920\Foo.csv so your initial parameter to FileMove is simply inputFile
So really the challenge becomes changing the folder path out of the inputFile variable to the targeted one (CSV, XML, or XLSX). Lazy hack would be to call the string.replace method specifying the inputDir and using the new directory. I'd probably go with something a bit more elegant in case there's weirdness with UNC or relative paths.
Path.GetFileName will give me the file and extension. So using that + Path.Combine would yield the correct final path for our Move operation
Path.Combine(CSVFolder, Path.GetFileName(inputFile));
Thus
File.Move(inputFile, Path.Combine(CSVFolder, Path.GetFileName(inputFile)));
Visual studio is rather unhappy at the moment so pardon the lack of precision in the suggested code but if there are typos, you have the references to books online and the logic behind it.
Also, try/catch blocks are exceptionally helpful in defensive coding as will be testing to ensure the folders exist, there's no process with a lock on the file, etc.
Wondering how to best deal with a problem I am having with xsltransform. Long story short, everything works in my test environment, but it crashes when I run it on the server due to the filenames it tries to deal with, which are output from another program, over which I have no control.
For example. "4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml" a simple # would solve this, but it's actually running on a service, and this service gets all files of that type in the directory and processes them one by one.
string[] filepaths = Directory.GetFiles(path, Filetype);
I keep the file name variable in:
FileInfo f = new FileInfo(filepaths[i]);
But the method I use for the transform:
myXslTransform = new XslCompiledTransform();
myXslTransform.Transform(filename,OutputFileName);
Only accepts (String, String) and thus when it sees "4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml" it has a heart attack and cuts it off.
I was thinking save the original name, rename, remove whitespace, transform, and rename back. But I think there is a smarter way to handle it out there, just not sure where to look. Is there a way of telling C# to handle a variable as a literal? Or a different transform method that accepts these weird filenames with very bad naming conventions?
Any insight that helps would be great!
The error & exception message I recieve from the Eventvwr is
Cannot Translate
\\9g031\Export\4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml
OutputName = \\9g031\Export\done\4Copy (2) of Fed_Around_Six__TFVC020-12.mov.xml
XSL LOC = C:\CXS.xsl
System.IO.IOException: The specified path is invalid.
private void PreformTranslation(FileInfo FileName, String OutputFileName , String result)
{
try
{
XslCompiledTransform myXslTransform;
myXslTransform = new XslCompiledTransform();
myXslTransform.Load(XSLname);
EventLog.WriteEntry(FileName.ToString(), OutputFileName);
myXslTransform.Transform(FileName.Name,OutputFileName);
EventLog.WriteEntry("TranslationComplete");
if (File.Exists(path + result))
{
MoveVideoFiles(path + result, outputPath + result);
}
// Rename(OutputFileName, FileName, Out);
}
catch (Exception e)
{
EventLog.WriteEntry("Cannot Translate " + FileName + " OutputName = " + OutputFileName + " \r\n"+
"XSL LOC = " + XSLname + "\r\n" + e);
}
}
The default directory when running a service is something like "windows/system32" and this isn't the directory of the executable.
This is probably the reason the XML file isn't found.