wpf console application not returning to prompt - wpf

I've got a wpf "console" application with the following application class:
public partial class App : Application
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();
const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine("test1");
FreeConsole();
System.Environment.Exit(0);
}
}
When i start it from the console the text "test1" appears but then the console cursor just blinks and the prompt does not appear until I hit Enter. I did remove the StartupURI statement.
How to force the application to behave like a console app and return to prompt after the execution? (Windows 7 32 bit).

Instead of setting it as a Windows Application output, use a Console Application output type. The only drawback is that the console will stay open while the windows application is running. I suppose since you can get the processId of the console, you might be able to kill it after launch.

Related

SetForegroundWindow Windows 11 doesn't work

I use without problems a program that uses [SetForegroundWindow] in C# to bring the window to the foreground and activate in Windows 7 and Windows 10 operating systems, but now with Windows 11 it stopped working.
I need help, does anyone know how to be able to use SetForegroundWindow on Windows 11?
Site: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
//windows forms project
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//use
IntPtr janela = FindWindow(null, "Seleção de Cliente");
SetForegroundWindow(janela);

WPF application command line arguments instead of start GUI

I have WPF application and i want to add the option to do my stuff in commend line instead of open the GUI.
Any way to send my Application exe arguments and in case the arguments length in > 0 continue with command line instead of open the GUI ?
You could edit the App.xaml.cs file and override the OnStartup method:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
string[] args = e.Args;
if(args.Length > 0 && args[0] == "cl")
{
//...
}
else
{
base.OnStartup(e);
Window2 mainWindow = new Window2();
mainWindow.Show();
}
}
}
You should also remove the StartupUri attribute from <Application> root element of the App.xaml file.
But if you want to be able to write to the console you need to create a console window manually:
No output to console from a WPF application?
Then you might as well create a console application in Visual Studio and instead start your WPF application based on the command line argument(s), e.g.:
public class Program
{
public static void Main(string[] args)
{
if (args.Length == 0 || args[0] != "cl")
{
System.Diagnostics.Process.Start(#"c:\yourWpfApp.exe");
}
else
{
//...
}
}
}
A console application is not a WPF application and vice versa. So create two different applications.
In your App.xaml.cs implement the OnStartup method. So you can access the arguments passed via command line.
protected override void OnStartup(StartupEventArgs e)
{
var args = e.Args;
// do anything with arguments
}

Problems writing up WebBrowser COM events

I'm developing a project that needs to show HTML that is returned by a third party service. I am currently using a WPF WebBrowser to show this output. However this creates a potential security problem in the eyes of my customers. When focus is set to this control you can open any webpage by using CTRL+O or open Internet Explorer by using Ctrl+N. My application is targeted for a kiosk-like environment (Terminal Services).
In the past I've used the WinForms WebBrowser control and was able to sink into the events through COM, however those tactics don't seem to work with the WPF version. My development partners are adamant that we develop a pure WPF application instead of mixing in the WinForms option.
Has anyone had success getting to the IWebBrowserEvets2COM interface of the WPF WebBrowser? I have been able cast the WebBrowser.Document to an IWebBrowser, but haven't got to where I need.
Please help me tap into the events so that I can stop the user from creating new windows and other events that might cause "security" problems for my clients. Or is there a better control out there to do the rendering of HTML and basic navigation?
Thanks in advance,
Jerod
You can try to use Windows hooks here. Find browser window and install proper keyboard hooks for it. This externals should be helpful for you:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, IntPtr windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SetWindowsHookEx(Int32 idHook, HookProc lpfn, IntPtr hInstance, Int32 threadId);
And here is a sample how to use those, but you have to implement KeyboardHookProcedure according to your needs.
private IntPtr FindExplorerWindow()
{
IntPtr wnd = Browser.Handle;
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero);
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero);
return wnd;
}
}
return IntPtr.Zero;
}
private void InstallHook()
{
if (_hHook.ToInt32() > 0) return;
IntPtr wnd = FindExplorerWindow();
if (wnd != IntPtr.Zero)
{
if (_hookProc == null)
{
_hookProc = new HookProc(KeyboardHookProcedure);
}
_hHook = SetWindowsHookEx(WH_KEYBOARD, _hookProc, (IntPtr)0, GetCurrentThreadId());
}
}
Good luck!

WPF identify remote access (Not Winforms)

How can a WPF app know if its getting remotely operated (via VNC or remote desktop)?
In winforms there is System.Windows.Forms.SystemInformation.TerminalServerSession as per Detecting remote desktop connection but is there a strightforward way for this in WPF?
I guess the hack for now could be to have an invisible Winforms host on WPF and use its own capacity to host dummy win form that can identify the same... but that looks lame to me!
Any inputs would be appreciated!
Thx
I guess the hack for now could be to have an invisible Winforms host on WPF and use its own capacity to host dummy win form that can identify the same... but that looks lame to me!
You don't need an invisible WinForms host... you can just add a reference to the System.Windows.Forms assembly, and use the SystemInformation.TerminalServerSession static property.
If you don't want a dependency on WinForms, you can use the GetSystemMetrics Win32 API:
const int SM_REMOTESESSION = 0x1000;
[DllImport("user32")]
static extern int GetSystemMetrics(int nIndex);
public static bool IsTerminalServerSession()
{
return (GetSystemMetrics(SM_REMOTESESSION) & 1) != 0;
}
This method does not require a Windows Forms Window, only a reference to the DLL.
If you don't want to reference this, you can call the method to check this yourself, the implementation is as follows (I've wrapped it in a class):
static class SystemInformation
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern int GetSystemMetrics(int nIndex);
public static bool IsTerminalServerSession
{
get
{
//copied the Windows Forms implementation
return (GetSystemMetrics(0x1000) & 1) != 0;
}
}
}

Silverlight 3 - Out of browser HtmlPage.Window.Navigate

Silverlight 3 allows you to run your application out of the browser, which installs a link on your desktop/start menu.
The problem is we are currently using
System.Windows.Browser.HtmlPage.
Window.Navigate(new Uri("http://<server>/<resource>"), "_blank")
to load a URL into a new browser window (it's to provide a 'print friendly' page for users to print). This works in the normal SL in-browser version, but outside the browser we get 'The DOM/scripting bridge is disabled.' exception thrown when issuing the call.
Is there an alternative which works out of the browser?
I've seen Open page in silverlight out of browser but I need to do this entirely in code, so I don't want to add a (hidden) hyperlink button and then programmatically 'click' it (unless I absolutely have to...).
you can try inheriting from HyperlinkButton and exposing public Click() method (which you can then instantiate and call from code instead of declaring it in xaml).
Details here: http://mokosh.co.uk/post/2009/10/08/silverlight-oob-open-new-browser-window/
I wrote an Extension method based on the idea to inherit from the HyperlinkButton.
public static class UriExtensions {
class Clicker : HyperlinkButton {
public void DoClick() {
base.OnClick();
}
}
static readonly Clicker clicker = new Clicker();
public static void Navigate(this Uri uri) {
Navigate(uri, "_self");
}
public static void Navigate(this Uri uri, string targetName) {
clicker.NavigateUri = uri;
clicker.TargetName = targetName;
clicker.DoClick();
}
}
Then use can use it simple, like
new Uri("http://www.google.com").Navigate("_blank");

Resources