I am using parameters from the command line which come in through the invoke handler of my WindowedApplication. I used to build using the excellent Flash Develop, we are now using Flash Builder 4.
I would like to know where do I enter these parameters in Flash Builder 4 so I can test them while debugging my app.
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
function onInvoke(e:InvokeEvent):void
{
trace('onInvoke', e.arguments);
}
Answering this question for Spark Application container. The WindowedApplication class allows you to do:
<s:WindowedApplication
invoke="onInvoke()"
>
but the Application container does not, so instead, you need to do this:
<s:Application
...
preinitialize="onPreinitialize()"
>
<fx:Script>
<![CDATA[
private function onPreinitialize():void
{
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onInvoke);
}
private function onInvoke(e:InvokeEvent):void
{
// e.arguments is an array containing the command line args
}
]]>
</fx:Script>
Related
I'm not sure what I'm doing wrong, but even though I'm definitely on the UI thread, I'm consistently getting the error " 'The application called an interface that was marshalled for a different thread.'" when constructing Xaml controls in C++.
See the following basic example, which uses a stripped down version of the default C++/WinRT CoreApplication template:
#include "pch.h"
using namespace winrt;
using namespace Windows;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::Foundation::Numerics;
using namespace Windows::UI;
using namespace Windows::UI::Core;
using namespace Windows::UI::Composition;
using namespace Windows::ApplicationModel::Activation;
struct App : implements<App, IFrameworkViewSource, IFrameworkView> {
CompositionTarget m_target{nullptr};
IFrameworkView CreateView() { return *this; }
void Initialize(CoreApplicationView const &) {}
void Load(hstring const &) {}
void Uninitialize() {}
void Run() {
CoreWindow window = CoreWindow::GetForCurrentThread();
winrt::Windows::UI::Xaml::Controls::TextBox textbox; // Crashes here
CoreDispatcher dispatcher = window.Dispatcher();
dispatcher.ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
}
void SetWindow(CoreWindow const &) {
Compositor compositor;
ContainerVisual root = compositor.CreateContainerVisual();
m_target = compositor.CreateTargetForCurrentView();
m_target.Root(root);
}
};
int __stdcall wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) { CoreApplication::Run(make<App>()); }
I've tried using window.Dispatcher().HasThreadAccess() to verify that I'm on the correct thread to be making UI calls, and it always returns true.
I've also tried calling RunAsync() from the window's Dispatcher and constructing a Xaml object in a lambda passed to this method, and it still has exactly the same result. HasThreadAccess returns true here too.
Can anyone explain to me where I'm going wrong here? Is constructing Xaml objects not supported in C++?
[edit]
Here's a sample project that reproduces the issue, again based on the default CoreWindow C++/WinRT template:
https://github.com/lyptt/CoreApp1
Turns out the CoreApplication-based template does not support anything from the Xaml namespace, as it's intended more towards providing a thin UWP layer for games, etc.
To get Xaml support you need to use the full template instead, then things magically start to work.
This may be a little early to ask this, but I'm running Windows 10 Technical Preview Build 10122. I'd like to set up Cortana to have custom commands. Here's how she works:
Hey Cortana, <she'll listen and process this command>
Microsoft will process the command and if there isn't anything for it, she'll just search the input on bing. However, I'd like to be able to say something like, just for example
Hey Cortana, I'm going to bed now
And have the input I'm going to bed now trigger run a batch script, a VBScript, a command, or any some sort some of custom response that basically does the following.
C:\> shutdown -s
Is there a way to set up a predefined custom commands for Cortana?
Update:
I created this basic YouTube tutorial and this more advanced one with a corresponding GitHub repo based on talkitbr's excellent and very helpful answer below.
At first his answer was beyond my understanding so I decided to break it down in a bit more detail for future users like myself.
You can create commands for Cortana to listen for.
These commands need to be described in a XML file called Voice Command Definitions or VCD.
Here's an example:
<?xml version="1.0" encoding="utf-8" ?>
<VoiceCommands xmlns="http://schemas.microsoft.com/voicecommands/1.2">
<CommandSet xml:lang="en-us" Name="HomeControlCommandSet_en-us">
<CommandPrefix>HomeControl</CommandPrefix>
<Example>Control alarm, temperature, light and others</Example>
<Command Name="Activate_Alarm">
<Example>Activate alarm</Example>
<ListenFor>[Would] [you] [please] activate [the] alarm [please]</ListenFor>
<ListenFor RequireAppName="BeforeOrAfterPhrase">Activate alarm</ListenFor>
<ListenFor RequireAppName="ExplicitlySpecified">Activate {builtin:AppName} alarm</ListenFor>
<Feedback>Activating alarm</Feedback>
<Navigate />
</Command>
...
</CommandSet>
</VoiceCommands>
After create this definition, you need to register it at App Startup:
protected async override void OnLaunched(LaunchActivatedEventArgs e)
{
...
// Install the VCD
try
{
StorageFile vcdStorageFile = await Package.Current.InstalledLocation.GetFileAsync(#"HomeControlCommands.xml");
await VoiceCommandDefinitionManager.InstallCommandDefinitionsFromStorageFileAsync(vcdStorageFile);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("There was an error registering the Voice Command Definitions", ex);
}
}
An then override the App.OnActivated method to handle when the events are triggered:
protected override void OnActivated(IActivatedEventArgs e)
{
// Handle when app is launched by Cortana
if (e.Kind == ActivationKind.VoiceCommand)
{
VoiceCommandActivatedEventArgs commandArgs = e as VoiceCommandActivatedEventArgs;
SpeechRecognitionResult speechRecognitionResult = commandArgs.Result;
string voiceCommandName = speechRecognitionResult.RulePath[0];
string textSpoken = speechRecognitionResult.Text;
IReadOnlyList<string> recognizedVoiceCommandPhrases;
System.Diagnostics.Debug.WriteLine("voiceCommandName: " + voiceCommandName);
System.Diagnostics.Debug.WriteLine("textSpoken: " + textSpoken);
switch (voiceCommandName)
{
case "Activate_Alarm":
System.Diagnostics.Debug.WriteLine("Activate_Alarm command");
break;
The tutorial shows the complete code [web archive].
After you do all of this, you can call your batch scripts using ProcessStartInfo or System.Diagnostics.Process.Start.
Also, if you are interested in responding to the user through Cortana window, check this post regarding Cortana in background [web archive].
What you can do is write a .bat file and add a shortcut to the file to the Folder: C:\ProgramData\Microsoft\Windows\Start Menu\Programs
you can name the shortcut whatever you want and trigger the shutdown by saying: "Hey Cortana open/start [shortcut name]".
Make sure that Cortana only listens to you to not get "pranked".
I'm doing an experiment with wxWebConnect test application, incorporating the xpcom tutorial at "http://nerdlife.net/building-a-c-xpcom-component-in-windows/"
I adapt MyComponent class as necessary to compile together with testapp.exe (not as separate dll), and on MyApp::OnInit I have the following lines:
ns_smartptr<nsIComponentRegistrar> comp_reg;
res = NS_GetComponentRegistrar(&comp_reg.p);
if (NS_FAILED(res))
return false;
ns_smartptr<nsIFactory> prompt_factory;
CreateMyComponentFactory(&prompt_factory.p);
nsCID prompt_cid = MYCOMPONENT_CID;
res = comp_reg->RegisterFactory(prompt_cid,
"MyComponent",
"#mozilla.org/mycomp;1",
prompt_factory);
Those lines are copied from GeckoEngine::Init(), using the same mechanism to register PromptService, etc. The code compiles well and testapp.exe is running as expected.
I put javascript test as below :
try {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const cid = "#mozilla.org/mycomp;1";
obj = Components.classes[cid].createInstance();
alert(typeof obj);
// bind the instance we just created to our interface
alert(Components.interfaces.nsIMyComponent);
obj = obj.QueryInterface(Components.interfaces.nsIMyComponent);
} catch (err) {
alert(err);
return;
}
and get the following exception:
Could not convert JavaScript argument arg 0 [nsISupport.QueryInterface]
The first alert says "object", so the line
Components.classes[cid].createInstance()
is returning the created instance.
The second alert says "undefined", so the interface nsIMyComponent is not recognized by XULRunner.
How to dynamically registering nsIMyComponent interface in wxWebConnect environment ?
Thx
I'm not sure what is happening here. The first thing I would check is that your component is scriptable (I assume it is, since the demo you copy from is). The next thing I would check is whether you can instantiate other, standard XULRunner components and get their interface (try something like "alert('Components.interfaces.nsIFile');" - at least in my version of wxWebConnect this shows an alert box with string "nsIFile".
Also, I think it would be worth checking the Error Console to make sure there are no errors or warnings reported. A magic string to do that (in Javascript) is:
window.open('chrome://global/content/console.xul', '', 'chrome,dialog=no,toolbar,resizable');
I have a winform app that is writing to console and it seems to work well. I'm using this code:
AttachConsole(-1)
Console.Out.WriteLine("Hellow world")
FreeConsole()
The question is:
If I run the app's exe file from command line, and try to redirect the output into a file. It doesn't work.
For example:
C:\ > myapp.exe > c:\output.txt
I still get the output to console screen (c:\output.txt file is created but empty), but I want it to to be saved into c:\output.txt
What's going wrong ? How to do that?
Many thanks!
You can have your cake and eat it too if you first check if output was redirected. Here's a little helper class that contains the P/Invoke voodoo:
using System;
using System.Runtime.InteropServices;
public static class ConsoleEx {
public static bool OutputRedirected {
get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdout)); }
}
public static bool InputRedirected {
get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stdin)); }
}
public static bool ErrorRedirected {
get { return FileType.Char != GetFileType(GetStdHandle(StdHandle.Stderr)); }
}
// P/Invoke:
private enum FileType { Unknown, Disk, Char, Pipe };
private enum StdHandle { Stdin = -10, Stdout = -11, Stderr = -12 };
[DllImport("kernel32.dll")]
private static extern FileType GetFileType(IntPtr hdl);
[DllImport("kernel32.dll")]
private static extern IntPtr GetStdHandle(StdHandle std);
}
Usage:
bool redir = ConsoleEx.OutputRedirected;
if (!redir) AttachConsole(-1);
// etc...
You are attaching to the parent process to provide output, which in your case is probably cmd.exe. The parent process' stdout stream has not been redirected and therefore continues to display the output on the screen.
I am not aware of a direct approach. If you do not call AttachConsole you will find that the redirect works as expected, but of course then you loose the option to have a console window. However, there is a work around that I think is reasonable.
If you want the output to go to a console window then you provide your application with a commandline switch that indicates this requirement, something like
C:\> myapp.exe /console
When the /console argument is present you call AttachConsole and the output will be written to the console. When this switch is not present you do not make the call to AttachConsole and you will be able to redirect the output to a file.
I'm building a flex 4 container for action script 2 flash applications.
I use <mx:SWFLoader> component to load the game.
I know that i can catch events or even custom events from an action script 3 application.
working example for action script 3 (not 2):
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955"
minHeight="600" creationComplete="init()">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import Red5Event;
private function handleRed5Event(e:Red5Event):void {
Alert.show("yay");
}
private function init():void {
this.fileSwf.content.addEventListener(Red5Event.CONTROL_TYPE
,handleRed5Event);
}
]]>
</fx:Script>
<mx:SWFLoader id="fileSwf" source="file.swf" />
</s:Application>
then in the flash application i extend the event class, adding the proper control type and setting bubbles to true, so whenever i dispatch an event, it's probably being catched by the flex application.
I understood that using as2 i can dispatch custom events using the following example:
import mx.events.EventDispatcher;
class Sender {
// these three lines are needed to use EventDispatcher
public var addEventListener:Function;
public var removeEventListener:Function;
public var dispatchEvent:Function;
public function Sender() {
// this line must be in the constructor of the class
EventDispatcher.initialize(this);
// dispatch an event once per second
}
public function sendEvent():Void {
dispatchEvent({type:"xpoControl"});
trace("event sent!");
}
}
can i somehow dispatch an event in action script 2 flash application that the flex 4 container will be able to catch?
thanks!
after a lot of reading.. what i
request may not be possible.
Actually, there are work-arounds. You are correct in that the way you're trying to accomplish this isn't really possible because of security restrictions. However, you could build what I like to call a marshaller-adapter via the LocalConnection class. You will need to have a method in AS2 that uses a localConnection to communicate with the flex 4 side. You will have to use simple types and pass the properties of your Red5Event more generically, but you should be able to accomplish what you need with your custom 'marshaller-adapter'.
Best of luck,
Jeremy