C# Security Exception - c#

When running this program I keep receiving the error:
An unhandled exception of type 'System.Security.SecurityException' occured
Additional Information: ECall methods must be packaged into a system module.
class Program{
public static void Main()
{
Brekel_ProBody2_TCP_Streamer s = new Brekel_ProBody2_TCP_Streamer();
s.Start();
s.Update();
s.OnDisable();
}
}
How can I fix this?
The important part of the Brekel library is as follows:
//======================================
// Connect to Brekel TCP network socket
//======================================
private bool Connect()
{
// try to connect to the Brekel Kinect Pro Body TCP network streaming port
try
{
// instantiate new TcpClient
client = new TcpClient(host, port);
// Start an asynchronous read invoking DoRead to avoid lagging the user interface.
client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(FetchFrame), null);
Debug.Log("Connected to Brekel Kinect Pro Body v2");
return true;
}
catch (Exception ex)
{
Debug.Log("Error, can't connect to Brekel Kinect Pro Body v2!" + ex.ToString());
return false;
}
}
//===========================================
// Disconnect from Brekel TCP network socket
//===========================================
private void Disconnect()
{
if (client != null)
client.Close();
Debug.Log("Disconnected from Brekel Kinect Pro Body v2");
}
public void Update()
{
// only update if connected and currently not updating the data
if (isConnected && !readingFromNetwork)
{
// find body closest to the sensor
closest_skeleton_ID = -1;
closest_skeleton_distance = 9999999f;
for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
{
if (!skeletons[bodyID].isTracked)
continue;
if (skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z < closest_skeleton_distance)
{
closest_skeleton_ID = bodyID;
closest_skeleton_distance = skeletons[bodyID].joints[(int)brekelJoint.waist].position_local.z;
}
}
// apply to transforms (cannot be done in FetchFrame, only in Update thread)
for (int bodyID = 0; bodyID < skeletons.GetLength(0); bodyID++)
{
for (int jointID = 0; jointID < skeletons[bodyID].joints.GetLength(0); jointID++)
{
// only apply if transform is defined
if (skeletons[bodyID].joints[jointID].transform != null)
{
// apply position only for waist joint
if (jointID == (int)brekelJoint.waist)
skeletons[bodyID].joints[jointID].transform.localPosition = skeletons[bodyID].joints[jointID].position_local;
// always apply rotation
skeletons[bodyID].joints[jointID].transform.localRotation = skeletons[bodyID].joints[jointID].rotation_local;
}
}
}

It appears you are using a Unity library but trying to run it as a standalone application?
This error means you are calling a method that is implemented within the Unity engine. You can only use the library from within Unity.
If you want to use it standalone, you'll need to compile the library without referencing any Unity libraries, which probably means you'll need to provide implementations for anything the library is using (such as MonoBehaviour
http://forum.unity3d.com/threads/c-error-ecall-methods-must-be-packaged-into-a-system-module.199361/
http://forum.unity3d.com/threads/security-exception-ecall-methods-must-be-packaged-into-a-system-module.98230/

Additionally,
If your only problem is Debug.Log() throwing an exception, you could use reflection to plant your own Logger instance instead of Unity's one.
Step 1: Create "MyLogHandler" that will do your actual logging(write to file or to console or do nothing). Your class needs to implement "ILogHandler" interface.
Step 2: Replace unity default one with new one.
var newLogger = new Logger(new MyLogHandler());
var fieldInfo = typeof(Debug).GetField("s_Logger", BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Static);
fieldInfo.SetValue(null, newLogger);
Note: Keep in mind that reflection accesses field by name and if Unity decide to change it in future, you will not get compile error - exception will be thrown in run-time.

I know this is old, but I came across a way to unit test Unity assemblies from within Visual Studio just by toggling a symbol definition from the Unity build settings. As long as you're OK with only being either able to either run tests or have the testable components usable in unity at one time, you can toggle unit testing mode and unity mode like this (images follow):
Make your unity component a partial class. Have one file where you declare that the partial class extends MonoBehaviour and put any stuff that has to actually use unity assemblies in there. This will not be tested by the unit tests but everything else will.
Use conditional compilation to make that file's contents only compile when a specific symbol is defined during the build. I used UNIT_TEST_NO_UNITY_INTEGRATION in my case.
When you want to run the unit tests from Visual Studio, update the build settings to define that symbol. This will exclude the Unity specific stuff from step 1 from the build and allow Visual Studio to be able to run your unit tests.
When you are finished testing, edit the build settings again and remove that symbol definition. Now your unit tests won't be able to run but your assemblies will work within Unity again.

Related

how do i get Android.Media.SetPreferredDevice() to work

So making a mobile application that works on UWP, IOS and Android but since not all librarys work on every platform I'm using the library based on what device is used by
if (Device.RuntimePlatform == Device.Android) { }
And I'm currently only working on the Android part of the application.
I'm using Android.Media to play a single audio file out of multiple speakers. And to do that I'm using a Picker that has the available audio output devices. This part works.
But I'm getting a error while trying to select the PreferredDevice:
Java.Lang.NoSuchMethodError: 'no non-static method "Landroid/media/MediaPlayer;.setPreferredDevice(Landroid/media/AudioDeviceInfo;)Z"'
The code line that is giving the error is:
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
the full method that is being run is:
newoutput.SelectedIndexChanged += (changed, args) =>
{
Context context = Android.App.Application.Context;
AudioManager audioMan = (AudioManager)context.GetSystemService(Context.AudioService);
AudioDeviceInfo audioDeviceInfo = audioMan.GetDevices(GetDevicesTargets.Outputs)[newoutput.SelectedIndex];
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
};
I can't find many examples that use the method and they don't usually go with a mediaplayer that is created by button press.
You can use this code
private AudioDeviceInfo findAudioDevice(int deviceType) {
AudioManager manager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] adis = manager.getDevices(GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo adi : adis) {
if (adi.getType() == deviceType) {
return adi;
}
}
return null;
}
Then set your input:
audioRecord.setPreferredDevice(findAudioDevice([newoutput.SelectedIndex]));

How to retrieve IVsDebugger from external DTE for automation in Visual Studio 2019

I am trying to write a VSIX for Visual Studio 2019 that controls multiple instances of the Visual Studio IDE. We are working on a networked project that requires some automation to perform testing of multiple users. In the past I would have used DTE in an external tool, but my understanding is that as of VS2017 the COM guids are no longer globally registered, so doing it within the IDE is the only way.
Regardless, I am trying to get the IVsDebugger so I can track events in the debugger. However, I am having no luck. I can get IVsDebugger2, 3, 4, 5 but not IVSDebugger. Here is the general flow of what I am doing:
void CaptureDebugger()
{
DTE dte = GetDTE(GetRemoteProcessID());
ServiceProvider sp = new ServiceProvider((Microsoft.VisualStudio.OLE.Interop.IServiceProvider)dte);
IVsDebugger vsDebugger = sp.GetService(typeof(SVsShellDebugger)) as IVsDebugger;
// vsDebugger is null!
IVsDebugger2 vsDebugger2 = sp.GetService(typeof(SVsShellDebugger)) as IVsDebugger2;
// vsDebugger2 is not null!
}
/// <summary>
/// Gets the DTE object from any devenv process.
/// </summary>
private static EnvDTE.DTE GetDTE(int processId)
{
object runningObject = null;
IBindCtx bindCtx = null;
IRunningObjectTable rot = null;
IEnumMoniker enumMonikers = null;
try
{
Marshal.ThrowExceptionForHR(CreateBindCtx(reserved: 0, ppbc: out bindCtx));
bindCtx.GetRunningObjectTable(out rot);
rot.EnumRunning(out enumMonikers);
IMoniker[] moniker = new IMoniker[1];
IntPtr numberFetched = IntPtr.Zero;
while (enumMonikers.Next(1, moniker, numberFetched) == 0)
{
IMoniker runningObjectMoniker = moniker[0];
string name = null;
try
{
if (runningObjectMoniker != null)
{
runningObjectMoniker.GetDisplayName(bindCtx, null, out name);
}
}
catch (UnauthorizedAccessException)
{
// Do nothing, there is something in the ROT that we do not have access to.
}
Regex monikerRegex = new Regex(#"!VisualStudio.DTE\.\d+\.\d+\:" + processId, RegexOptions.IgnoreCase);
if (!string.IsNullOrEmpty(name) && monikerRegex.IsMatch(name))
{
Marshal.ThrowExceptionForHR(rot.GetObject(runningObjectMoniker, out runningObject));
}
}
}
finally
{
if (enumMonikers != null)
Marshal.ReleaseComObject(enumMonikers);
if (rot != null)
Marshal.ReleaseComObject(rot);
if (bindCtx != null)
Marshal.ReleaseComObject(bindCtx);
}
return runningObject as EnvDTE.DTE;
}
What confuses me is I get get the local IVsDebugger via the call
var MYDEBUGGER = Package.GetGlobalService(typeof(SVsShellDebugger)) as IVsDebugger;
Which I see is using a GlobalService. I don't think there is an equivalent in the DTE I retrieve.
Any insight?
I ran into this issue as well (however in my case, I'm actually trying to retrieve the IVsDebugger in proc rather than what sounds like out of proc); after debugging into how vsdebug!CDebugger::QueryInterface works I determined the actual issue appears to be that the calling thread in your application needs to be STA.
When the calling thread in your application is MTA, while vsdebug!CDebugger::QueryInterface returns with HRESULT 0
This shortly gets turned into 0x80040155 (REGDB_E_IIDNOTREG) by OLE due to CStdWrapper::GetPSFactory failing to find a proxy DLL for this type
This error in turn gets converted by CRemoteUnknown::RemQueryInterface to 0x80004002 (E_NOINTERFACE)
Which is what is reported back to you if you try and Marshal.QueryInterface in C# to see what's going on directly.
If your program contains in-proc components that live inside the remote Visual Studio process (as mine does) you can retrieve and execute your operations against the IVsDebugger on the UI thread. Otherwise, you can potentially create a new Thread and call thread.SetApartmentState(ApartmentState.STA) on it prior to starting it

Socket connection from Unity to retrieve SUMO's vehicles

I would like to generate a 3D scenario for a traffic simulation.
The main idea would be having SUMO running a simulation and then getting the direction, speed and coordinates (X,Y) from each vehicle, so that I would create 3D models for this cars.
For this purpose, I was thinking about using some kind of TCP/IP communication between Unity and SUMO. Since this is possible while communicating SUMO with a network simulator such as OMNeT++, I was wondering if this would also be possible. I don't need to control the simulation in SUMO from Unity, just retrieve data regarding the vehicles in the network.
Unfortunately, I have no remarkable experience with Unity, so I cannot provide any code trying to achieve this...
EDIT:
As requested, I included some code. However, I only have code in Java.
String configFile = "test/resources/sumo_maps/Test2/Test2.sumo.cfg";
SumoTraciConnection trial = new SumoTraciConnection(configFile,-1);
trial.runServer();
Collection<Vehicle> vehicles = trial.getVehicleRepository().getAll().values();
for(Vehicle car : vehicles){
bw.write(time + " // The vehicle with ID: " + car.getID()+ " is driving "
+ "with a speed of "+ car.getSpeed() + " and is in coordinates x: " +car.getPosition().getX()+
" and y: " + car.getPosition().getY());
bw.newLine();
}
Now, let's proceed to get a bit into the class SumoTraciConnection and its methods. This class is part of the mentioned (in the comments) library Traci4j.
It can be found in GitHub in case you need more info: https://github.com/egueli/TraCI4J/blob/master/src/java/it/polito/appeal/traci/SumoTraciConnection.java
The constructor:
public SumoTraciConnection(String configFile, int randomSeed) {
this.randomSeed = randomSeed;
this.configFile = configFile;
}
Now the runServer() method (I put the one with a boolean argument because if no parameter is given then it is automatically called with a false) Basically, this boolean is used to determine wheter the GUI version of SUMO or the console version will be ran:
public void runServer(boolean withGui) throws IOException, InterruptedException {
retrieveFromURLs(); //Checks if the configFile given has an "http://" at the beggining, in order to download the file
int port = findAvailablePort(); //creates a Socket and finds a port with ServerSocket.getLocalPort()
runSUMO(port, withGui); //It is used to run SUMO with different options, such as the configFile for the simulation, the remote port... sumoProcess is set here as: sumoProcess = Runtime.getRuntime().exec(argsArray);, where argsArray contains the different options mentioned
tryConnect(InetAddress.getLocalHost(), port, sumoProcess); // tryConnect basicaly calls this method tryConnectOnce, which connects as a client to the sumo process mentioned before, and does some checks that everything is correct.
postConnect(); //I will explain this function after
}
postConnect() initialices the DataInput and DataOutput streams and creates the repositories. I show now the relevant parts of the code:
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
vehicles = new HashMap<String, Vehicle>();
edgeRepo = new Repository.Edges(dis, dos, newIDListQuery(Constants.CMD_GET_EDGE_VARIABLE));
addStepAdvanceListener(edgeRepo);
laneRepo = new Repository.Lanes(dis, dos, edgeRepo, newIDListQuery(Constants.CMD_GET_LANE_VARIABLE));
vehicleListQuery = newIDListQuery(Constants.CMD_GET_VEHICLE_VARIABLE);
addStepAdvanceListener(new StepAdvanceListener() {
public void nextStep(double step) {
vehicleListQuery.setObsolete();
}
});
vehicleListBefore = new HashSet<String>(vehicleListQuery.get());
vehicleRepo = new Repository.Vehicles(dis, dos, edgeRepo, laneRepo, vehicles, vehicleListQuery);
addStepAdvanceListener(vehicleRepo);
Where one StepAdvanceListener is just the following(I cannot explain exactly what is this for but I understand that is something that allow us to realize the new simulationstep has been done, so we have to update the repositories):
//Interface for an object that can be notified when the simulation advances by one step.
public interface StepAdvanceListener {
/**
* Callback for step advancement.
* #param step the new simulation time, in seconds
*/
void nextStep(double step);
}
Up to here, it would be the part related to the connection with SUMO. In the next edit (I need some rest right now..) I'll put the parts related with the Repositories and the Data retrieval
Thanks in advance!

How to compare CBUUID objects in Xamarin.ios app

I am developing a Xamarin.iOS Bluetooth enabled app and i have some hurdles which i need to overcome. I am trying to make a connection from C# iOS app to peripheral device; I can connect successfully to the device but after discovering services and characteristics of the device, I need to catch particular service so that i can further use it for different purposes.
Now, the issue is how can i catch particular service from list of services in the cb peripheral object. Each service is identified by CBUUID object and i already know the CBUUID object that the device is returning, but i am not sure how can i compare them so that i know i catch the appropriate service.
If you are targeting iOS 7.1 (or later) then you can compare the System.String Uuid property of CFUUID. That's the easiest way. E.g.
if (cbuuid1.Uuid == cbuuid2.Uuid)
Console.WriteLine ("Equal");
else
Console.WriteLine ("Different");
Otherwise (iOS 7.0 and earlier) you'll need to compare the NSData Data properties of CFUUID. First compare their length and, if equal, compare each byte inside them. E.g.
bool equal = false;
using (var d1 = cbuuid1.Data)
using (var d2 = cbuuid2.Data) {
if (d1.Lenght == d2.Length) {
for (int i=0; i < d1.Lenght; i++) {
if (d1 [i] != d2 [i]) {
equal = false;
break;
}
}
}
}
Console.WriteLine (equal ? "Equal" : "Different");

C# SAPI in a web service

var speechEngine = new SpVoiceClass();
SetVoice(speechEngine, job.Voice);
var fileMode = SpeechStreamFileMode.SSFMCreateForWrite;
var fileStream = new SpFileStream();
try
{
fileStream.Open(filePath, fileMode, false);
speechEngine.AudioOutputStream = fileStream;
speechEngine.Speak(job.Script, SpeechVoiceSpeakFlags.SVSFPurgeBeforeSpeak | SpeechVoiceSpeakFlags.SVSFDefault); //TODO: Change to XML
//Wait for 15 minutes only
speechEngine.WaitUntilDone((uint)new TimeSpan(0, 15, 0).TotalMilliseconds);
}
finally
{
fileStream.Close();
}
This exact code works in a WinForm app, but when I run it inside a webservice I get the following
System.Runtime.InteropServices.COMException was unhandled
Message="Exception from HRESULT: 0x80045003"
Source="Interop.SpeechLib"
ErrorCode=-2147201021
Does anyone have any ideas what might be causing this error? The error code means
SPERR_UNSUPPORTED_FORMAT
For completeness here is the SetVoice method
void SetVoice(SpVoiceClass speechEngine, string voiceName)
{
var voices = speechEngine.GetVoices(null, null);
for (int index = 0; index < voices.Count; index++)
{
var currentToken = (SpObjectToken)voices.Item(index);
if (currentToken.GetDescription(0) == voiceName)
{
speechEngine.SetVoice((ISpObjectToken)currentToken);
return;
}
}
throw new Exception("Voice not found: " + voiceName);
}
I have given full access to USERS on the folder C:\Temp where the file is to be written. Any help would be appreciated!
I don't think the System.Speech works in windows service. It looks like there is a dependency to Shell, which isn't available to services. Try interop with SAPI's C++ interfaces. Some class in System.Runtime.InteropServices may help on that.
Our naming convention requires us to use a non-standard file extension. This works fine in a Winforms app, but failed on our web server. Changing the file extension back to .wav solved this error for us.
Make sure you explicitly set the format on the SPFileStream object. ISpAudio::SetState (which gets called in a lower layer from speechEngine.Speak) will return SPERR_UNSUPPORTED_FORMAT if the format isn't supported.
I just got the webservice to spawn a console app to do the processing. PITA :-)

Categories

Resources