Using the Plantronics SDK with a Delphi application - class

and thank you in advance for any advice / insight / assistance that can be provided.
The Background:
We have a soft phone application that is written in Delphi (XE3) for Windows. The ability to answer an incoming call by activating the answer button an a Plantronics Wireless Headset was recently requested. The MSI files were downloaded and executed, and the Plantronics SDK was converted / altered into a Delphi Library File.
I then started to follow the "First Steps" section of the Plantronics Website. I knew that the "First Steps" code would have to be tweaked to fit the Delphi system.
The Problem:
In adjusting the code to work within Delphi, a few translation problems were encountered and resolved. One such error is proving to be stubborn - When an instance of one specific class is created, the error "Class not registered" is thrown.
"First Steps" code for reference -
// Connect to the Plantronics COM API:
myAppName = "SDK .NET COM sample";
sessionManager = new COMSessionManager();
sessionManager.Register(myAppName, out session);
// Hook to SessionManager events:
sessionManagerEvents = sessionManager as ICOMSessionManagerEvents_Event;
if (sessionManagerEvents != null)
{
sessionManagerEvents.onCallStateChanged += SessionManagerEvents_onCallStateChanged;
sessionManagerEvents.onDeviceStateChanged += SessionManagerEvents_onDeviceStateChanged;
}
Delphi Code:
//Connect to the Plantronics COM API:
plugin_name: "Plugin Name";
the_session: CoCOMSession.Create;
session_manager = new COMSessionManager.Create;
session_manager.Register(plugin_name, the_session);
//Hook to Session Manager Events
state_device_event_args := CoCOMStateDeviceEventArgs.Create;
call_event_args := CoCOMCallEventArgs.Create;
The final line of Delphi Code is the issue. The other three "Create" calls go off without a hitch. The line "call_event_args := CoCOMCallEventArgs.Create;" throws the error "Class not registered", even through it is declared and implemented in the library file along with the other three.
Excerpts from the library file:
Class Declarations:
IID_ICOMStateDeviceEventArgs: TGUID = '{91542BEE-4931-4620-9E96-23AE4001E93F}';
CLASS_COMStateDeviceEventArgs: TGUID = '{335D08FD-8BB5-4EF5-964B-E8A8C010530F}';
IID_ICOMCallEventArgs: TGUID = '{0280956C-C644-4CD8-B124-C8A99E5D505E}';
CLASS_COMCallEventArgs: TGUID = '{705129C3-2265-4F10-9768-0FF8A20234C0}';
Class creation functions:
//Works
class function CoCOMStateDeviceEventArgs.Create: ICOMStateDeviceEventArgs;
begin
Result := CreateComObject(CLASS_COMStateDeviceEventArgs) as ICOMStateDeviceEventArgs;
end;
// Doesn't Work
class function CoCOMCallEventArgs.Create: ICOMCallEventArgs;
begin
Result := CreateComObject(CLASS_COMCallEventArgs) as ICOMCallEventArgs;
end;
Every tutorial / forum answer about resolving the "Class Not Registered" error that I have found has not resolved the issue.
Does anyone have any advice or insight as to what I have been doing wrong?
Thank you.

The issue has been (potentially) resolved by the following -
I had mistakenly thought from the tutorial / first steps section that a "COMCallEventArgs" object needed to be created before it could be used.
Upon further review, the COMCallEventArgs object gets created when necessary at a later point.
More testing needs to be done, but I believe this issue is resolved.

Related

How to install GSDML file via Siemens TIA openness API into TIA project?

Updating with very useful info using guidance from mrsargent
I am trying to automate following steps in C# (Visual Studio) with following steps:
run and connect to TIA portal
create project
install GSDML device files
add PLC and single device as per GSDML
design application relationship between product and PLC (cpu)
I tried to use OpenNess Demo Application for the same but I am unable to step through the code and there is no option in the Demo GUI to install GSDML files in the same.
I tried to write the following code as per documentation for CAX import of GSDML file but faced errors as described below:
Code:
using
(TiaPortal tiaPortal = new TiaPortal(TiaPortalMode.WithoutUserInterface))
{
Console.WriteLine("TIA Portal has started");
ProjectComposition projects = tiaPortal.Projects;
Console.WriteLine("Opening Project...");
DirectoryInfo dinfo = new DirectoryInfo(#"C:\projects\TestProjects\");
string unixTimestamp = Convert.ToString((int)DateTime.Now.Subtract(new DateTime(1970, 1, 1)).TotalSeconds);
string prj_name = "Prj_" + unixTimestamp;
Project project = null;
try
{
project = projects.Create(dinfo, prj_name);
}
catch (Exception)
{
Console.WriteLine(String.Format("Could not open project {0}", projectPath.FullName));
Console.WriteLine("Demo complete hit enter to exit");
Console.ReadLine();
return;
}
CaxProvider caxProvider = project.GetService<CaxProvider>();
if (caxProvider != null)
{
// GETTING ERROR OVER HERE
// {"Error when calling method 'Import' of type 'Siemens.Engineering.Cax.CaxProvider'.\r\n\r\nThe path of the import file 'C:\\Gaurav\\GSDML-xxxxxxxx.xml' with the extension '.xml' is invalid.\r\n"}
caxProvider.Import(
new FileInfo(#"C:\GSDML-xxxx.xml"),
new FileInfo(#"C:\ProjectImport_Log.log"),
CaxImportOptions.MoveToParkingLot
);
}
Console.WriteLine(String.Format("Project {0} is open", project.Path.FullName));
// IterateThroughDevices(project);
project.Close();
Console.WriteLine("Demo complete hit enter to exit");
Console.ReadLine();
}
Following error is observed:
{"Error when calling method 'Import' of type 'Siemens.Engineering.Cax.CaxProvider'.\r\n\r\nThe path of the import file 'C:\GSDML-xxx.xml' with the extension '.xml' is invalid.\r\n"}
Yes this is a difficult thing to do. However it is possible. First you need proper documentation that is a little difficult to find. The manual is very detailed and good found here
You need the import the GSD file as a CAx that is found page 939 of the documentation.
//Access the CaxProvider service
Project project = tiaPortal.Projects.Open(...);
CaxProvider caxProvider = project.GetService<CaxProvider>();
if(caxProvider != null)
{
// Perform Cax export and import operation
}
To create this CAx (an xml document) you need to look starting at page 988 of this manual. It will tell you how to configure. It is far too much to explain and list in this forum but the documentation does a good job of explaining after you read it 5 times ;)
It is probably best to read this entire import/export section in order to get a full understanding of how to do this. Hope this helps!

error.CannotStartupOSGIPlatform issue when running birt

I'm in the midst of implementing Birt 4.6.0 into my gwt application. Unfortunately whenever I run a specific section of the program, I get the following error:
org.eclipse.birt.core.exception.BirtException:
error.CannotStartupOSGIPlatform at
org.eclipse.birt.core.framework.Platform.startup(Platform.java:81)
I've done some searching and one thread mentioned a permissions error but I am not sure what that entails. What does this mean?
EDIT Just read another article that suggests that it may be an issue with my classpath but I already added all the jar files from ReportEngine/lib to my buildpath. Anyone know what jar files I am supposed to include?
the offending code:
public static synchronized IReportEngine getBirtEngine(ServletContext sc) {
if (birtEngine == null) {
EngineConfig config = new EngineConfig();
java.util.HashMap map = config.getAppContext();;
map.put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, SegnalazioniDbManager.class.getClassLoader());
config.setAppContext(map);
IPlatformContext context = new PlatformServletContext(sc);
config.setPlatformContext(context);
try {
Platform.startup(config); //problem begins here
.....
}
[1]: http://developer.actuate.com/community/forum/index.php?/topic/20933-errorcannotstartuposgiplatform/
Yes it is indeed a permission error.
The relevant file is:
WEB-INF/platform/configuration/org.eclipse.osgi/.manager/.fileTableLock
You need to give access to the Birt user.

Accessing Raw Gamer Profile Picture

I am using the new XBox Live API for C# (https://github.com/Microsoft/xbox-live-api-csharp) for official access through a UWP app.
I am able to authenticate fine and reference the XBox Live user in context.
SignInResult result = await user.SignInAsync();
XboxLiveUser user = new XboxLiveUser();
Success! However, I can't seem to find an appropriate API call to return XboxUserProfile or XboxSocialProfile. Both of these classes contain URLs to the player's raw gamer pics. After reviewing MSDN documentation and the GH library it isn't clear to me how this is achieved. Any help is greatly appreciated.
The below sample should work if you meet the following pre requisits:
Reference the Shared Project that contains the API from your project and don't reference the "Microsoft.Xbox.Services.UWP.CSharp" project
Copy all source code files from the "Microsoft.Xbox.Services.UWP.CSharp" project into your project
Include the Newtonsoft.Json NuGet package into your project
Steps 1 & 2 are important as this allows you to access the "internal" constructors which otherwise would be protected from you.
Code to retrieve the profile data:
XboxLiveUser user = new XboxLiveUser();
await user.SignInSilentlyAsync();
if (user.IsSignedIn)
{
XboxLiveContext context = new XboxLiveContext(user);
PeopleHubService peoplehub = new PeopleHubService(context.Settings, context.AppConfig);
XboxSocialUser socialuser = await peoplehub.GetProfileInfo(user, SocialManagerExtraDetailLevel.None);
// Do whatever you want to do with the data in socialuser
}
You may still run into an issue like I did. When building the project you may face the following error:
Error CS0103 The name 'UserPicker' does not exist in the current
context ...\System\UserImpl.cs 142 Active
If you get that error make sure you target Win 10.0 Build 14393.

methodAccessException when passing variables from ViewModel to ViewModel on WP7 using anonymous object (MVVMCross)

I've created an app using MVVMCross, the IOS and Android versions are working but when I tried to "port" to WP7 and I ran into the following problem:
throw methodAccessException.MvxWrap("Problem accessing object - most likely this is caused by an anonymous object being generated as Internal - please see http://stackoverflow.com/questions/8273399/anonymous-types-and-get-accessors-on-wp7-1");
As mentioned in the answer to my other question about this (on Android) you have to set an InternalsVisibleTo attribute in the AssemblyInfo.cs for WP7. So I did:
[assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
But this doesn't make any difference. I use the following code to send two variables form my BeckhoffViewModel to my BeckhoffSensorViewModel.
BeckhoffViewModel:
public IMvxCommand BeckhoffSensor1
{
get
{
return new MvxRelayCommand(kvpSens1);
}
}
private void kvpSens1()
{
RequestNavigate<BeckhoffSensorViewModel>(new { VarType = "short", Variable = ".countertest" });
}
BeckhoffSensorViewModel:
public BeckhoffSensorViewModel(string VarType, string Variable)
{
_vartype = VarType;
_variable = Variable;
}
Anything I'm overlooking? I also looked at the other stackoverflow topic mentioned in the exception but couldn't really understand it.
The anonymous class will most definitely be created as internal by the compiler - which is why you need the line [assembly: InternalsVisibleTo("Cirrious.MvvmCross.WindowsPhone")]
Can you check that the AssemblyInfo.cs file definitely being linked into the project (and that this is the project containing the ViewModel/anonymous-class code)?
If that is the case, can you check the methodAccessException to see what the message is?
If that doesn't help, can you use a tool like Reflector to check the internalVisible attribute is actually present on the core/application assembly?

EventLogInstaller Full Setup with Categories?

It appears the MSDN docs are broken concerning creating an Event Log completely along with a definitions file for messages. I am also lost on how to setup Categories (I have custom numbers in the 3000's for messages).
Can anyone point me to a link or show sample code on how to make this right?
You should start (if you haven't done so already) here:
EventLogInstaller Class (System.Diagnostics)
The sample provided there is the foundation for what you want to do. To sum it up, build a public class inheriting from System.Configuration.Install.Installer in an assembly (could be the same DLL where you have the rest of your application, a separate DLL, or an EXE file), decorate it with the RunInstaller attribute, and add your setup code in the constructor:
using System;
using System.Configuration.Install;
using System.Diagnostics;
using System.ComponentModel;
[RunInstaller(true)]
public class MyEventLogInstaller: Installer
{
private EventLogInstaller myEventLogInstaller;
public MyEventLogInstaller()
{
// Create an instance of an EventLogInstaller.
myEventLogInstaller = new EventLogInstaller();
// Set the source name of the event log.
myEventLogInstaller.Source = "NewLogSource";
// Set the event log that the source writes entries to.
myEventLogInstaller.Log = "MyNewLog";
// Add myEventLogInstaller to the Installer collection.
Installers.Add(myEventLogInstaller);
}
}
When you have your assembly compiled, you may use the InstallUtil tool available through the Visual Studio Command Prompt to run the installer code.
Regarding the message definition file (which includes category definitions), the MSDN documentation for EventLogInstaller.MessageResourceFile mentions that you should create an .mc file, compile it, and add it as a resource to your assembly. Digging around, I found an excellent post which should guide you to the end, here:
C# with .NET - Event Logging (Wayback Machine)