Determining type of running application (.NET) - c#

How can I determine if the running application is a Windows Forms or a Console application?

You can't do this reliably. For example, start a new project from the Windows Forms Application project template. Project + Properties, change Output Type to "Console Application". Press F5 to see what that looks like. While every reasonable test will say it is a console mode application, it is very much a WF app.
The opposite is true as well, merely the presence of System.Windows.Forms.dll doesn't make it a WF app. A console app might use it to display a MessageBox for example.
Furthermore, it could be neither. Your code might be called by a service.
Punt this problem, the author of the app never has a problem telling you what your code should do. Add a property to your class to allow her to do so.

p/invoke:
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
Struct:
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=80)]
public string szTypeName;
}
Method:
private static bool IsWindowsApplication(string fileName)
{
SHFILEINFO psfi = new SHFILEINFO();
switch (((int) SHGetFileInfo(fileName, 0, ref psfi, (uint) Marshal.SizeOf(psfi), 0x2000)))
{
case 0:
return false;
case 0x4550:
return false;
case 0x5a4d:
return false;
}
return true;
}
If the above method returns false, it's a console application.
-Oisin

If it doesn't need to be done programmatically you could maybe use a program like ProcessExplorer and see if the System.Winforms.dll is loaded. I don't think this is foolproof but it may be a start.

One option might be to check if System.Windows.Forms.Application.OpenForms contains any elements.
Another option might be to check whether Console.Title or Console.WindowTop throws an exception (it would if no console window is open).
EDIT
However, note that an application may have a console window and a form open at the same time... What kind of application is it then?

Related

Preventing Lock screen from Console Application [duplicate]

I am writing an application in C# that plays a movie. I need to figure out how to disable the screen saver and power options using C#.
I know the Windows SDK API has a function called SetThreadExecutionState() which can be used to do this, however, I do not know if there is a better way to do it. If not, how do I incorporate this function into C#?
Not sure if there is a better .NET solution but here is how you could use that API:
The required usings:
using System.Runtime.InteropServices;
The P/Invoke:
public const uint ES_CONTINUOUS = 0x80000000;
public const uint ES_SYSTEM_REQUIRED = 0x00000001;
public const uint ES_DISPLAY_REQUIRED = 0x00000002;
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetThreadExecutionState([In] uint esFlags);
And then disable screensaver by:
SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED);
Finnaly enable screensaver by reseting the execution state back to original value:
SetThreadExecutionState(ES_CONTINUOUS);
Note that I just picked one of the flags at random in my example. You'd need to combine the correct flags to get the specific behavior you desire. You will find the description of flags on MSDN.

Refresh Desktop in C# on Win7 like 'F5' would have been pressed to apply explorer settings

I would like to have a function to refresh the desktop like pressing "F5" does. I found many codes with Sendmessage and ToggleDesktopIcons on/off but none worked for me like manual hit of "F5" does. I saw also some topics here, but all with non-working solutions for this matter.
I am on Windows 7 64 Bit with IE 10 and use C# Net Framework 2.
I found also this code, but C# doesn't accept it, even if it seems to me as the right function.
I dunno what I need to change here. I would expect that the IDE would tell me what is my mistake here or what I need to correct. Can someone please correct me this function or suggest another function which is compatible to C#.
procedure RefreshDesktop2;
var
hDesktop: HWND;
begin
hDesktop := FindWindowEx(FindWindowEx(FindWindow('Progman', 'Program Manager'), 0,
'SHELLDLL_DefView', ''), 0, 'SysListView32', '');
PostMessage(hDesktop, WM_KEYDOWN, VK_F5, 0);
PostMessage(hDesktop, WM_KEYUP, VK_F5, 1 shl 31);
end;
Question:
How do I make the code above working in C# (translate in C#) or how looks a similar code in C# like.
Refreshing the desktop with its icons/settings like by pressing "F5" on a selected desktop icon is my goal. Several codes which I tried in similar questions brought me no result.
OK, I don't really understand your code, in fact you have to find the exact window to send the F5 keypress to it so that it will refresh the desktop. Here is the c# code (tested and worked like a charm:)
[DllImport("user32")]
private static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32")]
private static extern IntPtr FindWindow(string className, string caption);
[DllImport("user32")]
private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr startChild, string className, string caption);
public void RefreshDesktop(){
IntPtr d = FindWindow("Progman", "Program Manager");
d = FindWindowEx(d, IntPtr.Zero, "SHELLDLL_DefView", null);
d = FindWindowEx(d, IntPtr.Zero, "SysListView32", null);
PostMessage(d, 0x100, new IntPtr(0x74), IntPtr.Zero);//WM_KEYDOWN = 0x100 VK_F5 = 0x74
PostMessage(d, 0x101, new IntPtr(0x74), new IntPtr(1 << 31));//WM_KEYUP = 0x101
}
However I think there are still other choices for you to refresh the desktop programmatically, here is one of the links How to refresh the windows desktop programmatically (i.e. F5) from C#?

how to use ORIYA font in smart device development?

I am developing an application for WINDOWS CE5.0 based device. It requires ORIYA language(INDIAN REGIONAL LANGUAGE) to be used completely. As visual studio use ENGLISH as standard language, please tell me how to proceed? I tried to copy the font in WINDOWS CE device's WINDOWS/FONTS folder but as i restart the device that font file disappears. I developed the application in c# and changed labels text into oriyaa in Development system. It looks fine on the development system but as i deployed it into device, All label text appears in ENGLISH. I dont know whats happening? I also need to set the LABEL.TEXT property in ORIYA language. Is it possible? How to take user input in ORIYA? Please help..... Thanks...
Not very sure as what you meant by browser but for the Forms you can go about using PrivateFontCollection
you can load the font from a folder in your app and then use
AddFontFile or AddMemoryFont as per your need. So now the Client can see the controls in the font you set and its available to it irrespective of its installed or not
I have used the following approach with English-based fonts, but I am not sure if it will work on your case. The original source of this approach is a nice post from Chris Tacke (SO user #ctacke) with some modifications.
[DllImport("coredll.dll")]
private static extern int AddFontResource(string lpszFilename);
[DllImport("coredll.dll", SetLastError = true)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
static IntPtr HWND_BROADCAST = (IntPtr)0xFFFF;
const int WM_Fontchange = 0x001D;
private static void RegisterFont(string aFontPath, string aTargetFontPath)
{
IntPtr thir = (IntPtr)0;
IntPtr fourth = (IntPtr)0;
try
{
if (!System.IO.File.Exists(aTargetFontPath))
System.IO.File.Copy(aFontPath, aFontTargetPath);
}
catch { throw; }
int _Loaded = AddFontResource(aFontTargetPath);
if (_Loaded != 0)
SendMessage(HWND_BROADCAST, WM_Fontchange, thir, fourth);
}

P/Invoke problems with basic CRT functions (i.e., putchar, puts)

I've noticed something very strange. I was trying to call the CRT function "putchar", and was unable to get it to work. So I double-checked that I wasn't missing something, and I copied the code directly from the P/Invoke tutorial on MSDN to see if it worked.
http://msdn.microsoft.com/en-us/library/aa288468%28VS.71%29.aspx
You'll notice that they import "puts".
So I tested the exact code copied from MSDN. It didn't work! So now I got frustrated. I've never had this problem before.
Then I just so happened to run WITHOUT debugging (hit ctrl+f5), and it worked! I tested other functions which output to the console too, and none of them work when debugging but all work when not debugging.
I then wrote a simple C dll which exports a function called "PrintChar(char c)". When I call that function from C#, it works even if I'm debugging or not, without any problems.
What is the deal with this?
The Visual Studio hosting process is capable of redirecting console output to the Output window. How exactly it manages to do this is not documented at all, but it gets in the way here. It intercepts the WriteFile() call that generates the output of puts().
Project + Properties, Debug tab, untick "Enable the Visual Studio hosting process". On that same page, enabling unmanaged debugging also fixes the problem.
It's a bad example, using the C-Runtime Library DLL to call puts. Keep reading the tutorial as there is good info there, but try making Win32 API calls instead.
Here is a better introduction to p/invoke: http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
It's old, but the information is still good.
Edited
My explaination was wrong.
I went looking for a correct explaination and I discovered that the C-Runtime puts method and the .NET Framework Console.Write method differ in how they write to the console (Console.Write works where the p/invoke to puts does not). I thought maybe the answer was in there, so I whipped up this demonstration:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
class Program
{
public static void Main()
{
int written;
string outputString = "Hello, World!\r\n";
byte[] outputBytes = Encoding.Default.GetBytes(outputString);
//
// This is the way the C-Runtime Library method puts does it
IntPtr conOutHandle = CreateFile("CONOUT$", 0x40000000, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
WriteConsole(conOutHandle, outputBytes, outputString.Length, out written, IntPtr.Zero);
//
// This is the way Console.Write does it
IntPtr stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
WriteFile(stdOutputHandle, outputBytes, outputBytes.Length, out written, IntPtr.Zero);
// Pause if running under debugger
if (Debugger.IsAttached)
{
Console.Write("Press any key to continue . . . ");
Console.ReadKey();
}
}
const int STD_OUTPUT_HANDLE = -11;
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern int WriteFile(IntPtr handle, [In] byte[] bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr CreateFile(string lpFileName, int dwDesiredAccess, FileShare dwShareMode, IntPtr securityAttrs, FileMode dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
static extern bool WriteConsole(IntPtr hConsoleOutput, [In] byte[] lpBuffer, int nNumberOfCharsToWrite, out int lpNumberOfCharsWritten, IntPtr mustBeZero);
}
Both of those successfully output under the debugger, even with the hosting process enabled. So that is a dead end.
I wanted to share it in case it leads someone else to figuring out why it happens -- Hans?

Running executable from memory

I'm trying to run an executable directly from a byte[] representation of this executable as a resource in C#.
So basically i want to run a byte[] of an PE directly without touching the harddisk.
The code I'm using for this used to work but it doesn't anymore.
The code creates a process with a frozen main thread, changes the whole process data and finally resumes it so it runs the byte[] of the PE. But it seems like the process dies if the thread is resumed, i don't really know whats wrong.
So here is the code in a pastebin because its too long for here i guess...
http://pastebin.com/18hfFvHm
EDIT:
I want to run non-managed code !
Any PE File ...
Here is some code to execute native code (inside a byte array). Note that it is not exactly what you are asking for (it's not a PE file bytes, but a native procedure bytes ie. in assembly language)
using System;
using System.Runtime.InteropServices;
namespace Native
{
class Program
{
private const UInt32 MEM_COMMIT = 0x1000;
private const UInt32 PAGE_EXECUTE_READWRITE = 0x40;
private const UInt32 MEM_RELEASE = 0x8000;
[DllImport("kernel32")] private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
[DllImport("kernel32")] private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType);
[DllImport("kernel32")]
private static extern IntPtr CreateThread(
UInt32 lpThreadAttributes,
UInt32 dwStackSize,
UInt32 lpStartAddress,
IntPtr param,
UInt32 dwCreationFlags,
ref UInt32 lpThreadId
);
[DllImport("kernel32")] private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32")] private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);
static void Main(string[] args)
{
byte[] nativecode = new byte[] { /* here your native bytes */ };
UInt32 funcAddr = VirtualAlloc(0, (UInt32)nativecode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Marshal.Copy(nativecode, 0, (IntPtr)(funcAddr), nativecode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
CloseHandle(hThread);
VirtualFree((IntPtr)funcAddr, 0, MEM_RELEASE);
}
}
}
This code may help:
Dynamic Process Forking of Portable Executable by Vrillon / Venus:
http://forum.gamedeception.net/threads/16557-Process-Forking-Running-Process-From-Memory
Leaving this here for everyone.
USE RUNPE
Look it up, works great :) I suggest self inject.
i found that sample, hope it will be useful for you.
http://www.cyberhackers.mybbnew.com/showthread.php?tid=178
I haven't tried this, so it's purely specutive, but I believe you want to load in into the AppDomain:
byte[] myAssm = ...
AppDomain.CurrentDomain.Load(myAssm);
AppDomain.CurrentDomain.ExecuteAssemblyByName(nameOfMyAssm);
I'm not sure if this will be much help, but here is where I answer running straight x86/x64 assembly opcodes from a C# program.
I believe your problem is that you are asking for a security hole.
To run any PE, you are asking -- "Let my secure/managed .NET app run an insecure/unmanaged app -- In a way which bypasses normal security".
Let's say I run you application (which I assume is secure). I've not given it permission to write to sensitive folder; it can't overrun buffers; it can't touch my win32 mode code. You then build, byte-by-byte, a malicious application in a byts[], and launch that. Where does Windows step in to ask me if I want to let this happen? And what does that warning say ? "Is that array of bytes from a trusted source?"
In theory, if you are running full trust, there is nothing stopping you from doing CreateProcess on rundll32.exe, unmapping rundll32.exe, and performing the initial EXE load yourself.
The way I'd go about it is inject a thread into the target process that does the work in an unmanaged way. Yes, this means piles of relocatable assembly.
The general idea is to call LdrUnloadModule to get rid of rundll32.exe, call LdrLoadModule to load the EXE, fixup the load chain to indicate it was loaded first, then restart the main thread.
Good luck to you.
Repost of Load an EXE file and run it from memory
Not tested but looks like to be the only way to do this (2nd answer)

Categories