Executable behaving differently when run through WMI compared to run locally - c#

I have the following c sharp file compiled as an executable.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.IO;
using System.Threading;
namespace Foreground {
class GetForegroundWindowTest {
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
public static void Main(string[] args){
while (true){
IntPtr fg = GetForegroundWindow(); //use fg for some purpose
var bufferSize = 1000;
var sb = new StringBuilder(bufferSize);
GetWindowText(fg, sb, bufferSize);
using (StreamWriter sw = File.AppendText("C:\\Office Viewer\\OV_Log.txt"))
{
sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd_HH:mm:ss,") + sb.ToString());
}
Thread.Sleep(5000);
}
}
}
}
When I run this executable on a local machine it yields both the date and the name of the current window.
when I run this executable from a remote machine using wmi it yields date and the name of the current window is blank, which I assume means that it returns null. Does anyone have a fix for this?
The program which runs the wmi executable is written in python, and is of the form:
import wmi
IP = '192.168.165.x'
USERNAME = 'username'
PASSWORD = 'password'
REMOTE_DIR = 'c:\ ... \'
remote_pc = wmi.WMI (IP, user = USERNAME, password = PASSWORD)
exe_remote_path = join (['\\\\', IP, '\\', REMOTE_DIR, filename)
remote_pc.Win32_Process.Create (CommandLine = exe_remote_path)

This may be the issue.....
For security reasons the Win32_Process.Create method cannot be used to start an interactive process remotely.
from msdn

Related

I have an error "Dll load error" while using Hybridizer in C#

I am using Hybridizer for the first time. I am using Windows 10, Visual Studio 2019, CUDA 10.1 and Hybridizer 1.3.0 "Released Sep. 5th 2019". Although I have followed their steps, I keep getting the same error:
Dll load error when loading Hello_World_CUDA.dll: 126
whenever I try to make any simple code to test it like this:
using System;
using Hybridizer.Runtime.CUDAImports;
public class Hello_World
{
[EntryPoint]
public static void Hello()
{
Console.Out.Write("Hello from GPU");
}
static void Main()
{
cuda.DeviceSynchronize();
HybRunner runner = HybRunner.Cuda().SetDistrib(1, 2);
runner.Wrap(new Hello_World()).Hello();
}
}
even when using their examples without any change.
How can I solve this problem?
To troubleshoot please follow the three following steps:
Check file exists and can be loaded from current directory
Make sure dll can be loaded using LoadLibrary
Verify symbol can be found using GetProcAddress
To facilitate your investigation, please find below code to run these assertions
using System;
using System.IO;
using System.Runtime.InteropServices;
using Hybridizer.Runtime.CUDAImports;
public class Hello_World
{
[EntryPoint]
public static void Hello()
{
Console.Out.Write("Hello from GPU");
}
[DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", SetLastError = true)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string name);
[DllImport("kernel32.dll", EntryPoint = "FormatMessage", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int FormatMessage(int dwFlags, IntPtr lpSource, int dwMessageId, int dwLanguageId, [MarshalAs(UnmanagedType.LPArray)] char[] data, uint dwSize, IntPtr args);
[DllImport("kernel32.dll", EntryPoint = "GetProcAddress", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr GetProcAddress(IntPtr hModule, [MarshalAs(UnmanagedType.LPStr)] string symbol);
static unsafe string ErrorToString(int er)
{
char[] buffer = new char[2048];
int res = FormatMessage(0x00001000, // FORMAT_MESSAGE_FROM_SYSTEM
IntPtr.Zero, er,
0x0409, // US language -- in case of issue, replace with 0
buffer, 2048, IntPtr.Zero);
if (res == 0)
throw new ApplicationException(string.Format("Cannot format message - Error : {0}", res));
string resstring;
fixed (char* ptr = &buffer[0])
{
resstring = new string(ptr);
}
return resstring;
}
static void Main()
{
// Trouble-shooting
// print execution directory
Console.Out.WriteLine("Current directory : {0}", Environment.CurrentDirectory);
Console.Out.WriteLine("Size of IntPtr = {0}", Marshal.SizeOf(IntPtr.Zero));
// first, make sure file exists
string path = #"Troubleshooting_CUDA.dll"; // replace with actual dll name - you can read that on the output of the build
if (!File.Exists(path))
{
Console.Out.WriteLine("Dll could not be found in path, please verify dll is located in the appropriate directory that LoadLibrary may find it");
Environment.Exit(1);
}
// make sure it can be loaded -- open DLL in depends to missing troubleshoot dependencies (may be long to load)
IntPtr lib = LoadLibrary(path);
if (lib == IntPtr.Zero)
{
int code = Marshal.GetLastWin32Error();
string er = ErrorToString(code);
Console.Out.WriteLine("Dll could not be loaded : {0}", er);
Environment.Exit(2);
}
// finally try to get the proc address -- open DLL in depends to see list of symbols (may be long to load)
IntPtr procAddress = GetProcAddress(lib, "Hello_Worldx46Hello_ExternCWrapper_CUDA");
if (procAddress == IntPtr.Zero)
{
int code = Marshal.GetLastWin32Error();
string er = ErrorToString(code);
Console.Out.WriteLine("Could not find symbol in dll : {0}", er);
Environment.Exit(3);
}
cuda.DeviceSynchronize();
HybRunner runner = HybRunner.Cuda().SetDistrib(1, 2);
runner.Wrap(new Hello_World()).Hello();
}
}
If it fails at first step, you may need to change output directory of the CUDA satellite project, and/or execution directory of your application.
Should it fail at second step, you want to verify you execute in x64 (size of IntPtr should be 8), and that dll loads. Dependency walker, you may find here, is a great tool for this purpose, you want the x64 version. NOTE: loading may be very long.
Should it fail at third step, look-up the symbol name with depends, maybe your CUDA satellite project is not up to date.

Performing Key Output from C# to EuroTruck not working (PostMessage, user32.dll)

I am trying to get my C# script to output into ets2 so that it will drive for me (wasd). For testing I am using the space bar. I have tested the code in chrome and notepad, where it works and puts down a space. Would anyone know what is going wrong?
Update:
I wrote a little bit of test code for python using the keyboard module and I got it to work. Would it be possible to make "space" into a variable that I could change from C#?
Python Code:
import keyboard, time
time.sleep(5)
keyboard.press_and_release("space")
The Threads and Windows in Spy++:
I use the following code:
public const int WM_KEYDOWN = 0x0100;
const int VK_SPACE = 0x20;
static void Main(string[] args)
{
System.Threading.Thread.Sleep(2000); // gives user time to switch tabs
IntPtr programloc = WindowHelper.GetForegroundWindow();
// I also tried using (from Spy++) FindWindow("Euro Truck Simulator 2", "prism3d");
if (programloc == IntPtr.Zero) throw new SystemException();
WindowHelper.PostMessage(programloc, WM_KEYDOWN, VK_SPACE, 0);
}
and the following module WindowHelper (combination of multiple Stackoverflow and docs.microsoft pages):
class WindowHelper
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern IntPtr FindWindow(
string lpClassName,
string lpWindowName);
[System.Runtime.InteropServices.DllImport("User32.dll")]
public static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindos);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "GetForegroundWindow")]
public static extern IntPtr GetForegroundWindow();
}
Your code is exiting immediately. Is this intentional? Make a call to Console.Readline() at the end of main to block until you give the console input.
I have been able to find a (temporary) fix myself. This fix is however not very performance friendly. Anyone having better suggestions is welcome.
Using the keyboard function I described in my question, I made a python script which uses arguments. This python script is started by the C# script using the following code:
static public string run_python(string cmd, string args)
{
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = #"C:\Users\Stijn\AppData\Local\Programs\Python\Python36\python.exe";
start.Arguments = string.Format("\"{0}\" \"{1}\"", cmd,args);
start.UseShellExecute = false;// Do not use OS shell
start.CreateNoWindow = true; // We don't need new window
start.RedirectStandardOutput = true;// Any output, generated by application will be redirected back
start.RedirectStandardError = true; // Any error in standard output will be redirected back (for example exceptions)
using (Process process = Process.Start(start))
{
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Here are the exceptions from our Python script
string result = reader.ReadToEnd(); // Here is the result of StdOut(for example: print "test")
return result + stderr;
}
}
}
The python code consists of:
from keyboard import press_and_release
from sys import argv as args
for i in range(len(args)-1):
press_and_release(args[i+1])
Using the keyboard module as can be found at https://pypi.org/project/keyboard/

Getting the exact display name of the metro style apps

I am using PackageManager class to list the installed metro style applications in the system.
PackageId.Name does not return the actual name of the package, Neither is Package.DisplayName. Package.DisplayName returns empty string. It does return display name only for Package.Current.
When I tried to use AppxManifest.xml, I could not get the display name from
Package->Properties->Displayname too.
<Properties>
<DisplayName>ms-resource:///Resources/AppStoreName</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\WindowsIcons\StoreLogo.png</Logo>
</Properties>
Where can I get the exact display name of metro style applications ?
If you already have a reference to a Package instance, you can get the Display Name using an interop method and the registry. Here's a complete example:
using Microsoft.Win32;
using System;
using System.Runtime.InteropServices;
using System.Text;
using Windows.ApplicationModel;
public class PackageUtil
{
[DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode,
ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
private static extern int SHLoadIndirectString(string pszSource,
StringBuilder pszOutBuf, int cchOutBuf, IntPtr ppvReserved);
private static string GetPackageDisplayName(Package package)
{
using (var key = Registry.ClassesRoot.OpenSubKey(
#"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel" +
$#"\Repository\Packages\{package.Id.FullName}\App\Capabilities"))
{
var sb = new StringBuilder(256);
Shlwapi.SHLoadIndirectString((string)key.GetValue("ApplicationName"),
sb, sb.Capacity, IntPtr.Zero);
return sb.ToString();
}
}
}

Executing Commands to External Linux Server via SharpSSH

I am trying to communicate with a remote Linux machine using the Tamir.SharpSSH library. I have been able to establish the connection, and submit the commands. However, I need to press enter twice to see the response from the server.
This is the code I am using:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tamir.SharpSsh;
namespace SshMultipleConsoles
{
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AllocConsole();
[DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);
private const int ATTACH_PARENT_PROCESS = -1;
[STAThread]
static void Main()
{
AllocConsole();
AttachConsole(ATTACH_PARENT_PROCESS);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 x = new Form1();
Application.Run(x);
x.Close();
SshExec ssh = null;
SshStream ssh2 = null;
try
{
Console.Write("-Connecting...");
ssh2 = new SshStream(host, username, password);
ssh2.Prompt = "\n";
ssh2.RemoveTerminalEmulationCharacters = true;
Console.Write(ssh2.ReadResponse());
while (true)
{
string command = Console.ReadLine();
if (command == "exit")
break;
ssh2.Write(command);
ssh2.ReadResponse(); // UPDATE
string data = ssh2.ReadResponse();
Console.Write(data);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
if (ssh2 != null)
{
Console.WriteLine("Disconnecting...");
ssh2.Close();
Console.WriteLine("OK");
}
Console.Write("Press any key to continue...");
}
}
}
Here is the output I am getting:
As you can see, I type the "ls" command, and press enter. Nothing returns. I press enter again, and I see the command that was submitted along with the files in the folder. I am not sure what I am doing wrong.
UPDATE
I found out that if I run the ssh2.ReadResponse() command twice, this does not occur. This is telling me that when I run the ls command, I get back 2 responses? However, when I run "cd.." this command stalls (since I believe there is no second response). I am not sure how this is working.

Help using PInvoke CreateDirectory () in C#

I'm using C# for WinForms app in VS2010 and I needed to create a directory in which the path was too large for the .NET methods (248 char limit, I believe) and ran across suggestions from google to use the Unicode Win32 CreateDirectory(). I had initially tried calling it using Unicode and passed parameters but after several failed attempts, I've reduced the code and am using EXACTLY the code found here:
http://www.pinvoke.net/default.aspx/Structures/SECURITY_ATTRIBUTES.html
I am still getting the same error:
System.AccessViolationException was caught
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Admittedly, I don't know anything about calling the Win32 functions, I'm really just pulling what I can find online and trying to learn. Can anyone tell me what I'm doing wrong? Removing non-essential code for the question, I have:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Text;
namespace RFCGenerator
{
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
public class RFC
{
[DllImport("kernel32.dll")]
static extern bool CreateDirectory(string lpPathName, SECURITY_ATTRIBUTES lpSecurityAttributes);
protected void CopyDirectory(Uri Source, Uri Destination)
{
SECURITY_ATTRIBUTES lpSecurityAttributes = new SECURITY_ATTRIBUTES();
DirectorySecurity security = new DirectorySecurity();
lpSecurityAttributes.nLength = Marshal.SizeOf(lpSecurityAttributes);
byte[] src = security.GetSecurityDescriptorBinaryForm();
IntPtr dest = Marshal.AllocHGlobal(src.Length);
Marshal.Copy(src, 0, dest, src.Length);
lpSecurityAttributes.lpSecurityDescriptor = dest;
string path = #"C:\Test";
CreateDirectory(path, lpSecurityAttributes);
}
}
}
UPDATE: using Hans' suggestion, I did get this to work locally. However, when I attempt to create a directory using a UNC address, such as passing in:
path = #"\\mydomain.com\foo\bar\newfolder"
I now get:
System.ComponentModel.Win32Exception was caught
Message=The filename, directory name, or volume label syntax is incorrect
I have verified that \\mydomain.com\foo\bar\ does exist.
SOLUTION:
Using Hans' code and a minor modification to check if it's UNC path (reference: http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx, under "Maximum Path Length Limitation"):
string UnicodePath = (path.StartsWith(#"\\")) ? #"\\?\UNC\" + (path.Remove(0, 2)) : #"\\?\" + path;
if (!CreateDirectory(UnicodePath, IntPtr.Zero))
throw new System.ComponentModel.Win32Exception();
You are not using the Unicode version, that requires CharSet = CharSet.Unicode in the [DllImport] declaration. Furthermore, creating directories with long names has nothing to do with the security attribute. You have to prefix the name with #"\\?\". Thus:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool CreateDirectory(string lpPathName, IntPtr lpSecurityAttributes);
...
if (!CreateDirectory(#"\\?\" + path, IntPtr.Zero))
throw new Win32Exception();

Categories

Resources