Executing Assembly Location is Unknown - c#

TL;DR
Why
System.Reflection.Assembly.GetExecutingAssembly().Location
returns "<Unknown>"?
The whole story:
When I run my console application manually, everything goes well. When I set Task Scheduler to run my app, there is a problem: my app can't find some dependent files.
These files are written in the .config file like this:
<add key="SomeFile" value="SomeFolder\SomeFile.xml"/>, I need only relative pathes.
When I run my app manually, 'current folder' = 'application folder', but when I run with Task Scheduler, 'current folder' = C:\Windows\system32, because with Task Scheduler my app runs under taskeng.exe which lies in system32.
So to find assembly path I want to use this code:
System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
from this answer https://stackoverflow.com/a/16102640/6184866.
But it doesn't work.

After native compilation, the assembly no longer exists on the file system.
A more recent way to pull the current directory is:
AppContext.BaseDirectory
This works in .net6

I had this same issue also with a console application.
I only received this error when:
The assembly is built as release with optimisations on
The program is run outside of Visual Studio and then the process is attached to
The command Assembly.GetExecutingAssembly().Location is executed via the Immediate Window.
It can be replicated with the following code. The sleep in a loop is just to give me time to attach the debugger.
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine(10 - i);
Thread.Sleep(1000);
}
Console.WriteLine(Assembly.GetExecutingAssembly().Location);
Console.WriteLine(Directory.GetCurrentDirectory());
Console.ReadLine();
}
Breakpointing this code (when the above constraints are true) and from the Immediate Window executing the command Assembly.GetExecutingAssembly().Location returns <Unknown>. Executing Directory.GetCurrentDirectory() returns Cannot evaluate expression because the code of the current method is optimized.
However, both commands execute and print the expected correct values to the console.

Related

.bat file in Visual Studio 2017

I'm trying to run a .bat file in my application. This .bat calls a JTAG application to load a firmware in microcontroller. However, I don't know why this fail in to execute the software.
If I run the .bat outside of Visual Studio it works perfectly.
I have the GUI and a Button which I will click to execute the firmware loading
To generate the command files I used a software Uniflash. This software generates a folder with all necessary files to execute the JTAG access and load the firmware.
My code is below:
private void Button_Relay_Click(object sender, EventArgs e)
{
Process MSP = new Process();
MSP.StartInfo.WorkingDirectory = #"D:\\Projects\\Test_Fixture\\Test_Fixture_Visual_Studio\uniflash_windows_64";
MSP.StartInfo.FileName = "dslite.bat ";
MSP.Start();
Thread.Sleep(500);
MSP.WaitForExit();
}
However when I executed this code the compilation is ok, but when I run this code appear this error:
Questions:
I will always generate specific bat files for each application and include the .bat folder inside the folder of VS C#, how I set up the directory path to check automatically in my software folder?
Why the VS can't find the files if the path is right?
After my .bat run I would like to read the status of the programming ( Success or fail ) How I do it?
Success
Fail:
Ad 2)
About the error:
That's because you may have specified the path wrong:
Instead of
MSP.StartInfo.WorkingDirectory = #"D:\\Projects\\Test_Fixture\\Test_Fixture_Visual_Studio\uniflash_windows_64";
either use \\ everywhere (there is only one \ between Test_Fixture_Visual_Studio and uniflash_windows_64) and skip the # OR use the # and just use one \ instead of two. So replace your line with this one:
MSP.StartInfo.WorkingDirectory = #"D:\Projects\Test_Fixture\Test_Fixture_Visual_Studio\uniflash_windows_64";
Ad 3)
About the result of your prcess:
In my opinion it is easier to not call a batch file but to call the process itself directly. In this way you can retrieve the Process.ExitCode property to retrieve the exit code of the executable (if it returns it's state via the exit code).
You can check this by calling the executable in the command shell and check the error level of the last execution by calling
echo %ERRORLEVEL%
Usually 0 indicates success, everything else indicates a failure of some kind.

Csc.exe running in AppDomain is getting arguments from caller's command line

I'm trying to run csc.exe (the C# compiler) from within an AppDomain created from my executable. However, what I'm seeing is that any argument passed to my executable also seems to be passed to csc.exe, even though I'm not providing any arguments.
Here's my complete application:
class Program
{
static void Main(string[] args)
{
var cscPath = #"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Roslyn\csc.exe";
var appDomain = AppDomain.CreateDomain("csc");
appDomain.ExecuteAssembly(cscPath);
Console.ReadLine();
}
}
When I run this without providing any arguments to my program, I see what I expect:
warning CS2008: No source files specified.
error CS1562: Outputs without source must have the /out option specified
However, when I add "-test" to the command line of my executable (using my project's Debug tab in Visual Studio), I get this output:
error CS2007: Unrecognized option: '-test'
warning CS2008: No source files specified.
error CS1562: Outputs without source must have the /out option specified
The "-test" now shows up as an error to csc.exe, and I don't know why it's even seeing that parameter.
Obviously, this is a contrived example, and I'm not really trying to call csc.exe without any parameters, but this is the minimal example where I can see the behavior.
If I call csc.exe using Process.Start, I don't see this behavior.
Any help would be appreciated!

Require a full clean/rebuild prior to running a console application in Visual Studio

I have a c# console application project in visual studio that should only be run:
with the debugger attached
and only after a full clean / rebuild
Is there a way to force the project to fail if hasn't had a full clean/rebuild prior to launch?
Background info: The application is used to deploy versions of another application. It gathers up everything that's needed from various sources including downloads, zips them and and places them in a version deployment system.
One of the sources it gathers up files from is the output directory of another project that it references. The full clean/rebuild is required to ensure that output directory contains the latest and correct binaries.
The REAL problem I'm trying to solve is making sure that we are deploying the latest and correct binaries from another project.
The only way for an application to know if it was built-clean is for it to inspect the rest of the files in the directory it lives in, how you do that is up to you (try using FileInfo and inspect the LastWriteTime property).
As for the debugger, try this:
using System.Diagnostics;
using System.Threading;
...
public static Int32 Main(String[] args) {
if( !Debugger.IsAttached ) {
Console.WriteLine("No debugger attached. Execution will resume once a debugger is attached.");
while( !Debugger.IsAttached ) Thread.Sleep( 100 );
}
}

Why is the working directory the directory of the executable and not where I'm running from?

I'm running my console app from a plain old command prompt. I'm running it two ways:
using a relative path to the executable from what I think is the working directory. i.e.
C:\Working>.\path\to\my.exe -fileToRead file.txt
using a folder in my $PATH$. I.e.
C:\Working>my.exe -fileToRead file.txt
file.txt is in C:\Working and my.exe is C:\Working\path\to. my.exe will output an XML log file to the working directory. In my mind that, that should be C:\Working, but the file actually ends up in C:\Working\path\to. This doesn't jive with all other command line applications.
I'm not doing anything weird or non-standard (that I know about). I've tried just using the file name for the XML file, "TestResult.xml" and also Path.Combine(Environment.CurrentDirectory, "TestResult.xml"). Both end up in the executable directory, not the directory from which I'm running. The command-line parameter file argument is being read properly, so I know that's working.
Clarification: Basically, my problem is that Environment.CurrentDirectory and Assembly.GetExecutingAssembly().Location are the same directory, but shouldn't be.
What am I doing wrong here? And how do I get the directory from which I execute, not the path to the executable? (I realize I have the exact opposite problem of many questions on stackoverflow)
The results you have using Environment.CurrentDirectory are not the one I get with a very simple program like this
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Environment=" + Environment.CurrentDirectory);
Console.WriteLine("Assembly=" + Assembly.GetExecutingAssembly().Location);
}
}
}
Executing this little app from the command line gives always for the first line the directory where the command prompt is running and the second line always the directory where the assembly is located.
So, I suppose that your problem is caused by something different. Probably a change in the current directory.

The filename, directory name, or volume label syntax is incorrect, c#

i've written a console application deploy.exe which runs a batch script.
Process p1 = new Process();
p1.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "installer.bat";
p1.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
p1.Start();
p1.WaitForExit();
p1.Close();
the installer.bat conatins the following command.
\shared1\lists\list1.cmd
If i run the executable byitself it runs successfully.
However i needed it to run in a windows installer project. So i made a setup and deployment project and added the deploy.exe successfully as custom action upon install.
It runs fine but when it starts to execute the command i get this error
"The filename, directory name, or volume label syntax is incorrect".
any help?
Try printing out what the value of AppDomain.CurrentDomain.BaseDirectory is. It may not be where installer.bat is when you are installing it.
Also, you tried adding the bat file to a custom action (if that is even possible)?
And, would it possible to move what is in the bat to the exe?
Is it a problem in your batch file?
Check this:
\\shared1\\lists\\list1.cmd
should probably be
\\shared1\lists\list1.cmd
Note the extra \ chars in your original command. That would cause the batch file to give that error.
the error seems to be inside the script which was being executed. It contained environment variables %kind%, which were not acceptable by the installer for some reason. So it was working properly outside the installer and not properly when the installer was calling it.

Categories