This question already has an answer here:
How to ignore win32 exception? module process
(1 answer)
Closed 5 years ago.
I tried to create to look dll that loaded in process, but I got an error when getting process with system.dll. It throws this error message:
System.ComponentModel.Win32Exception: 'Unable to enumerate the process modules.'
My code:
using System;
using System.Diagnostics;
using System.Threading;
namespace dll
{
class Program
{
static void Main(string[] args)
{
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
foreach (ProcessModule module in process.Modules)
{
if (module.FileName.Contains("foo.dll"))
{
Console.WriteLine(module.FileName);
Console.ReadLine();
}
}
}
}
}
}
What is this? How to fix this?
This is not the final answer but better fits here then in a comment.
Try using this code to catch the exception and print it to the console. Then you can see the full stacktrace in the console. With this stacktrace you can further resolve the error.
You probably trying to access a MainModule where you don't have access too.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
namespace dll {
class Program {
static void Main(string[] args) {
try {
Process[] processlist = Process.GetProcesses();
foreach(Process process in processlist) {
foreach(ProcessModule module in process.Modules) {
if(module.FileName.Contains("foo.dll")) {
Console.WriteLine(module.FileName);
}
}
}
}
catch(Win32Exception ex) {
Console.WriteLine(ex.ToString());
}
Console.ReadLine();
}
}
}
It probably fails on this line: foreach(ProcessModule module in process.Modules) so you know it can't access one or more of the modules. Probably due to system restrictions.
If you only want to check the modules and therefore accept that not all the modules are checked then you can do this.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
namespace dll {
class Program {
static void Main(string[] args) {
int noErrorCount = 0;
int errorCount = 0;
Process[] processlist = Process.GetProcesses();
foreach(Process process in processlist) {
try {
foreach(ProcessModule module in process.Modules) {
if(module.FileName.Contains("foo.dll")) {
Console.WriteLine(module.FileName);
}
noErrorCount++;
}
}
catch(Win32Exception ex) {
errorCount++;
}
}
Console.WriteLine("Modules checked: " + noErrorCount);
Console.WriteLine("Modules with error(not checked): " + errorCount);
Console.ReadLine();
}
}
}
Code in an infinite loop
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
namespace dll {
class Program {
static void Main(string[] args) {
try {
while(true) {
int noErrorCount = 0;
int errorCount = 0;
Process[] processlist = Process.GetProcesses();
foreach(Process process in processlist) {
try {
foreach(ProcessModule module in process.Modules) {
if(module.FileName.ToLower().Contains("Kernel32.dll".ToLower())) {
Console.WriteLine(module.FileName);
}
//Console.WriteLine(module.FileName);
noErrorCount++;
}
}
catch(Win32Exception ex) {
errorCount++;
}
}
Console.WriteLine("Modules checked: " + noErrorCount);
Console.WriteLine("Modules with error(not checked): " + errorCount);
}
}
catch(Exception ex) {
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
}
}
Related
I have made a Windows Service in C# that calls a python script to run. This works without a problem. However, when I go to stop the service, it gives the error "could not be stopped" and I have to manually kill it using the PID in the command line. This hasn't always been like this and I can't seem to find previous versions of my code in VS2017. What part of my code is causing the Windows service to not be able to close?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Timers;
using System.Threading;
using System.Security.Permissions;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
public ThreadStart startScript;
public Thread PyScriptThread;
public ServerClass serverObject;
//-------------------------------------------------------------------------
public Service1() { InitializeComponent(); }
//-------------------------------------------------------------------------
protected override void OnStart(string[] args)
{
serverObject = new ServerClass();
PyScriptThread = new Thread(new ThreadStart(serverObject.PyScript));
var t = Task.Run(() => serverObject.PyScriptAsync(PyScriptThread));
}
//-------------------------------------------------------------------------
protected override void OnStop()
{
try
{
StreamWriter sw = new StreamWriter(#"C:\Users\bakere1\A19149\Projects\text_doc.txt", false);
sw.Write("***STOP***");
sw.Close(); //stop the script within the process
if (!serverObject.p.HasExited) //kill the process within the thread
{
serverObject.p.CancelErrorRead();
serverObject.p.CancelOutputRead();
serverObject.p.CloseMainWindow();
serverObject.p.Refresh();
serverObject.p.Close();
serverObject.p.Kill();
serverObject.p.Dispose();
}
serverObject.PyScriptAsync(PyScriptThread).Dispose();
killPyThread(PyScriptThread); //kill the overarching thread
base.OnStop();
}
catch (Exception ex)
{
if (ex is IOException || ex is ThreadInterruptedException || ex is ThreadAbortException || ex is InvalidOperationException)
{
StreamWriter errorSW = new StreamWriter(#"C:\Users\bakere1\A19149\Projects\text_doc.txt", true);
errorSW.Write("Error occurred: Stacktrace/Message/Source", ex.StackTrace, ex.Message, ex.Source);
errorSW.Close();
}
}
}
//-------------------------------------------------------------------------
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public void killPyThread(Thread thread)
{
thread.Interrupt();
thread.Abort();
}
}
public class ServerClass
{
public event System.EventHandler serviceChanged;
public Process p;
//-------------------------------------------------------------------------
public async Task PyScriptAsync(Thread thread)
{
await Task.Delay(10000).ConfigureAwait(false);
thread.Start();
}
public void PyScript()
{
string fileName = #"C:\Users\bakere1\A19149\Projects\BLE_Advertiser.py";
p = new Process
{
StartInfo = new ProcessStartInfo(#"C:\Python36_64\python.exe", fileName)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = false
}
};
p.Start();
p.WaitForExit();
p.CancelErrorRead();
p.CancelOutputRead();
p.CloseMainWindow();
p.Refresh();
p.Close();
p.Kill();
p.Dispose();
return;
}
//-------------------------------------------------------------------------
protected virtual void onServiceChanged()
{
serviceChanged?.Invoke(this, EventArgs.Empty);
}
}
}
PowerShell 4.0
I want to host PowerShell engine in my application and to have the capability of using API of my application in the hosted PowerShell. I read the description of the PowerShell class and its members in the documentation. In the PowerShell.exe and PowerShell_ISE.exe hosts I can to create the variables, loops, launch the static and instance methods of my classes. Can I do the same through the PowerShell class? I can't find the the examples about it.
It is my simple attempt to do it:
using System;
using System.Linq;
using System.Management.Automation;
namespace MyPowerShellApp {
class User {
public static string StaticHello() {
return "Hello from the static method!";
}
public string InstanceHello() {
return "Hello from the instance method!";
}
}
class Program {
static void Main(string[] args) {
using (PowerShell ps = PowerShell.Create()) {
ps.AddCommand("[MyPowerShellApp.User]::StaticHello");
// TODO: here I get the CommandNotFoundException exception
foreach (PSObject result in ps.Invoke()) {
Console.WriteLine(result.Members.First());
}
}
Console.WriteLine("Press any key for exit...");
Console.ReadKey();
}
}
}
There are two problems in your code:
You need to make User class public, to be visible to PowerShell.
You should use AddScript instead of AddCommand.
This code will call two methods of User class and print resulting strings to console:
using System;
using System.Management.Automation;
namespace MyPowerShellApp {
public class User {
public static string StaticHello() {
return "Hello from the static method!";
}
public string InstanceHello() {
return "Hello from the instance method!";
}
}
class Program {
static void Main(string[] args) {
using (PowerShell ps = PowerShell.Create()) {
ps.AddScript("[MyPowerShellApp.User]::StaticHello();(New-Object MyPowerShellApp.User).InstanceHello()");
foreach (PSObject result in ps.Invoke()) {
Console.WriteLine(result);
}
}
Console.WriteLine("Press any key for exit...");
Console.ReadKey();
}
}
}
This question already has answers here:
Checking if my Windows application is running
(9 answers)
Closed 8 years ago.
I tried to do it this way:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using DannyGeneral;
namespace mws
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
try
{
if (IsApplicationAlreadyRunning() == true)
{
MessageBox.Show("The application is already running");
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
catch (Exception err)
{
Logger.Write("error " + err.ToString());
}
}
static bool IsApplicationAlreadyRunning()
{
string proc = Process.GetCurrentProcess().ProcessName;
Process[] processes = Process.GetProcessesByName(proc);
if (processes.Length > 1)
{
return true;
}
else
{
return false;
}
}
}
}
But I'm getting some problems.
First, when I'm loading my project in Visual Studio and then running my program it's detecting the vshost.exe file of my project for example: My project.vshost
And I want that it will detect if my program is running only when I'm running the program only if it find the .exe for example: My project.exe not the vshost.
Have a look at using a mutex.
static class Program {
static Mutex mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}");
[STAThread]
static void Main() {
if(mutex.WaitOne(TimeSpan.Zero, true)) {
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
finally
{
mutex.ReleaseMutex();
}
} else {
MessageBox.Show("only one instance at a time");
}
}
}
If our app is running, WaitOne will return false, and you'll get a message box.
As #Damien_The_Unbeliever pointed out correctly, you should change the Guid of the mutex for each application you write!
Source: http://sanity-free.org/143/csharp_dotnet_single_instance_application.html
Could you please try below snippet?
private static void Main(string[] args)
{
if (IsApplicationAlreadyRunning())
{
Console.Write("The application is already running");
}
else
{
Console.Write("The application is not running");
}
Console.Read();
}
static bool IsApplicationAlreadyRunning()
{
return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
}
Why this work:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronRuby;
class Tutorial
{
static void Main(string[] args)
{
var engine = Ruby.CreateEngine();
engine.Runtime.Globals.SetVariable("Holly",new Holly("Test"));
engine.Execute("Holly.Say");
Console.ReadLine();
}
}
class Holly
{
string speech;
public Holly(string speech)
{
this.speech = speech;
}
public void Say()
{
Console.WriteLine("Hollu said " + this.speech);
}
}
and this is not work
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronRuby;
class Tutorial
{
static void Main(string[] args)
{
var engine = Ruby.CreateEngine();
engine.Runtime.Globals.SetVariable("Mouse",new Holly("Test"));
engine.ExecuteFile("./test.rb");
Console.ReadLine();
}
}
class Holly
{
string speech;
public Holly(string speech)
{
this.speech = speech;
}
public void Say()
{
Console.WriteLine("Hollu said " + this.speech);
}
}
Try this
engine.ExecuteFile(#"..\test.rb");
Also wrap your code in try/catch statement and check for exception
try
{
var engine = Ruby.CreateEngine();
engine.Runtime.Globals.SetVariable("Holly",new Holly("Test"));
engine.ExecuteFile(#"..\test.rb");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
I am recently writing a wiimote program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
namespace WiiTester
{
public partial class Form1 : Form
{
Wiimote wm = new Wiimote();
public Form1()
{
InitializeComponent();
wm.WiimoteChanged += wm_WiimoteChanged;
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;
wm.Connect();
wm.SetReportType(InputReport.IRAccel, true);
}
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
if (args.Inserted)
{
wm.SetReportType(InputReport.IRExtensionAccel, true);
}
else
{
wm.SetReportType(InputReport.IRAccel, true);
}
}
}
}
My wiimote keeps getting disconnected and this error keeps running on wm.Connect();
Timed out waiting for status report
Is there a solution?
I have a lot of experience with this library, and your problem is most likely being caused because you are calling SetRumble so often, this code:
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
Will call SetRumble constantly whether A is down or not, consider using this code instead:
bool rumbleOn = false;
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
bool newRumble = (ws.ButtonState.A == true);
if (rumbleOn != newRumble)
{
rumbleOn = newRumble;
wm.SetRumble(rumbleOn);
}
}
This way the set rumble method is only called when required and not constantly sending output reports to the WiiMote which causes the Bluetooth BUS to overload.