I have a console application which can also open winform under certain conditions.Processing(its a database export utility) and be done either through form or commandline. but the form is always associated with command prompt. i mean when i close the console the form get closed as well.My requirement is that when form is launched , the command prompt is closed by itself without closing the form.
[STAThread]
public static void Main(string[] args)
{
if(hastolaunchform)
{
Application.Run(new Form1());
}
else
{
Console.WriteLine("started");
try
{
dataclass.extract();
console.writeline("finish");
}
catch (Exception e)
{
Console.WriteLine("An error occur");
}
}
}
What you have here is an app that has a gui or not.
What you need is a gui version of it that optionally can be run from the CLI, ie it needs to be another exe, or the same exe with different command line parameters, though be careful with that, otherwise it could just keep launching another version of itself until windows dies.
At least I think that's what you are asking.
CLI arguments
MyApp.Exe --GUI
--GUI will apears in args[1].
So something like
if (args.Contains["--GUI"])
{
Application.Run(new Form1());
}
else
{
if (hastolaunchForm)
{
// use Process.start to run another version of your app with --GUI parameter
// and close
}
else
{
// do console stuff.
}
}
}
Related
I'm currently trying to get codename one working with some native code on windows phone. I created a "native demo" project where I changed the NativeCalls class to just support one simple method:
package com.codename1.nativedemo;
import com.codename1.system.NativeInterface;
public interface NativeCalls extends NativeInterface {
public String testString();
}
from this one i used the context menu item "Generate Native" and changed the NativeCallsImpl.cs file to return "windows phone" when testString is called. The last change I made is within the StateMachine:
protected void onGUI1_AddNativeButtonAction(Component c, ActionEvent event) {
super.onGUI1_AddNativeButtonAction(c, event);
try {
NativeCalls n = (NativeCalls) NativeLookup.create(NativeCalls.class);
if (n != null) {
if (n.isSupported()) {
Dialog.show("Got string", n.testString(), "OK", null);
} else {
Dialog.show("Error", "Platform not supported!", "OK", null);
}
} else {
Dialog.show("Error", "Native lookup returned null!", "OK", null);
}
c.getComponentForm().revalidate();
} catch (Throwable t) {
Dialog.show("Error", "Exception during native access: " + t, "OK", null);
}
}
the build works perfectly fine and it also runs on the simulator. But when I'm deploying the xap file on my phone (via WP Dev Tools, QR code doesn't work, shows "company app couldn't been installed), the app boots normally but shows that the NativeLookup returned null. The built .jar file from within the dist-directory contains the .cs file in the correct location (com/codename1/nativedemo/NativeCallsImpl.cs, right besides NativeCalls.class)
A null is returned by this lookup is an exception is thrown or something failed during creation.
I'm not 100% sure this works properly in the current Windows Phone port.
FYI The current Windows Phone port is deprecated and undergoing a complete rewrite.
I use this method to close my app:
public void quit()
{
if (NavigationService.CanGoBack)
{
while (NavigationService.RemoveBackEntry() != null)
{
NavigationService.RemoveBackEntry();
}
}
}
When I call it after pressing back key, the app closes as intended:
protected override void OnBackKeyPress(CancelEventArgs e)
{
quit();
}
But anywhere else I call this method, the stack is emptied but the app will not close.
If I try:
quit();
NavigationService.GoBack();
There will be a runtime error. If anybody can help me because I don't like to through an exception since it will be recorded as a bug in the marketplace statistics.
There is no need to clear the Navigation stack; if the application terminates the navigation stack will be gone. Do not worry about the user going forward; there is no forward key.
To remove the exception:
quit();
if( NavigationService.CanGoBack)
{
NavigationService.GoBack();
}
But before you do this, look at the code: what are you trying to accomplish? First you are cleaning out the stack and then you want to use the stack.
I have a link on my app UI that launches a URL using System.Diagnostics.Process.Start(). If the user clicks the link several times, it opens several tabs.
Is there a way, maybe a command-line option, to still use the default web browser, but have it just reopen the same tab if the URL is already open? It would be OK if it doesn't work with every possible browser out there, but nice if it at least works with IE, Firefox and Chrome.
I doubt it, but since I didn't see any other questions/answers on this topic, I figured I'd ask.
This is somewhat of a workaround but it might get you started. I have used the System.Diagnostics.Process.ProcessId.
As an example I have used IE, I will explain later why I did this. The code is just "quick and dirty" but I just made it as proof of concept.
I have created a basic WinForm app with one button that will open google in IE, if it has already been opened by the application it will not be opened again.
I added the System.Diagnostics reference.
public int ProcessID;
public Form1()
{
InitializeComponent();
}
private void MyButton_Click(object sender, EventArgs e)
{
if (ProcessID == null)
{
StartIE();
}
else
{
if (!ProcessIsRunning())
{
StartIE();
}
}
}
private bool ProcessIsRunning()
{
bool ProcessRunning = false;
foreach (Process p in Process.GetProcesses())
{
try
{
if (p.Id == ProcessID)
{
ProcessRunning = true;
}
}
catch { }
}
return ProcessRunning;
}
private void StartIE()
{
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "iexplore.exe";
proc.StartInfo.Arguments = "http://www.google.be";
proc.Start();
ProcessID = proc.Id;
}
This does not completely do what you requested but it might be a good start. There are a few reasons why I did it this way and what possible options are..
If you would use the url as the Filename, it would indeed open up the webpage in the default browser, it would however not return a processID. This is why the snippet shows usage of IE. (If you would use this option, you could use the System.IO.File.Exists to make sure the desired browser is installed)
If you would like to use this option, you can query the registry to pick up what te default browser is, if you have that you could launch that from the value obtained from the registry. If you then change the process.startinfo.filename to this value, then you will launch the default browser but you will still obtain a processId so this might be the way forward. You can check how to do this over here: http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/b200903e-ce69-4bd4-a436-3e20a7632dc4
Showing the internet window if it would already be opened, can be done by using the SetForegroundWindow property. As this is already documented in this article, I did not add it in this snippet.
I hope this helps to get you on your way.
My WIX installer launches an immediate custom action.
The custom action starts a WPF dialog prompting the user for a BD connection parameters (I basically wrote the 'new connection' DB prompter dialog in WPF, to get me a connection string that the custom action can inject in the installed application's configuration file).
The WIX code is fairly simple to figure out, and I know I execute the custom action just fine - I put there a MessageBox and a MmsiBreak on the call to my custom action method. I get there without a problem.
When the custom action instantiates my WPF dialog window, I get an InvaliOperationException: "The calling thread must be STA, because many UI components require this".
The same code runs fine when I put it in a standard WPF application, because VisualStudio generates boiler plate code with Main() that has a STAThreadAttribute on it.
I can't tack that attribute on the msiexec caller, and if I try to set the thread apartment state in my custom action, it fails:
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
Is not supposed to work for framework past 2.0.
Is there any way to do what I'm trying to do here? I'd appreciate some pointers.
EDIT
I even tried to run the dialog in its own thread, e.g. the code is like this:
// Static class members
static ManualResetEvent _done = new ManualResetEvent(false);
static ActionResult _caResult;
static Session _session;
static Thread _worker;
[CustomAction]
static public ActionResult PromptForDB(Session session)
{
_session = session;
_worker = new Thread(WorkerThread);
_worker.Start();
_done.WaitOne();
return _caResult;
}
[STAThread]
static void WorkerThread()
{
try
{
Prompter wnd = new Prompter();
if (!(bool)wnd.ShowDialog())
{
_caResult = ActionResult.SkipRemainingActions;
}
else
{
// Harvest our properties (omitted from this post)
_caResult = ActionResult.Success;
}
catch (Exception ex)
{
_caResult = ActionResult.Failure;
_session.Log("Error: " + ex.Message);
}
finally
{
_done.Set();
}
}
That does not work either.
Before starting your new thread, set its ApartmentState as follows:
_worker.SetApartmentState(ApartmentState.STA);
See this:
The calling thread must be STA, because many UI components require this in WPF
When I launch a winform application from visual studio, it does extra runtime checks to check for errors. In particular it will throw an exception if I access a form element outside of the thread it was created, with text "Cross-thread operation not valid".
When I run my integration tests, which start the process outside of visual studio, that checking is not enabled. I am running the executable build result, except starting it with Process.Start() and perhaps custom command-line arguments.
How can I enable that run-time checking when I run the executable outside of visual studio?
This is controlled by the Control.CheckForIllegalCrossThreadCalls property. It is initialized with the value of Debugger.IsAttached. Simply set it to true to force checking even when your program isn't being debugged. For example:
private void button1_Click(object sender, EventArgs e) {
Control.CheckForIllegalCrossThreadCalls = true;
var t = new System.Threading.Thread(() => {
try {
this.Text = "kaboom";
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
});
t.Start();
}
This brings up the message box when you start the program with Ctrl+F5 or run it outside of Visual Studio.
it builds a debug and release version can you not run the debug version in your integration tests?