Com Error creating Visual Studio 2010 Plugin - visual-studio-2010

I am attempting my first Visual Studio 2010 plugin and am attempting to reference the ActiveSolutionProjects like so
private DTE2 _applicationObject;
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
_applicationObject = (DTE2)application;
...
}
private void load()
{
var theProjects = (System.Array)_applicationObject.ActiveSolutionProjects;
...
}
The
var theProjects = (System.Array)_applicationObject.ActiveSolutionProjects;
line fails with
Error HRESULT E_FAIL has been returned from a call to a COM component.
ErrorCode -2147467259
Any idea how I fix this error?

The issue is there is no active solution selected and a null reference issue. I just wrapped the call in an exception handler and am investigating how to set the active solution through automation.

Related

JavascriptInterface in Xamarin.Android is obsolete and cant invoke C# from Javascript

few months ago I had a custom Xamarin.Android renderer for a webview based on the sample code in
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview
Javascript code was perfectly invoking my C# code however recently after the latest updates, the WebView control is no longer able to invoke the C# action,
(to be more precise, if I am targeting Android 9.0 (API level 28) or higher)
using API level 27 still works fine
after more investigation, I figured out that the compiler gives a warning on [JavascriptInterface] is being obsolete!
https://learn.microsoft.com/en-us/dotnet/api/android.webkit.javascriptinterface?view=xamarin-android-sdk-9
and they advised to use the (IJavascriptInterface) instead
here is the code to be reviewed
[JavascriptInterface]
[Export ("invokeAction")]
public void InvokeAction (string data)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget (out hybridRenderer))
{
hybridRenderer.Element.InvokeAction (data);
}
}
Does anyone know how to implement this properly to fix that and get Javascript to invoke my C# code again.
it still works in my Xamarin.Android project with [JavascriptInterface]
this is part of my sample :
var webview = FindViewById<WebView>(Resource.Id.webView1);
WebSettings settings = webview.Settings;
settings.JavaScriptEnabled = true;
// load the javascript interface method to call the foreground method
webView.AddJavascriptInterface(new MyJSInterface(this), "CSharp");
webview.SetWebViewClient(new WebViewClient());
MyJSInterface class :
class MyJSInterface : Java.Lang.Object
{
Context context;
public MyJSInterface (Context context)
{
this.context = context;
}
[JavascriptInterface]
[Export]
public void ShowToast (string msg)
{
Toast.MakeText(context, msg, ToastLength.Short).Show();
}
}
and in html :
<button type="button" onClick="CSharp.ShowToast ('Call C#')">Call C#</button>
you could refer to https://stackoverflow.com/a/54069075/10768653

AUTOFAC THROWIN EXCEPTION ON DBCONTEXT CONSTRUCTOR PARAMETER IN WINDOWS CONSOLE APP

I am using reverse poco to create entities from an sql database. The tt script I am using is from the on the plural website on the tutorial on EF. In a windows console app I am using Autofac to dependency injection of the the ddbcontext interface ISCDInnoPRDDataLayerDbContext:
public partial class SCDInnoPRDDataLayerDbContext : Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext, ISCDInnoPRDDataLayerDbContext
and of a class that will takes that interface as an input.
public class DLScdHopDataNarRepository :
DLScdBaseRepository<Read_Only_HopDataNar>,
IDLScdHopDataNarRepository
{
public DLScdHopDataNarRepository(ISCDInnoPRDDataLayerDbContext dataLayerDbContext)
: base(dataLayerDbContext)
{
}
Autofac is throwing an exception when I resolve the DLScdHopDataNarRepository class. The exception is on the constructor parameter to the SCDInnoPRDDataLayerDbContext class.
Exceptions:
An exception was thrown while invoking the constructor 'Void .ctor(System.String)' on type 'SCDInnoPRDDataLayerDbContext'.
at SCDInnoPRD.DataLayer.Context.SCDInnoPRDDataLayerDbContext..ctor(String connectionString)
at lambda_method(Closure , Object[] )
at Autofac.Core.Activators.Reflection.ConstructorParameterBinding.Instantiate()
+ InnerException {"The type initializer for 'System.Data.Entity.Internal.AppConfig' threw an exception."}
System.Exception {System.TypeInitializationException}
Below is the autofac registration and the code that resolves the DLScdHopDataNarRepository .
Registration code:
public class SCDInnoPRDModule :Module
{
public string ConnectionString { get; private set; }
public SCDInnoPRDModule(string connectionString)
{
ConnectionString = connectionString;
}
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<SCDInnoPRDDataLayerDbContext>()
.As<ISCDInnoPRDDataLayerDbContext>()
.Keyed<ISCDInnoPRDDataLayerDbContext>("scdb")
.WithParameter((pi, ctx) => pi.ParameterType == typeof(string)
&& pi.Name == "connectionString",
(pi, ctx) => getConnectionString(ConnectionString))
.InstancePerLifetimeScope();
builder.RegisterType<DLScdHopDataNarRepository>()
.As<IDLScdHopDataNarRepository>()
.Keyed<IDLScdHopDataNarRepository>("sdhopres")
.InstancePerLifetimeScope();
builder.RegisterType<DLScdNarsService>()
.As<IDLScdNarsService>()
.Keyed<IDLScdNarsService>("sddlser")
.InstancePerLifetimeScope();
}
private Func< string,string> getConnectionString = delegate (string connectionString)
{
string retVal = connectionString;
return retVal;
};
Resolve code:
using (var config= new ContainerConfig())
{
// register dependency injectopn
var container = config.Configure();
using (var scope = container.BeginLifetimeScope())
try
{ // exception occurs here
var dlscd = container.ResolveNamed("sdhopres");
I have to a point where I can solve this problem. Any suggestion to fix the problem would be appreciated.
Any example source code project that use autofac to do di of a dbcontext in a windows console application would be helpful. I can not find any such project on line.
I can post the entire source code project on GitHub or a website for download if anyone would like to view the code

How to use Prism with Spring.net

I am currently trying to complete this tutorial to get Prism to work with Spring.net.
After referencing Prism4 and Spring.Net through NuGet (or manualy referencing the assemblies), setting up a bootstrapper and running the application I get a "File or Assembly "System, Version=1.0.3300.0, Culture=neutral, ..." FileNotFoundException.
I am succesfully using Prism and Spring.Net in seperate projects. Above exception only occours in a project where Prism AND Spring.net is referenced. Spring.net is not even used in code or app.config. Searching various sites I could not find any informations on version issues or similar problems.
namespace PrismSpringSandbox {
/// <summary>
/// Interaktionslogik für "App.xaml"
/// </summary>
public partial class App : Application {
protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e);
Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();
}
}
}
The Exception occours on "bootstrapper.Run()".
namespace HelloWorld {
public class Bootstrapper : UnityBootstrapper {
protected override DependencyObject CreateShell() {
Shell1 shell = new Shell1();
shell.Activate();
RegionManager.UpdateRegions();
shell.Show();
return shell;
}
protected override IModuleCatalog CreateModuleCatalog() {
DirectoryModuleCatalog catalog = new DirectoryModuleCatalog{ModulePath = #".\"};
//ModuleCatalog catalog =
// new ModuleCatalog().AddModule(typeof(HelloWorldModule.HelloWorldModule)).AddModule(
// typeof(SecondaryModule.SecondaryModule));
return catalog;
}
}
}
Maybe someone knows a solution for this problem when trying to use current Prism with current Spring.Net versions.
Ok, got it!
Problem was a reference to unity while referncing spring.net at the same time.

How to sink COM events from Silverlight?

I want to raise an event from a .NET class, and receive this event in Silverlight code (out-of-browser, using the COM interop support added in SL4).
Can anyone point out the problem in my code? Do I maybe need to do more attribute-decorated interface boilerplate to get this working?
Code:
Rather than write native COM code, I am writing .NET code and exposing it via COM interop.
My event-raising .NET class looks like this:
using System;
namespace TestComInterop2 {
public class TestClass {
public event EventHandler TestEvent;
public void Fire() {
if (TestEvent != null)
TestEvent(this, EventArgs.Empty);
}
}
}
My SL4 client code looks like this:
...
private delegate void HandlerDelegate(dynamic sender, dynamic eventArgs);
private void TestEventSinking(object sender, RoutedEventArgs e)
{
// Create instance of COM-registered .NET class
var testClass = AutomationFactory.CreateObject("TestComInterop2.TestClass");
// Subscribe to event (second line fails with System.Exception)
//
// "Failed to add event handler. Possible reasons include: the object does not
// support this or any events, or something failed while adding the event."
//
AutomationEvent testEvent = AutomationFactory.GetEvent(testClass, "TestEvent");
testEvent.AddEventHandler(new HandlerDelegate(HandleTestEvent));
// Fire the event
testClass.Fire();
}
private void HandleTestEvent(object sender, object eventargs)
{
MessageBox.Show("Event fired");
}
...
Use the [ComSourceInterface] attribute on your class. The relevant MSDN Library topic is here.

How do I create an COM visible class in C#?

I using Visual Studio 2010 (.NET 4). I need to create a COM object (in C#) and have no idea how to get started (what type of project to use,etc.)
OK I found the solution and I'll write it here for the common good.
Start VS2010 as administrator.
Open a class library project (exmaple - MyProject).
Add a new interface to the project (see example below).
Add a using System.Runtime.InteropServices; to the file
Add the attributes InterfaceType, Guid to the interface.
You can generate a Guid using Tools->Generate GUID (option 4).
Add a class that implement the interface.
Add the attributes ClassInterface, Guid, ProgId to the interface.
ProgId convention is {namespace}.{class}
Under the Properties folder in the project in the AssemblyInfo file set ComVisible to true.
In the project properties menu, in the build tab mark "Register for COM interop"
Build the project
now you can use your COM object by using it's ProgID.
example:
the C# code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace Launcher
{
[InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX")]
public interface ILauncher
{
void launch();
}
[ClassInterface(ClassInterfaceType.None), Guid("YYYYYYYY-YYYY-YYYY-YYYY-YYYYYYYYYYY"), ProgId("Launcher.Launcher")]
public class Launcher : ILauncher
{
private string path = null;
public void launch()
{
Console.WriteLine("I launch scripts for a living.");
}
}
}
and VBScript using the COM:
set obj = createObject("PSLauncher.PSLauncher")
obj.launch()
and the output will be:
I launch scripts for a living
Creation Steps
Start Visual Studio 2013 as administrator
Install Visual Studio extension Microsoft Visual Studio Installer Projects
Create a class library project (WinFormActivex)
Create your example window form (MainWindow)
Create a new component interface(ILauncher)
Create a new security interface (IObjectSafety)
Create the component control (Launcher) that implement interfaces and launch the window.
Check that all GUIDs are generated by you
Check that the project is marked for COM
Create the setup project (LauncherInstaller) with the primary output of WinFormActivex with the property Register = vsdrpCOM
Install LauncherInstaller
Run your test page in explorer (test.html)
MainWindow
You can create a normal Form, here is pre-generated.
public partial class MainWindow : Form
{
public MainWindow()
{
InitializeComponent();
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(42, 23);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(100, 20);
this.textBox1.TabIndex = 0;
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(42, 65);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(100, 20);
this.textBox2.TabIndex = 0;
//
// MainWindow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Name = "MainWindow";
this.Text = "MainWindow";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
}
ILauncher
using System.Runtime.InteropServices;
namespace WinFormActivex
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("94D26775-05E0-4B9C-BC73-C06FE915CF89")]
public interface ILauncher
{
void ShowWindow();
}
}
IObjectSafety
[ComImport()]
[Guid("51105418-2E5C-4667-BFD6-50C71C5FD15C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IObjectSafety
{
[PreserveSig()]
int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
[PreserveSig()]
int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions);
}
Launcher
Please generate your GUID here.
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[Guid("D100C392-030A-411C-92B6-4DBE9AC7AA5A")]
[ProgId("WinFormActivex.Launcher")]
[ComDefaultInterface(typeof(ILauncher))]
public class Launcher : UserControl, ILauncher, IObjectSafety
{
#region [ ILauncher ]
public void ShowWindow()
{
var f = new MainWindow();
f.StartPosition = FormStartPosition.Manual;
f.Location = Screen.AllScreens[0].Bounds.Location;
f.WindowState = FormWindowState.Normal;
f.WindowState = FormWindowState.Maximized;
f.ShowInTaskbar = false;
f.Show();
}
#endregion
#region [ IObjectSafety ]
public enum ObjectSafetyOptions
{
INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001,
INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002,
INTERFACE_USES_DISPEX = 0x00000004,
INTERFACE_USES_SECURITY_MANAGER = 0x00000008
};
public int GetInterfaceSafetyOptions(ref Guid riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
{
ObjectSafetyOptions m_options = ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_CALLER | ObjectSafetyOptions.INTERFACESAFE_FOR_UNTRUSTED_DATA;
pdwSupportedOptions = (int)m_options;
pdwEnabledOptions = (int)m_options;
return 0;
}
public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
{
return 0;
}
#endregion
}
test.html
Please check that your CLSID match (Launcher) GUID.
<html>
<head>
<objectname="activexLauncher" style='display:none' id='activexLauncher' classid='CLSID:D100C392-030A-411C-92B6-4DBE9AC7AA5A' codebase='WinFormActivex'></object>
<script language="javascript">
<!-- Load the ActiveX object -->
var x = new ActiveXObject("WinFormActivex.Launcher");
alert(x.GetText());
</script>
</head>
<body>
</body>
</html>
References
Stack Overflow question I always use as reference
Activex tag you should read
Old Microsoft guide
Article on creating the acrivex control with security options
Article about creating the window
You could use a class library project. Declare a type with methods that will be exposed as a COM object.
Make sure that the assembly has been made COM-visible:
And finally register it using regasm.exe:
regasm.exe /codebase mylib.dll
Now the assembly is exposed as a COM object and the type you declared can be consumed by any client that supports COM.

Resources