Windbg and viewing AppDomain content - c#

I know we can use !dumpdomain command in winbbg to view the various app domains present in a given managed process(e.g. w3wp).
I wrote a small program(Recipe 3-1 from Visual C# 2010 Recipes A problem solution approach) in LinqPad, to create a custom AppDomain. This is where I am facing issues. I am not able to view this appdomain using windbg. In other words, where is this app domain created ? Is it hosted inside LinqPad process ? If not, then which process is hosting this custom appdomain ?
I tried attaching LinqPad.exe to windbg and issues !dumpdomain command but I got the following error :
Failed to find runtime DLL (clr.dll), 0x80004005 Extension commands
need clr.dll in order to have something to do.
Code :
void Main()
{
AppDomainSetup setUpInfo = new AppDomainSetup();
setUpInfo.ApplicationBase = #"C:\MyRootDirectory";
setUpInfo.ConfigurationFile = "MyApp.config";
setUpInfo.PrivateBinPath = "bin;plugins;external";
AppDomain newDomain = AppDomain.CreateDomain("My New Domain",null,setUpInfo);
Console.WriteLine("Main method complete.Press Enter");
Console.ReadLine();
}
Steps Followed :
Run the program. It waits for the user to press Enter.
Start windbg. Attach LinqPad.exe.
issue commands : .load sos.dll and .load sosex.dll
Issue command .reload
Finally call !dumpdomain. At this point the LinqPad freezes. If I close the windbg, then LinqPad is also closed.

It's created inside the LINQPad process. Your query itself runs in separate AppDomain created by LINQPad. Could the error message be related to a CLR version mismatch? Are you running LINQPad 2.x or 4.x?

Related

Running a process from jenkins

My console application is responsible for starting a WCF service in interactive mode (ie. the service does not get installed as a Windows service in that case).
In order for my application to start the latter, the application invokes the compiled executable using the following method:
static bool AutoStartService()
{
var MyProcessFile = System.IO.Path.GetFullPath($"pathToExecutable/MyServiceExe.exe");
Process myProcess = new Process();
myProcess.StartInfo.FileName = MyProcessFile;
myProcess.StartInfo.Arguments = "";
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
myProcess.Start();
Thread.Sleep(WaitForTheServiceToStart);
}
return true;
}
Note that this approach works just fine when debugging from Visual Studio.
However, when the console application is invoked from Jenkins (note that I gave Jenkins admin access and it logs in as a normal user), then the service process does not seem to stick or be visible from the Console application. I can tell it at least starts and stops as I can see the logs being written to file.
The Console application is started using a batch command from Jenkins (I also tried using Powershell, but without luck).
Any suggestion on how to do that?
I have tried with both debug and release builds of my Console app C# project, but it makes no difference.
EDIT
I have edited the following properties, but without success:
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.Environment.Add("BUILD_ID", "dontKillMe");
I am now seeing the following warning, but I don't believe installing the service is the only way to go as this is what I am doing when running this code without Jenkins and it works. Maybe Jenkins does not allow it though?:
Cannot start service from the command line or a debugger. A Windows Service must first be installed (using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.
EDIT2
I went a step further. The reason why I was getting the former message is that the service checks "Environment.UserInteractive" to either run as interactive or to start/run the installed service. For some reasons this flag is always set to false, while it should be true in my case.
Is there a way to fool the service to think that flag is true?

C# Class Library throws FileNotFoundException while trying to load another library

I try to connect to a fiscal device with a C#.
I use this documentation to do so: http://integration.atol.ru/api-en/#connection-to-project
So basically I have a driver of the device installed on my PC (fprt10.dll) and there is a "wrapper" assembly that allows me to work with this driver from C# (Atol.Drivers10.Fptr.dll). I import this wrapper into my project as a reference.
I have the following constructor in my class:
public MyClass()
{
IFptr fiscalPrinter = new Fptr();
// Here comes several settings to configure connection
fiscalPrinter.applySingleSettings();
fiscalPrinter.open();
fiscalPrinter.beep();
fiscalPrinter.close();
}
To test the solution I use another application, that loads my Class Library as a dependency.
When I call a constructor of MyClass I get an exception:
System.IO.FileNotFoundException: Driver not installed
at Atol.Drivers10.Fptr.Fptr.loadDriver(String path)
at Atol.Drivers10.Fptr.Fptr..ctor()
at MySolution.MyClass.MyClass()
...
If I create instance of Fptr with a path to the driver
IFptr fiscalPrinter = new Fptr(#"C:\path\fptr10.dll")
I get the slightly different exception, but I believe the problem is the same:
System.IO.FileNotFoundException: Can`t load driver library "C:\path\fptr10.dll"
at Atol.Drivers10.Fptr.Fptr.raiseNotFoundError(String path, Exception reason)
at Atol.Drivers10.Fptr.Fptr.loadDriver(String path)
at Atol.Drivers10.Fptr.Fptr..ctor(String libraryPath)
at MySolution.MyClass.MyClass()
...
But when I create a Console Application and put in there exact same code (both versions with path and without), everything works: the device beeps, there are no exceptions.
What could be the reason for that behavior and how to fix this?
The issue may be one of the following
The test application is using 'target platform' different than the console application which works fine. The device driver folders expected for each platform could be different. e.g. Changing the targeted platform from 'any CPU' to 'x64' / 'x86' (depending on the type of OS where you are running it) will help
Try running the test application from admin command prompt. Permissions issue may reflect as 'file not found' (instead of 'file could not be loaded').
Use an assembly binding viewer tool to debug the issue further
Refer to Could not load file or assembly or one of its dependencies for more discussion and inputs on the assembly loading issues.
Thank you samiksc.
The issue was in the test app. The driver and OS that I use are both x64, but the test application is x86. With x86 driver everything works.

Start.Process not run scipt in separate process

I want to run my long runing python script from my console app.
I use
("my_script.py"), when I shut down console also python script is terminate.
In task manager all(console app and script) is runing under .Net Core Host.
How to run python as completly separated process?
Normally, this would start your python script completely outside of your console application:
System.Diagnostics.Process.Start(#"C:\path\to\my_script.py");
In classic .NET it will invoke the process via a new shell, but in .NET Core, the process is created directly inside the existing executable. There is an option to change this, called UseShellExecute. This is directly from the Microsoft documentation:
true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true on .NET Framework apps and false on .NET Core apps.
This is how you can use it:
var myPythonScript = new Process();
myPythonScript.StartInfo.FileName = #"C:\path\to\my_script.py";
myPythonScript.StartInfo.UseShellExecute = true;
myPythonScript.Start();
When your C# console app terminates, your python script should still be running.
EDIT
Thanks to Panagiotis Kanavos, he made me realize the UseShellExecute has nothing to do with the parent/child relationship between the processes. So I setup a sandbox locally with .NET Core and played around with it a bit and this is working for me:
var myPythonScript = new Process();
myPythonScript.StartInfo.FileName = #"C:\path\to\python.exe"; // the actual python installation executable on the server
myPythonScript.StartInfo.Arguments = #"""C:\path\to\my_script.py""";
myPythonScript.StartInfo.CreateNoWindow = true;
myPythonScript.Start();
When the parent app terminates, my python script is still running in the background.

Error when reading audio file?

I have the following function that I am attempting to use to determine the length of an MP3 file:
public static string GetMP3DurationBackup(string Filename)
{
string Duration = null;
WMPLib.WindowsMediaPlayer w = new WMPLib.WindowsMediaPlayer();
WMPLib.IWMPMedia m = w.newMedia(Filename);
if (m != null)
{
Duration = m.durationString;
}
w.close();
return Duration;
}
I have run into an issue where I get the following error:
Retrieving the COM class factory for component with CLSID
{6BF52A52-394A-11D3-B153-00C04F79FAA6} failed due to the following
error: 80040154..
when I call the above function from my web application (call below):
string test = MediaUtil.GetMP3DurationBackup(#"C:\Temp\Audio\bad.mp3");
But when I call it from a console application test harness I created (exact same call as above) it works fine. I have set the project that contains the function to target x86 in the Build properties, but that did not fix the issue.
Does anyone know why this would happen? Suggestions on where to start to debug this?
UPDATED FOR BOUNTY:
Ok, I've tried a number of things but I am still getting this error. Among other things I have tried the steps below which I felt were the most promising, but no dice:
Went into my registry and confirmed that the value at:
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{6BF52A52-394A-11d3-B153-00C04F79FAA6}\InprocServer32
is refering to C:\WINDOWS\SysWOW64\wmp.dll
Opened command prompt,
navigated to C:\WINDOWS\SysWow64, ran: regsvr32.exe wmp.dll
I have created a console app test harness and I am able to reproduce the error if I run the test project in x64. If I switch it to x86 it works fine.
Does anyone have any idea of why the above would not resolve the issue? Suggestions on where to look next?
You say it doesn't work in x64, but you try to register the 32-bit version of wmp.dll (C:\Windows\SysWow64 contains 32-bit assemblies).
Try to register the x64 version of wmp.dll, which is located in C:\Windows\System32 on a 64-bit platform.
If you don't have this file then there probably is no 64bit Windows Media Player available for your platform. But there is a workaround:
Create a 32-bit console application that takes the mp3 filename as command line argument and outputs the duration to stdout using Console.WriteLine, then in the webapp, you call the console application and capture the output like in this example on MSDN
Give this lib a whirl. Its fast and has no special requirements for software to be installed on the machine.
http://naudio.codeplex.com/

C# .Net Service won't install on Win 7 64 bit

.Net 3.5
I've built into the service exe the ability for it to install itself using a -i feature. I have a custom installer class and am using a common technique on found online here. That installer class basically has it's own service and serviced process installer.
This code has worked well for a very long time. Finally ran into a Win 7 64 bit machine were it refuses to install.
Basically, the log shows it's installing the service and that succeeds. Then it tries to create an event log and that fails with
An exception occurred during the Install phase.
System.ComponentModel.Win32Exception: The specified service already
exists
I just got done having the OS completely reinstalled from scratch, first thing I did was try to install as a service, and it's the same error. Why is it thinking that event log is already there?
I've already read all the other posts and I've browsed my registry and there is nothing in there for my service or event log. I have full admin rights, when I try to open cmd as administrator, it doesn't even prompt me, so as far as I can tell, I am an admin (I can see that in my user profile).
I even added code to check to see if it found the EventLog using System.Diagnostics.EventLog.SourceExists which does report it found it, and so I added a call to System.Diagnostics.EventLog.DeleteEventSource but that doesn't help.
I even tried removing the EventLog installer from the ServiceInstaller, but then it starts failing for other reasons.
Any ideas?
Here is some sample code for an alternate installer I tried that I found here with the same results:
public partial class Service1Installer : Installer
{
public Service1Installer()
{
InitializeComponent();
ServiceProcessInstaller process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
ServiceInstaller serviceAdmin = new ServiceInstaller();
serviceAdmin.StartType = ServiceStartMode.Manual;
serviceAdmin.ServiceName = "Service1";
serviceAdmin.DisplayName = "Service1";
serviceAdmin.Description = "Service1";
Installers.Add(serviceAdmin);
Installers.Add(process );
}
}
uninstall your service
installutil /u yourproject.exe
restart your machine
http://msdn.microsoft.com/en-us/library/sd8zc8ha(v=vs.80).aspx
let me know if you still have a issue
Use installutil as #MicahArmantrout mentions, if the exe still resides on disk.
Otherwise, open a commandline as Administrator and execute: sc delete "my service name"
In the end, my problem was our internal installer. I commented it out and now just install the service from the command line and it now installs on 64 bit OS. Still don't know why it would work before on 32 bit.

Categories

Resources