I'm building a visual studio add-in. I copy a solution and do various things to the files inside its and the folder structure. I then load it into visual studio and proceed to load a list of predefined files however when I do this I get an exception and a message saying the files cannot be access for they are in a zombie state.
Here is my code for opening and loading in my Connect.cs
public void OpenCodeFile(String file)
{
try
{
_applicationObject.Documents.Open(file, Constants.vsViewKindCode, false);
}
catch (System.Exception e)
{
System.Console.Out.WriteLine(e.Message);
}
}
public void OpenSolution(String file)
{
_applicationObject.Solution.Open(file);
}
private DTE2 _applicationObject;
private AddIn _addInInstance;
I fixed my problem with the following code:
public void OpenCodeFile(String file)
{
try
{
_applicationObject.ExecuteCommand("File.OpenFile", file);
}
catch (System.Exception e)
{
System.Console.Out.WriteLine(e.Message);
}
}
Related
I am trying to configure my installer so that it will close any instances of the application before installation starts and relaunch the application once installation has finished.
The MS documents provide and example similar to the one below and indicate that the [RunInstaller(true)] annotation specifies whether the Visual Studio Custom Action Installer or the Installutil.exe (Installer Tool) should be invoked when the assembly is installed.
Of course this could mean just about anything...
I am using the Visual Studio Project Installer NuGet package to create the install files (setup.exe and APP.msi files). When configuring the Project Installer there is an option set configure the Custom Actions - I assume this is what the documentation means.
However the Custom Actions has options to add things to the Install, Commit sections - what has to be added to these sections and how does this relate to the Installer class defined below.
This whole area of installation seems to be poorly documented and there seem to be so many options, none of which seem to work properly.
You would think closing any running instances before installing an update and then relaunching after completing the installation would be a no brainer but it seems anything but simple.
Appreciate any assistance with a working example of how this can be achieved.
namespace FocusBracketer
{
[RunInstaller(true)]
public partial class Installer: System.Configuration.Install.Installer
{
public Installer() : base()
{
InitializeComponent();
// Attach the 'BeforeInstall' event.
this.BeforeInstall += new InstallEventHandler(Installer_BeforeInstall);
// Attach the 'Committed' event.
this.Committed += new InstallEventHandler(Installer_Committed);
// Attach the 'Committing' event.
this.Committing += new InstallEventHandler(Installer_Committing);
}
// Event handler for 'BeforeInstall' event.
private void Installer_BeforeInstall(object sender, InstallEventArgs e)
{
Console.WriteLine("");
Console.WriteLine("BeforeInstall Event occurred.");
Console.WriteLine("");
}
// Event handler for 'AfterInstall' event.
private void Installer_AfterInstall(object sender, InstallEventArgs e)
{
Console.WriteLine("");
Console.WriteLine("AfterInstall Event occurred.");
Console.WriteLine("");
System.Diagnostics.Process.Start(System.IO.Path.GetDirectoryName(this.Context.Parameters["AssemblyPath"]) + #"\FocusBracketer.exe");
}
// Event handler for 'Committing' event.
private void Installer_Committing(object sender, InstallEventArgs e)
{
Console.WriteLine("");
Console.WriteLine("Committing Event occurred.");
Console.WriteLine("");
}
// Event handler for 'Committed' event.
private void Installer_Committed(object sender, InstallEventArgs e)
{
Console.WriteLine("");
Console.WriteLine("Committed Event occurred.");
Console.WriteLine("");
}
// Override the 'Install' method.
public override void Install(IDictionary savedState)
{
base.Install(savedState);
}
// Override the 'Commit' method.
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
}
// Override the 'Rollback' method.
public override void Rollback(IDictionary savedState)
{
base.Rollback(savedState);
}
public static void Main()
{
Console.WriteLine("Usage : installutil.exe Installer.exe ");
}
}
}
As far as I know I have followed exactly the instructions:
I have set everything up as suggested. Used my secret key, enabled crashes. Had the set up checked by another developer and see the crash happened in appcenter.ms but still I never see any attached information.
Here's an example:
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
try
{
UIApplication.Main(args, null, "AppDelegate");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Crashes.TrackError(ex,
new Dictionary<string, string> {
{"Main", "Exception"},
{"Device Model", DeviceInfo.Model },
});
throw;
}
}
}
No matter what, when and how my application crashes I still will not get the attached information.
I am wondering has anyone got the attached data for crashes to work with XF ?
We can use AppCenter only after it has been started which according to official documentation on iOS we do it in AppDelegate class in the method FinishedLaunching. But the point is the class Application in Main.cs file is called before AppDelegate class.
If you want to see the attached info then you can try it for example in a XAML code-behind file by manually throwing an exception. Here is an example for a button's click event:
private void TheButton1_OnClicked(object sender, EventArgs e)
{
try
{
throw new DivideByZeroException("Testing attached info!");
}
catch (Exception exception)
{
Crashes.TrackError(exception,
new Dictionary<string, string> {{"Device Model", "My device model" }});
}
}
The attached info on TrackError() method i.e properties dictionary works on both Android and iOS. To see that info you need to go through this in App Center's panel:
From left panel choose Diagnostics.
From Groups section choose your specific group.
From tabs in top section choose Reports.
Choose your specific device.
The attached info is In Stacktrace tab and in Error properties section.
Just to correct, the additional data you attach with exception in TrackError method are mostly in catch blocks or generated exception in TrackError methods, so it will only displayed with those manually logged(TrackError) exceptions.
Crashes are exceptions that are not handled and logged automatically by appcenter so if you look in crash reports there will not be any attached data available.
Additional data sent with exception as properties can be found in reports section of error on appcenter.
I am sure you have initialized Crash service in OnStart method of App.xaml.cs class with correct app secrets and required platforms(android/ios).
I was able to track the crashes. The only difference is am tracking it from the native projects.
For Android in the MainActivity:
protected override void OnCreate(Bundle savedInstanceState)
{
...
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
AndroidEnvironment.UnhandledExceptionRaiser += AndroidEnvironment_UnhandledExceptionRaiser;
...
}
private void AndroidEnvironment_UnhandledExceptionRaiser(object sender, RaiseThrowableEventArgs e)
{
var newExc = new Exception("UnhandledExceptionRaiser", e.Exception as Exception);
LogUnhandledException(newExc);
}
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
{
var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
LogUnhandledException(newExc);
}
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
LogUnhandledException(newExc);
}
internal static void LogUnhandledException(Exception exception)
{
try
{
Crashes.TrackError(exception);
...
}
catch (Exception ex)
{
// just suppress any error logging exceptions
}
}
For iOS in the AppDelegate:
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
...
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
...
}
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
{
var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
LogUnhandledException(newExc);
}
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
LogUnhandledException(newExc);
}
internal static void LogUnhandledException(Exception exception)
{
try
{
...
}
catch
{
// just suppress any error logging exceptions
}
}
I want to know if there is a way to add a cover page to a Visual Studio solution. Is there any extension which allows me to add for example a HTML file, which gets displayed in VS every time I open the solution. I am working with VS versions 2013 and 2015.
Thank you for your help.
Kind regards
You can use the following code as a Visual Commander C# extension to open a startup.html file from the solution directory on opening a solution:
public class E : VisualCommanderExt.IExtension
{
public void SetSite(EnvDTE80.DTE2 DTE_, Microsoft.VisualStudio.Shell.Package package)
{
DTE = DTE_;
events = DTE.Events;
solutionEvents = events.SolutionEvents;
solutionEvents.Opened += OnSolutionOpened;
}
public void Close()
{
solutionEvents.Opened -= OnSolutionOpened;
}
private void OnSolutionOpened()
{
try
{
string startupFile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(DTE.Solution.FullName), "startup.html");
DTE.ItemOperations.OpenFile(startupFile);
}
catch (System.Exception e)
{
}
}
EnvDTE80.DTE2 DTE;
private EnvDTE.Events events;
private EnvDTE.SolutionEvents solutionEvents;
}
I get error
The resource cannot be found.
When I try to implement Ninject in my MVC-3 application. The problem appears to be coming from Global.asax during CreateKernel()
#region Inversion of Control
protected override IKernel CreateKernel()
{
return Container;
}
static IKernel _container;
public static IKernel Container
{
get
{
if (_container == null)
{
_container = new StandardKernel(new SiteModule());
}
return _container;
}
}
internal class SiteModule : NinjectModule
{
public override void Load()
{
bool MOCKDB = true;
//MOCKDB = false;//Stop Mocking
if (MOCKDB)
{
//Set up mock bindings
Bind<iItem>().To<LeadServiceMock>();
}
else
{
//Set up real bindings.
Bind<iItem>().To<LeadService>();
}
}
}
#endregion
If I take the code above out and revert back to System.Web.HttpApplication then things start to work again.
public class MvcApplication : NinjectHttpApplication//:System.Web.HttpApplication
{
I took this code from a previous implementation that I wrote that also still works. If I step through debug
protected override IKernel CreateKernel()
{
return Container;
}
I get an error in both the working program and this broken one:
Locating source for 'c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs'. Checksum: MD5 {b8 b2 52 86 ce 34 de 53 61 76 c9 df ff 65 8c 3f}
The file 'c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs' does not exist.
Looking in script documents for 'c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs'...
Looking in the projects for 'c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs'.
The file was not found in a project.
Looking in directory 'c:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\'...
Looking in directory 'c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\src\mfc\'...
Looking in directory 'c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\src\atl\'...
Looking in directory 'c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\'...
The debug source files settings for the active solution indicate that the debugger will not ask the user to find the file: c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs.
The debugger could not locate the source file 'c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectHttpApplication.cs'.
I suspect I did someting wrong in SiteModule. What am I doing wrong?
Replace Application_Start() with OnApplicationStarted()
//protected void Application_Start()
//{
// AreaRegistration.RegisterAllAreas();
// RegisterGlobalFilters(GlobalFilters.Filters);
// RegisterRoutes(RouteTable.Routes);
//}
protected override void OnApplicationStarted()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
When I start to installing using installutil it gives me following error, I have set ServiceInstaller and ServiceInstallerProcess,
System.InvalidOperationException: Installation failed due to the absence of a ServiceProcessInstaller. The ServiceProcessInstaller must either be the containing installer, or it must be present in the Installers collection on the same installer as the ServiceInstaller.
Any ideas on how to fix the problem?
I had the same problem with the Installer and found that in the [YourInstallerClassName].Designer.cs at InitializeComponent() method, the dfault generated code is Missing add the ServiceProcessInstaller
//
// [YourInstallerClassName]
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceInstaller1});
Just add your ServiceProcessInstaller in my case its:
//
// ProjectInstaller
//
this.Installers.AddRange(new System.Configuration.Install.Installer[] {
this.serviceProcessInstaller1, //--> Missing
this.serviceInstaller1});
and the Setup project works.
Usually, this means you failed to attribute your installer with RunInstaller(true). Here's an example of one I have handy that works:
namespace OnpointConnect.WindowsService
{
[RunInstaller(true)]
public partial class OnpointConnectServiceInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;
public OnpointConnectServiceInstaller()
{
InitializeComponent();
}
public override string HelpText
{
get
{
return
"/name=[service name]\nThe name to give the OnpointConnect Service. " +
"The default is OnpointConnect. Note that each instance of the service should be installed from a unique directory with its own config file and database.";
}
}
public override void Install(IDictionary stateSaver)
{
Initialize();
base.Install(stateSaver);
}
public override void Uninstall(IDictionary stateSaver)
{
Initialize();
base.Uninstall(stateSaver);
}
private void Initialize()
{
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
processInstaller.Account = ServiceAccount.LocalSystem;
serviceInstaller.StartType = ServiceStartMode.Manual;
string serviceName = "OnpointConnect";
if (Context.Parameters["name"] != null)
{
serviceName = Context.Parameters["name"];
}
Context.LogMessage("The service name = " + serviceName);
serviceInstaller.ServiceName = serviceName;
try
{
//stash the service name in a file for later use in the service
var writer = new StreamWriter("ServiceName.dat");
try
{
writer.WriteLine(serviceName);
}
finally
{
writer.Close();
}
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
catch (Exception err)
{
Context.LogMessage("An error occured while creating configuration information for the service. The error is "
+ err.Message);
}
}
}
}