Playing regular and looping sounds with JDK 11? - codenameone

I am using Java JDK 11.0.8 ("Installed JREs" under Eclipse is set to jdk-11.0.8), Eclipse 2020-06, and Codename One 6.0.0.
I have recently switched from JDK 8 to JDK 11 and noticed that playing sounds option in my app does not work anymore...
Note that I uncheck "Java 8" when I create my app and I am only trying to work things out in the simulator (I am not trying to deploy the app to an actual mobile device).
I want to play a "regular sound" (I want to play a sound from beginning to end, and when it ends I do not need to replay it from the beginning) and also a "looping sound" (the sound should come to its beginning when it ends and hence, I can continuously play it in the background).
Hence I have two questions:
Question1 - About "regular sounds"
I would like to create Media object just once and then re-use it whenever I need to play the same regular sound.
For that purpose I am encapsulating a Media creation inside a class as follows:
public class RegularSound {
private Media m;
public RegularSound(String fileName) {
try{
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/"+fileName);
m = MediaManager.createMedia(is, "audio/wav");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void play() {
m.setTime(0);
m.play();
}
}
Then I instantiate the RegularSound object and play it as follows:
mySound = new RegularSound("example.wav");
mySound.play();
Please note that example.wav is copied directly under the "src" directory of my project.
This code used to work with JDK 8, but with JDK 11, I get the following build errors:
Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: javax/media/ControllerListener
at com.codename1.impl.javase.JavaJMFSEPort$1.run(JavaJMFSEPort.java:67)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: java.lang.ClassNotFoundException: javax.media.ControllerListener
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.ClassLoader.findSystemClass(ClassLoader.java:1247)
at com.codename1.impl.javase.ClassPathLoader.findClass(ClassPathLoader.java:269)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:115)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at com.codename1.impl.javase.ClassPathLoader.loadClass(ClassPathLoader.java:107)
... 14 more
Question2- About "looping sounds"
For looping sound I have created another class as follows:
public class LoopingSound implements Runnable{
private Media m;
String fileName;
public LoopingSound(String fileName){
try{
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/"+fileName);
m = MediaManager.createMedia(is, "audio/wav",this);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void pause()
{
m.pause();
}
public void play()
{
m.play();
}
public void run() {
m.setTime(0);
m.play();
}
}
But I again get build errors when I instantiate an object of LoopingSound and try to play it...
So could you please let me know how to change code for regular and looping sounds so that I do not receive above-mentioned errors when using JDK 11?
UPDATE
Thanks for the reply #shai-almog. I have installed CEF. But I am receiving some messages on the console in runtime and I can't hear the sound playing... I run the following code:
try {
InputStream is = Display.getInstance().getResourceAsStream(getClass(), "/example.wav");
Media m = MediaManager.createMedia(is, "audio/wav");
m.play();
} catch (IOException e) {
e.printStackTrace();
}
and I receive the following messages on console when I run this code (it throws an exception at the end):
Adding CEF to classpath
Retina Scale: 2.0
CEF Args: [--disable-gpu, --disable-software-rasterizer, --disable-gpu-compositing, --touch-events=enabled, --enable-media-stream, --device-scale-factor=4, --force-device-scale-factor=4, --autoplay-policy=no-user-gesture-required, --enable-usermedia-screen-capturing]
Using:
JCEF Version = 83.4.0.260
CEF Version = 83.4.0
Chromium Version = 83.0.4103.106
AppHandler.stateHasChanged: INITIALIZING
initialize on Thread[AWT-EventQueue-0,6,main] with library path C:\Users\pmuyan\.codenameone\cef\lib\win64
Added scheme search://
Added scheme client://
Added scheme cn1stream://
DevTools listening on ws://127.0.0.1:8088/devtools/browser/591d3502-6fd6-4997-9131-9a2a352e47b1
AppHandler.stateHasChanged: INITIALIZED
Running ready callbacks
Exception in thread "AWT-EventQueue-0" Address changed to data:text/html,%3C!doctype%20html%3E%3Chtml%3E%3Chead%3E%3Cstyle%20type%3D'text%2Fcss'%3Edocument%2C%20body%20%7Bpadding%3A0%3Bmargin%3A0%3B%20width%3A100%25%3B%20height%3A%20100%25%7D%20video%2C%20audio%20%7Bmargin%3A0%3B%20padding%3A0%3B%20width%3A100%25%3B%20height%3A%20100%25%7D%3C%2Fstyle%3E%3C%2Fhead%3E%3Cbody%3E%3Caudio%20id%3D'cn1Media'%20width%3D'640'%20height%3D'480'%20style%3D'width%3A100%25%3Bheight%3A100%25'%20src%3D'https%3A%2F%2Fcn1app%2Fstreams%2F1'%2F%3E%3Cscript%3Ewindow.cn1Media%20%3D%20document.getElementById('cn1Media')%3Bfunction%20callback(data)%7B%20cefQuery(%7Brequest%3A'shouldNavigate%3A'%2BJSON.stringify(data)%2C%20onSuccess%3A%20function(response)%7B%7D%2C%20onFailure%3Afunction(error_code%2C%20error_message)%20%7B%20console.log(error_message)%7D%7D)%3B%7Dcn1Media.addEventListener('pause'%2C%20function()%7B%20callback(%7B'state'%3A'paused'%7D)%7D)%3Bcn1Media.addEventListener('play'%2C%20function()%7B%20callback(%7B'state'%3A'playing'%7D)%7D)%3Bcn1Media.addEventListener('ended'%2C%20function()%7B%20callback(%7B'state'%3A'ended'%7D)%7D)%3Bcn1Media.addEventListener('durationchange'%2C%20function()%7B%20callback(%7B'duration'%3A%20Math.floor(cn1Media.duration%20*%201000)%7D)%7D)%3Bcn1Media.addEventListener('timeupdate'%2C%20function()%7B%20callback(%7B'time'%3A%20Math.floor(cn1Media.currentTime%20*%201000)%7D)%7D)%3Bcn1Media.addEventListener('volumechange'%2C%20function()%7B%20callback(%7B'volume'%3A%20Math.round(cn1Media.volume%20*%20100)%7D)%7D)%3Bcn1Media.addEventListener('error'%2C%20function()%7B%20var%20msg%20%3D%20'Unknown%20Error'%3B%20try%20%7Bmsg%20%3D%20cn1Media.error.message%20%2B%20'.%20Code%3D'%2Bcn1Media.error.code%3B%7Dcatch(e)%7B%7D%20callback(%7B'error'%3A%20msg%7D)%7D)%3B%3C%2Fscript%3E%20%3C%2Fbody%3E%3C%2Fhtml%3E
UPDATE 2
I could manually add Open JavaFX 11 to Eclipse and to Codename One app running under Eclipse while using JDK 11 as follows:
Step1) Create JavaFX11 user library under Eclipse
Download JavaFX 11 from https://gluonhq.com/products/javafx/
unzip it -> creates javafx-sdk-11.0.2 folder
Create a User Library: Eclipse -> Window -> Preferences -> Java -> Build Path -> User Libraries -> New.
Name it JavaFX11.
Hit "Add External JARs" and include all the jars under javafx-sdk-11.0.2\lib
Step 2) Add the JavaFX11 library to the project:
Right click on project.
Select Build path -> Configure Build Path
Goto Library tab->Add Library->User Library->Check JavaFX11->Apply and Close
Now, I can hear sounds playing in my Codename One application.
However, I need to run my application from command prompt and regular command line to run the apps does not work anymore (the app cannot find the JavaFX related classes from the command prompt and I get the same errors listed above). So could you please tell me how to modify the command line so that Codename One project that uses JavaFX would run from command prompt?
Here is the regular command line I use:
java -cp dist\Proj.jar;JavaSE.jar com.codename1.impl.javase.Simulator com.mycompany.hi.Main
BTW, I have tried to add javafx.media.jar under javafx-sdk-11.0.2\lib to the classpath (-cp) in the command line, but this did not work...
UPDATE 3
We have solved the issue by using the following command line:
java --module-path C:\javafx-sdk-11.0.2\lib\ --add-modules= ALL-MODULE-PATH -cp dist\Proj.jar;JavaSE.jar com.codename1.impl.javase.Simulator com.mycompany.hi.Main
(where C:\javafx-sdk-11.0.2\lib\ is our )
Thanks!

The TL;DR
Either install CEF as explained here or switch to ZuluFX 11 for your VM.
The explanation:
This used to work until we integrated CEF support we would download JavaFX dynamically for JDK 11 installs but this caused a lot of related problems. So we decided to migrate to CEF, this is still in progress and while it's ongoing JavaFX dynamic download is broken. Once it's done CEF will be auto-installed and this will be seamless again.
This impacts browser component and media which are the two components implemented by JavaFX.

Related

How to detect URI activation on a WPF desktop package (WAP) after it has already launched?

I have a WPF desktop application that is MSIX-packaged using a Windows Application Package (WAP) project. I already know how to launch my WPF desktop app the first time using URI activation, by calling AppInstance.GetActivatedEventArgs() and then analyzing the arguments:
if (activatedEventArgs.Kind == ActivationKind.Launch)
{
if (((LaunchActivatedEventArgs)activatedEventArgs).Arguments == "myactivationcode")
// .. do something
}
But if a user runs the URI activation a 2nd time, while my app is already launched, I have learned that a new instance of my app is launched. This doesn't happen with UWP apps, just desktop apps. I can kill the 2nd instance to follow a desired singleton pattern, but what I want is for the first instance of my WPF app to get some event that lets it know to come back into view.
Things I've researched that have no answers that I can see:
How to handle URI activation in a Windows Application Packaging Project?
How can I handle file activation from a WPF app which is running as UWP?
https://learn.microsoft.com/en-us/windows/uwp/launch-resume/handle-uri-activation#step-3-handle-the-activated-event
Does any such API or event exist for URI re-activation? Or do I need to do some other form of IPC, like named pipes or WCF on the 2nd instance of my app? Any help here would be greatly appreciated.
But if a user runs the URI activation a 2nd time, while my app is already launched, I have learned that a new instance of my app is launched.
Whether a second instance is launched depends on the implementation of your custom Main method.
In your second link, there is a link to blog post and a code example that demonstrates how to prevent another instance from being launched.
It uses named pipes to communicate with the already running app instance and passes a serialized IActivatedEventArgs to it:
[STAThread]
static void Main(string[] args)
{
IActivatedEventArgs activatedEventArgs = AppInstance.GetActivatedEventArgs();
using (Mutex mutex = new Mutex(false, AppUniqueGuid))
{
if (mutex.WaitOne(0, false))
{
new Thread(CreateNamedPipeServer) { IsBackground = true }
.Start();
s_application = new App();
s_application.InitializeComponent();
if (activatedEventArgs != null)
s_application.OnProtocolActivated(activatedEventArgs);
s_application.Run();
}
else if (activatedEventArgs != null)
{
//instance already running
using (NamedPipeClientStream namedPipeClientStream
= new NamedPipeClientStream(NamedPipeServerName, AppUniqueGuid, PipeDirection.Out))
{
try
{
namedPipeClientStream.Connect(s_connectionTimeout);
SerializableActivatedEventArgs serializableActivatedEventArgs = Serializer.Serialize(activatedEventArgs);
s_formatter.Serialize(namedPipeClientStream, serializableActivatedEventArgs);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, string.Empty, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
}
}
Does any such API or event exist for URI re-activation?
No
Or do I need to do some other form of IPC, like named pipes or WCF on the 2nd instance of my app?
Yes. Again, please refer to the mentioned blog post and accompanied code sample.

How to Execute (Vector) Storage.getInstance().readObject(filePath); in Java 8 Swing Package

Windows 10 Pro
Latest Simulator
Java Swing Project
I would like to execute "Vector a1 = (Vector) Storage.getInstance().readObject(filePath);"
In a Java Swing Application running on Windows 10 platform, I tried import CodenameOne.jar in Swing package, however when executing above code, get null pointer exception in Storage.getInstance()
Is there a way to execute this in Swing?
Thoughts?
Best Regards.
Thanks, I did not init the Display, however "Display.init(Object m)" requires an Object Argument and the Init method is deprecated.
Can you please provide me the codenameone Display dependencies?
And perhaps a java Swing snippet of code to initialize Display in order to execute Storage.getInstance().readObject(filePath)
Thoughts?
Best Regards
Thanks, Passing init(working directory) solved the Exception thrown.
Here is the Code snippet used to allow me to execute:
Storage.getInstance().readObject(filePath).
String filePath = incSrv.Pwd();// gets working directory
try {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Display.init(filePath);
String fileName = "A1-MMA.properties";
Vector a1 = (Vector) Storage.getInstance().readObject(filePath);
}
});
} catch (Exception e) {
}
And it does appear to work,
However I am left with a blacked out form that appears modal.
How can I avoid this or dispose it?.
FYI: What I am creating here is a work around for serializing Vector in Codenameone. I Save Vector to file using "Storage.getInstance().writeObject(Path, Vector)"
I convert the file to bytes and write it to the Swing Server VIA socket.
Using Storage.getInstance().readObject(file) on the Swing Server I have deserialize the object into the Vector from my app.
This appears to work well and is more efficient than the current method I use to deliver complex Vectors from the app to the Swing Server.
Can you please let me know if you see a red flag with this workaround?
Like The ability to Storage.getInstance().readObject(file) on the Swing Server may go away?
This method will save a lot of time in movind Vector data to and from the App/Server.
Thoughts Best Regards
Storage.getInstance().readObject(file) // (A1ServiceSrv.java:571)
Caused this Exception:
java.lang.NullPointerException
at com.codename1.io.Storage.init(Storage.java:89)
at com.codename1.io.Storage.getInstance(Storage.java:112)
at Main.A1ServiceSrv.loadVectorFromFile(A1ServiceSrv.java:571)
Regards
12/11/2021:
Thanks Shai,
I am including in my classpath CodenameOne.jar with update date of 12/11/2021 after CN1 refresh.
Getting Same null pointer exception.
Passing in Path "C:\Src1\A1-Arms\A1-Server\A1-MMA.properties" (Absolute Path)
Also Tried "A1-MMA.properties", however I don't think Codenameone knows where my home path is since we are not initializing it as we did with
Display.init("Current Working Directory where files reside");
This is the Fresh Stack Trace w/o calling Display.init (12-20-2021)
java.lang.NullPointerException at
com.codename1.ui.Display.getResourceAsStream(Display.java:3086)
at com.codename1.io.Log.print(Log.java:327)
at com.codename1.io.Log.logThrowable(Log.java:299)
at com.codename1.io.Log.e(Log.java:285)
at com.codename1.io.Storage.readObject(Storage.java:271)
at Main.A1ServiceSrv.loadVectorFromFile(A1ServiceSrv.java:596)
vector = (Vector) Storage.getInstance().readObject(filePath); // (A1ServiceSrv.java:596)
This is hopefully fixed by this commit: https://github.com/codenameone/CodenameOne/commit/72bf283bdaaefe5207bb9fd6787578e3ef61522c if not let me know with a fresh stack

Why is this DLL DevExpress.ExpressApp loading?

I am trying to deploy a plugin to a customer.
We use MEF, import, export attributes. I use the Export and the client imports it
My application uses DevExpress XtraGrid, XtraEditors and many other DevExpress DLL's(see screenshot), System.Data.Services.
Inspite of providing all these required DLL's and many of their dependencies, the plugin still seems to be requiring DevExpress.ExpressApp. DevExpress.ExpressApp and all its other dependencies are definitely not needed.
Since the client kept complaining that they have a FileNotFound exception, I decided to make a test project to import my own plugin. This is my test code to test the clients theory that he is getting is the following.
System.IO.FileNotFoundException: Could not load file or assembly 'DevExpress.ExpressApp.v14.2, Version=14.2.7.0,
Our Plugin
[Export(typeof (ISomething))]
public class MyClass : ISomething
{
}
TESTER
class Program
{
[ImportMany]
public IEnumerable<ISomething> Somethings { get; set; }
static void Main(string[] args)
{
var rp = new Program();
rp.Run();
}
public void Run()
{
Compose();
}
public void Compose()
{
try
{
AppDomain.CurrentDomain.FirstChanceException += FirstChanceHandler;
AggregateCatalog aggregatecatalogue = new AggregateCatalog();
aggregatecatalogue.Catalogs.Add(new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory));
CompositionContainer container = new CompositionContainer(aggregatecatalogue);
CompositionBatch batch = new CompositionBatch();
batch.AddPart(this);
container.Compose(batch);
}
catch (Exception ex)
{
throw ex;
}
}
static void FirstChanceHandler(object source, FirstChanceExceptionEventArgs e)
{
System.Text.StringBuilder msg = new System.Text.StringBuilder();
msg.AppendLine(e.Exception.GetType().FullName);
msg.AppendLine(e.Exception.Message);
System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace();
msg.AppendLine(st.ToString());
msg.AppendLine();
String desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string logFilePath = String.Format("{0}\\{1}", desktopPath, "logfile.txt");
System.IO.File.AppendAllText(logFilePath, msg.ToString());
}
Sure enough, I saw in the output window and found out that it was indeed loading this DLL and some of the dependencies related to ExpressApp from GAC.
Question: How do I figure out where and why is ExpressApp needed?
I can simply just deliver the DLL but then it goes on and on about a TON of dependencies which I have clue why they would be needed.
there are tools for checking managed assembly dependencies. The MS Windows SDK contains the ildasm.exe utility. Chances are you already have it installed in:
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\ildasm.exe
When I had a similar problem (it was dll version mismatch) I have also used cygwin's 'grep' from command line to search for the missing dependency string across all DX and our custom assemblies to locate the actual .dll file referencing the missing dependency dll version. Then opened it in ildasm.exe and double clicked on the MANIFEST tree node. There I've seen the reference to the .dll version I didn't have.
You may follow the same steps to try to track the missing dependency. Run the "DevExpress.ExpressApp" string search against all DX dlls in your project's bin directory then if result is found, open the reported file with ildasm.exe
Note, most probably you don't have 'grep' from the https://www.cygwin.com/ package installed, so use the string search utility which is available to you.
There are also other 3rd party tools for checking dll dependencies but those have to be installed separately, while ildasm.exe is a part of Windows SDK. See this question's answers for other tools refs:
How do I determine the dependencies of a .NET application?
UPDATE:
if you don't have all your DX libs in the bin folder because your app is a plugin and uses DX libs directly from GAC, then you may search for DevExpress.ExpressApp references right in the DX installation folder, in my case:
C:\Program Files (x86)\DevExpress 15.2\Components\Bin\Framework
I've copied the above folder contents to a temp folder, removed all locale subfolders as well as all DevExpress.ExpressApp.* dlls and then ran a command:
grep -nr "DevExpress.ExpressApp"
which produced the following results:
Binary file DevExpress.EasyTest.v15.2.dll matches
Binary file DevExpress.Persistent.Base.v15.2.dll matches
Binary file DevExpress.Persistent.BaseImpl.EF.v15.2.dll matches
Binary file DevExpress.Persistent.BaseImpl.v15.2.dll matches
Binary file DevExpress.Workflow.Activities.v15.2.Design.dll matches
Binary file DevExpress.Workflow.Activities.v15.2.dll matches
See if any of the above dlls is used by either your plugin or the host app where the plugin is to be deployed.
HTH

Intelligent Agents using Jade framework

I want to develop a multi-agent system and I want to run different agents from different containers. I'm using eclipse with Jade framework for this and i have no idea how to configure the "run configuration" for the project in order to accomplish this. So far I have this: -gui -container main:Sender;a1:Receiver;a2:Pong and I want to put agents a1 and a2 in a separate container. Please help.
When starting a new jade project I usually create a Coordinator agent with the methods to launch and destroy other agents. I think this is good practice as you can extend these methods to other agents if need be.
I hope that this will help.
First Run the Agent jade graphical user interface (Ejade) (By Installing the Ejade Library)
or you can run it on the console:
C:\java jade.Boot -gui (You have to fix the system variable path to "C:\..\jade.far" and create a variable name classpath = "C:\..\jdk7\")
Run the code that allows you to create a new container to deploy on it your agents.
import jade.core.ProfileImpl;
import jade.core.Runtime;
import jade.domain.ams;
import jade.wrapper.AgentContainer;
import jade.wrapper.AgentController;
public class ContainerDeploy {
public static void main(String[] args) {
try{
Runtime runtime=Runtime.instance();
ProfileImpl profileImpl = new ProfileImpl(false);
profileImpl.setParameter(ProfileImpl.MAIN_HOST, "localhost");
AgentContainer agentContainer=runtime.createAgentContainer(profileImpl);
AgentController agentcontroller1 = agentContainer.createNewAgent("Name of Agent", "com.package.AgentClass", new Object[]{});
agentController1.start();
}catch(Exception e) {
System.out.println("Runtime Error\t");
e.printStackTrace();
}
}
}

Is it possible to launch a Silverlight 4 OOB application from a web page? [duplicate]

This question already has an answer here:
Launch Silverlight Out-of-Browser from browser post-installation
(1 answer)
Closed 2 years ago.
I'm planning to build a download manager application and would like to be able to launch the application when a user clicks a button the site. The application would obviously already need to be installed on the client machine.
There are a few reasons why this needs to be written using Silverlight, but they're not really relevant to the question. I only mention it so that people don't suggest that I use another technology.
Doing a bit of a mash up from two other posts [1] and [2].
But of course this will only work for Windows not Mac. There you will have to fallback to the #michael-s-scherotter style solution.
private void Button_Click(object sender, RoutedEventArgs e)
{
if (Application.Current.HasElevatedPermissions && System.Windows.Interop.ComAutomationFactory.IsAvailable)
{
string run = "\""%ProgramFiles%\\Microsoft Silverlight\\sllauncher.exe"\" /emulate:"Silverface.xap" /origin:\"http://www.silverlight.net/content/samples/apps/facebookclient/ClientBin/Silverface.xap\" /overwrite";
dynamic cmd = ComAutomationFactory.CreateObject("WScript.Shell");
cmd.Run(run, 1, true);
}
}
Yes. Here is an example:
http://www.silverlight.net/content/samples/apps/facebookclient/sfcquickinstall.aspx
I found a trick that launches the installed silverlight OOB from the silverlight app in-browser. Both applications should be singed and have the elevated trust.
When a user installs the silverlight OOB App first time, retrive the path and argument values from the shortcut file of the OOB app on desktop. (ref: How I can use Shell32.dll in Silverlight OOB) If you know the the path and argument values, you can launch the OOB app using Com Object.
Send the retrive the path and argument values to the silverlight App in-browser. (ref: http://msdn.microsoft.com/en-us/library/dd833063(v=vs.95).aspx)
Store the path and argument values in a cookie.
Now, the silverlight app in-browser is able to launch the silverlight OOB using the path and argument values in the cookie.
using (dynamic shell = AutomationFactory.CreateObject("WScript.Shell"))
{
shell.Run(launchPath);
}
I hope this trick is useful to you :)
It is possible if you agree to install the app each time the user clicks on it.
You also should set the app to require elevated trust in its OOB settings.
Just uninstall the app on startup (for example, in main window constructor):
if (Application.Current.HasElevatedPermissions && Application.Current.InstallState == InstallState.Installed)
{
string launcherPath = string.Empty;
using (dynamic shell = AutomationFactory.CreateObject("Shell.Application"))
{
string launcher64 = #"C:\Program Files (x86)\Microsoft Silverlight";
string launcher32 = #"C:\Program Files\Microsoft Silverlight";
dynamic folder64 = shell.NameSpace(launcher64);
if (folder64 != null)
{
launcherPath = launcher64;
}
else
{
dynamic folder32 = shell.NameSpace(launcher32);
if (folder32 != null)
{
launcherPath = launcher32;
}
}
}
using (dynamic shell = AutomationFactory.CreateObject("WScript.Shell"))
{
var origin = Application.Current.Host.Source.OriginalString;
var launchCmd = string.Format(#"""{0}\sllauncher.exe"" /uninstall /origin:""{1}""", launcherPath, origin);
shell.Run(launchCmd);
}
}
(the code for uninstall was taken from this post: http://www.wintellect.com/blogs/sloscialo/programmatically-uninstalling-silverlight-out-of-browser-application)

Resources