Very newbie question.
I want to overwrite the Main in my WPF app so if I double-click on a file, it will be loaded. My main function is:
[STAThread]
static void Main(string[] args)
{
FileConvert.App app = new FileConvert.App();
app.InitializeComponent();
if (args.Length > 0)
{
Window1 wnd1 = (Window1)(app.MainWindow);
wnd1.SetProjectFile(args[0]);
}
app.Run();
My problem is that wnd1 is null. How do I get access to this window so I can pass it the filename to load?
Thanks!
Instead of overwriting the Main method, try overriding the OnStartup method in App.xaml.cs:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
if (e.Args.Length > 0)
((Window1) MainWindow).SetProjectFile(e.Args[0]);
}
}
Related
Currently I'm working on a WPF-App. It should be launched by command line with a single parameter.
I defined:
public App([Optional] string[] args)
{
//string[] args = new string[] { "UK356715586" };
Console.WriteLine("accessed app");
if (args.Length == 0)
{
Environment.Exit(-1);
}
else
{
Console.WriteLine("Before PONumber Setting");
PONumber = args[0].ToString();
}
//PONumber = "UK356715586";
}
I set this debug setting for the given parameter:
By launching in VS I'm getting:
instance of an object."
"args" war "null".
What can i do?
Do not create a constructor with a parameter declared as [Optional]. It is never assigned. If you remove the attribute, you will even get a compilation error.
Instead use the built in Startup event of the Application type. From the documentation:
A typical Windows Presentation Foundation application may perform a variety of initialization tasks when it starts up, including:
Processing command-line parameters.
[...] application-scope properties and command-line parameters can only be used programmatically. Programmatic initialization can be performed by handling the Startup event [...]
Assign an event handler in App.xaml and implement it in App.xaml.cs.
<Application x:Class="YourWpfApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
Startup="App_OnStartup">
<Application.Resources>
<!-- ...your resources. -->
</Application.Resources>
</Application>
public partial class App : Application
{
private void App_OnStartup(object sender, StartupEventArgs e)
{
Console.WriteLine("accessed app");
if (e.Args.Length == 0)
{
Shutdown(-1);
}
else
{
Console.WriteLine("Before PONumber Setting");
PONumber = e.Args[0];
}
}
// ...other code.
}
An alternative is to override the OnStartup method in your App type. From the documentation:
OnStartup raises the Startup event.
A type that derives from Application may override OnStartup. The overridden method must call OnStartup in the base class if the Startup event needs to be raised.
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Console.WriteLine("accessed app");
if (e.Args.Length == 0)
{
Shutdown(-1);
}
else
{
Console.WriteLine("Before PONumber Setting");
PONumber = e.Args[0];
}
}
// ...other code.
}
In my windows form application I call, from the main MDIContainer form, a class in which I invoke the open of the child form.
In Main Form :
private void btnTemplate_ItemClick(object sender, ItemClickEventArgs e)
{
beiProgressBar.EditValue = "Form opening in progress...";
repositoryItemMarqueeProgressBar1.ShowTitle = true;
beiProgressBar.Visibility = BarItemVisibility.Always;
bwTemplate.RunWorkerAsync();
}
private void bwTemplate_DoWork(object sender, DoWorkEventArgs e)
{
FrmTemplate frm;
frm = new FrmTemplate();
Callback.SetFormTemplate(this, ref frm);
}
In the Callback class I show the child form :
public delegate void SetFormTemplateCallback(FrmMain pFormMain, ref FrmTemplate pForm);
public static void SetFormTemplate(FrmMain pFormMain, ref FrmTemplate pForm)
{
if (pFormMain.InvokeRequired)
{
SetFormTemplateCallback d = new SetFormTemplateCallback(SetFormTemplate);
pFormMain.Invoke(d, new object[] { pFormMain, pForm });
}
else
{
pForm.MdiParent = pFormMain;
pForm.InitForm();
pForm.Show();
}
}
This operation randomly hangs my application.
I also tried with BeginInvoke but the problem is still present.
I noticed that often the application freeze when it is minimized.
It is difficult also debug this error.
Anyone has ever reached a similar behavior ?
I associated .pdf files with my C#.NET WPF app in Windows.
If I open the pdf file by clicking on it, array "param" is:
string[] param = Environment.GetCommandLineArgs();
Which contains two paths:
1) Path to my app (param[0])
2) Path to opened (param[1])
I have set in the C# code (app.xaml.cs) that only one instance of my app may be opened in Windows. If I try to open a second instance, the main window of the first instance is activated.
But now, if I open the next pdf file by click on it “param” contains the path to the first file logically, therefore I can not open the next file :0(.
How should I solve this problem? I don’t want to move to the next instance of the app!
Here is my app.xaml.code
public partial class App : Application
{
App()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
SingleInstanceManager manager = new SingleInstanceManager();
manager.Run(new[] { "test" });
}
}
public class SingleInstanceManager : WindowsFormsApplicationBase
{
SingleInstanceApplication app;
public SingleInstanceManager()
{
this.IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// First time app is launched
app = new SingleInstanceApplication();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
// Subsequent launches
base.OnStartupNextInstance(eventArgs);
app.Activate();
}
}
public class SingleInstanceApplication : Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
// Create and show the application's main window
MainWindow window = new MainWindow();
window.Show();
}
public void Activate()
{
// Reactivate application's main window
this.MainWindow.WindowState = WindowState.Normal;
this.MainWindow.Activate();
((MainWindow)this.MainWindow).SpracujStartovacieParametre();
}
}
Here is my solution:
public partial class App : Application
{
App()
{
InitializeComponent();
}
[STAThread]
static void Main()
{
SingleInstanceManager manager = new SingleInstanceManager();
//manager.Run(new[] { "test" });
manager.Run(Environment.GetCommandLineArgs());
}
}
public class SingleInstanceManager : WindowsFormsApplicationBase
{
SingleInstanceApplication app;
public SingleInstanceManager()
{
this.IsSingleInstance = true;
}
protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
{
// First time app is launched
app = new SingleInstanceApplication();
app.Run();
return false;
}
protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs)
{
// Subsequent launches
base.OnStartupNextInstance(eventArgs);
//MessageBox.Show("Event arguments:"+ eventArgs.ToString());
app.Activate(eventArgs.CommandLine.ToArray<string>());
}
}
public class SingleInstanceApplication : Application
{
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
base.OnStartup(e);
// Create and show the application's main window
MainWindow window = new MainWindow();
window.Show();
}
public void Activate(string[] eventArgs)
{
((MainWindow)this.MainWindow).SpracujCommandLineArgs(eventArgs);
this.MainWindow.WindowState = WindowState.Maximized;
this.MainWindow.Activate();
}
}
Is it possible to start WPF Application in Console mode?
public partial class App : Application
{
public App()
{
InitializeComponent();
}
}
<Application x:Class="WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
[STAThread]
static void Main(string[] args)
{
if (args.Length > 0)
{
switch (args[0].ToLower())
{
case "/g": RunApplication(); break;
}
}
}
private static void RunApplication()
{
var application = new System.Windows.Application();
application.Run(new App());
}
It will show Argument type 'WPF.app' is not assignable to parameter type 'System.Windows.Window'.
Any solution to work around it??
Any different between
1.public partial class App : Application
2.public partial class App : Window
You could declare a Window and then start your app this way:
var application = new System.Windows.Application();
application.Run(new Window());
EDIT:
You seem a bit confused, so let me explain:
Say you have a program:
using System;
namespace ConsoleApplication
{
class Program
{
[STAThread]
static void Main(string[] args)
{
RunApplication();
}
private static void RunApplication()
{
var application = new System.Windows.Application();
application.Run();
}
}
}
This will run a WPF application with no Window.
If, on the other hand, you pass a Window into application.Run(), you will get a WPF window. App should not derive from Window, since it should derive from Application.
Application.Run method either takes no arguments or a Window. It does not take Application. Therefore, if you want to start a previously created Application, as you have over there, you should do something like this:
private static void RunApplication()
{
var application = new App();
application.Run(); // add Window if you want a window.
}
Lastly, if you want to just use application.Run() and not have to pass a specific Window, just declare a starting Window in your Application XAML using StartupUri:
<Application x:Class="WPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="SomeWindow.xaml">
</Application>
As I understand it, the serviceBase.Onstart(args) should recieve arguments that are present in serviceController.start(args).
Here is my service controller implementation
if (serviceController.Status == ServiceControllerStatus.Stopped)
{
try
{
string[] args = {"execute-service"};
serviceController.Start(args);
ServiceManager.WaitForStatusChange(......);
}
catch (InvalidOperationException ex)
{
EventLog.WriteEntry(.....);
return 1;
}
}
Here is my service.cs
protected override void OnStart(string[] args)
{
this.OnStart(args);
this.scheduler.StartScheduler();
}
When I attempt to start my service, the argument "execute-service" is not passed to the main program.cs. I have a logFile that is being created and can see the args are not there.
Looking for some ideas on how to pass the args, as I read online, I am doing it correctly using the servicebase.onstart().
Thoughts on how to debug or fix?
I don't think there is enough information shown here to debug this issue. For comparison, this is what I do in a console application designed to run as a Windows service:
public sealed partial class ServiceMain : ServiceBase
{
// Service startup modes.
private const string DEBUG = #"/d";
private const string INSTALL = #"/i";
private const string UNINSTALL = #"/u";
Then ServiceMain.Main() is set is set as the startup method:
// This is the entry point for this service.
// This method runs on an SCM thread.
public static void Main(string[] args)
{
if (Environment.UserInteractive && args.Length > 0)
{
switch (args[0])
{
// Debug the service as a normal app, presumably within Visual Studio.
case DEBUG:
ServiceMain DebugService = new ServiceMain();
DebugService.OnStart(null);
break;
Which calls the ServiceMain.OnStart() method:
// SCM requests service start using its own thread.
// This method must complete within 10 seconds of it
// starting. Otherwise the SCM diagnoses a hang.
protected override void OnStart(string[] args)
{
this.AppLog = new Log();
AppLog.Information("SCM requested service start.", "ServiceMain.OnStart");
You can see the whole service in context here.