I'm not sure how to phrase this question so please bear with me.
I am creating a sandbox to run .exes with different privileges. Basically I'm building on the example in this article: https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspx
Prior to the re-design I'm about to mention, my project had a console application output type (Project->Properties->Application->Output type) despite the fact it was mainly a WPF project. This resulted in both a console window and my GUI being displayed on commencement of the program.
When running a console application IN the sandbox, the output would be written to the already open console window and not create another tied to the .exe under test. I'm trying to avoid this and would prefer my output type to remain as a windows application to prevent a needless console window being open.
As far as I can tell, the issue stems from this line of code:
target.EntryPoint.Invoke(null, parameters);
This runs the Main(string[] args) method in my .exe under test, however it doesn't spawn its own console window and errors follow swiftly. Is there some way to create a console window and attach the spawned process to it?
Thanks, edits and questions welcome
P.S. With the output type being set to console application, other output types (e.g. forms and wpf projects) load their respective GUIs perfectly fine.
The answer to my problem involves using pInvoke in order to use some of the kernal32 api. Adding these DLLImports:
[DllImport("kernel32.dll")]
static extern int AllocConsole();
[DllImport("kernel32.dll")]
static extern int FreeConsole();
These allow me to allocate a console to a process I'm about to launch and I can leave my project as a windows application. All that needs to happen is to enclose my invoke in between Alloc and Free.
As such:
AllocConsole();
var trythis = target.EntryPoint.Invoke(null, parameters);
FreeConsole();
Related
I realize this sort of question has been asked before, but I have a very specific (and a rather complicated) case that is subtly different, so the usual solutions either do not work or do not apply.
Basically, I have a console app which is launched by a VSIX debugger launcher. The purpose of this app is to load a hosted DLL, establish the appropriate environment, and allow debugging of the DLL's source code from Visual Studio the same way a normal C# project would be debugged. The difference is that this project is not an executable, but a library, and so it needs a host (i.e. the console app in question). It's all very similar to how ASP.NET projects work with IIS/IIS Express - it's just that I wrote a custom host and I manage its launching from my custom VSIX.
The custom host app is a .NET Core Console app and the debugger launches it without any windows. This is deliberate, since it needs no interactive input and all output is redirected to the Visual Studio's debugger session (i.e. the Events tab).
The app is also generic, so it can't know the name of the debugged project until it's actually started. On top of that, I can have multiple instances of Visual Studio debugging multiple different projects at the same time!
I would really like to ease differentiation of these processes in Task Manager, so that they each showed as the name of the specific DLL project that is being hosted in each respective instance. My attempts so far have been:
// 1. This crashes with InvalidOperationException because there is no window.
Console.Title = loadedDllProjectName;
// 2. This doesn't crash, but has no effect, either.
[DllImport("user32.dll")]
static extern int SetWindowText(IntPtr hWnd, string text);
...
SetWindowText(Process.GetCurrentProcess().MainWindowHandle, loadedDllProjectName);
FWIW, the Task Manager shows the process under its default image name and lists it among background processes. The latter is fine and expected. But I would like to change the former. How?
UPDATE
According to this, my pursuit might sadly be hollow. Still hoping for an encouraging hint, though!
I've made a Launcher for my game, and the launcher auto-download and patches the game.
But, how can I check if the game has been launched by the Launcher? Is there a way to do it without using Command Line Arguments?
If your launcher is .net application, you can start your application not from command line, but by calling Main() function (from exported class).
If your launcher is not .net application and your application works on Windows only, then you can try to find launcher's window (using FindWindow function) from main application, send message using SendMessage WinApi function, and check result.
These articles might be usefull:
Importing .net classes
Finding windows
Sending messages
Importing dll functions
Currently I have two separate C# projects under the same solution, let's call it Window.exe and Console.exe. Window.exe is a WPF MVVM application that works well standalone.
To eliminate one small issue, my goal is to convert Window.exe into Window.dll, and then use Console.exe to load Window.dll. I tried to call App.Run(), or move the routine in App_Startup, that is used to launch the main window onto a separate method and called it. The new thread that runs Window.dll couldn't really last. It was able to populate the GUI when I stepped into it in debug, but I could not interact with it.
Any ideas on how I should proceed?
I was able to accomplish this by doing two things:
You need to mark the Main method in your console applicaiton as an STAThread method because the UI will need to be on an STA thread. If you don't, you'll get an exception when the constructor for the main window is called.
Make sure you also call InitializeComponent() before Run(). If you don't, the app will run, but the window won't have been set up first.
I was able to get this to work in a solution where I, as well, have a WPF main application and console application for testing things:
[STAThread]
static void Main(string[] args)
{
WpfApp.App app = new WpfApp.App();
app.InitializeComponent();
app.Run();
}
I searched the web and Stackoverflow, I didn't find anything.
I am sorry if this question already exists.
If my C# application is called through the cmd for example:
C:\System32\MyConsoleApplication -parmOne -paramTwo ...
Is there a way to write into the cmd (for example to giving progressinformation?)
Edit: Cause I use a Consoleapplication the solution ist Console.WriteLine It doesnt worked for me cause my application requires adminrights (trough a Manifestfile) and was called with normal userrights. In this case the UAC asks for rights and opens a new Cmd with the application.
better solution : http://www.nerdyhearn.com/blog/157/
here is the code of the site:
[DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);
private const int ATTACH_PARENT_PROCESS = -1;
[STAThread]
static void Main(string[] args)
{
// Enable visual elements just like always
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Attach to the parent process via AttachConsole SDK call
AttachConsole(ATTACH_PARENT_PROCESS); // <-- important point here
Console.WriteLine("This is from the main program");
Application.Run(new Form1());
}
You can use the AttachConsole call at your will in the special conditions you need. This is much better and flexible and does not require you to change your application manifest. if its a win32 app, wll good for your app. if its launched from a cmd then the output will appear as excpected.
My opinion: this is just some useless microsoft complication of some concepts that are so pure and natural in the Unix world. If your application is launched from a visual launcher (icon, nautilus..) then the output is lost. You can launch your app from a console and its gets in the console. you can redirect the output if you need, it all imbricates logically and its powerful. With microsoft... its bloated and gets in the way of everybody.
This all depends on what the exe type is - which is a flag in the PE-header (the "exe" shell):
if it is flagged as a windows app, it doesn't get a console / output to the existing console - regardless of how it is started
if it is flagged as a console app, it does get a console / output to the existing console - regardless of how it is started
It cannot be both. It you want it to work like a windows exe normally, then you will have to compile it as a windows exe, which means no: it won't write to the console normally. Trying to acquire access to the console from a windows exe is tricky, and would require P/Invoke to the OS.
If it is flagged as a console exe, then just Console.WriteLine will work fine.
Hey,
This issue was addressed before but not in this angle. I'm trying to control a Python application with C#. The application runs an unknown time and I need to hold the main C# application form until It "knows" when the Python application is done processing.
I should mark that the Python Application has its own GUI which i'm trying to keep.
So far, I've used:
ProcessStartInfo processStart= new System.Diagnostics.ProcessStartInfo(#app);
processStart.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
processStart.UseShellExecute = false;
processStart.RedirectStandardOutput = true;
processStart.CreateNoWindow = true;
Process myProcess = Process.Start(processStart);
Then I send a couple of "SendKey" methods including some TAB and ENTER.
Furthermore, as you can probably infer from the code I'm trying to make the entire Python process hidden – I did succeed in open\close the Python application but didn't succeed in controlling it at all. Any suggestions?
Redirect stdin and the push characters in that way (rather than sendkeys)?
Have you looked into IronPython - it allows you to execute python code from within you .NET application natively.
SendKeys can only send keystrokes to the active application. Since you are forcing it to start without creating a window it can't receive the SendKeys.Send() messages. It sounds like what you really want is to use the functionality of the python code without presenting any UI from that application to your users.
You could approach this in one of 2 ways:
My first reccommendation is that you write a simple python script that imports the application you are trying to use, and invokes the functions inside the app that you need.
IF that won't work for you, you could allow the window to be created, then instantly set your application to be the foreground window using:
[DllImport("User32.dll")]
public static extern Int32 SetForegroundWindow(int hWnd);
public void ForceToFront()
{
SetForegroundWindow(Handle.ToInt32());
}
then you could send keys to the now background window using Win32 APIs. There's a pretty good (although fairly old) example here: http://www.codeproject.com/KB/cs/SendKeys.aspx