Cover page Visualstudio solution - visual-studio

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;
}

Related

How does Windows.System.Configuration.Install.Installer work

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 ");
}
}
}

Call UWP service on Shared project

I have a Xamarin app where I implemented a service to do some printing. I create that service on UWP app because it needs some dependencies of it.
UWP Service:
public class PrintUWPService
{
PrintManager printmgr = PrintManager.GetForCurrentView();
PrintDocument PrintDoc;
PrintDocument printDoc;
PrintTask Task;
private Windows.UI.Xaml.Controls.WebView ViewToPrint = new Windows.UI.Xaml.Controls.WebView();
public PrintUWPService()
{
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
}
public async void Print(WebView viewToPrint, string htmlSource)
{
ViewToPrint.NavigateToString(htmlSource);
if (PrintDoc != null)
{
printDoc.GetPreviewPage -= PrintDoc_GetPreviewPage;
printDoc.Paginate -= PrintDoc_Paginate;
printDoc.AddPages -= PrintDoc_AddPages;
}
printDoc = new PrintDocument();
try
{
printDoc.GetPreviewPage += PrintDoc_GetPreviewPage;
printDoc.Paginate += PrintDoc_Paginate;
printDoc.AddPages += PrintDoc_AddPages;
var showprint = await PrintManager.ShowPrintUIAsync();
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
PrintDoc = null;
GC.Collect();
}
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
var deff = args.Request.GetDeferral();
Task = args.Request.CreatePrintTask("Grocery List", OnPrintTaskSourceRequested);
deff.Complete();
}
async void OnPrintTaskSourceRequested(PrintTaskSourceRequestedArgs args)
{
var def = args.GetDeferral();
await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
args.SetSource(printDoc.DocumentSource);
});
def.Complete();
}
private void PrintDoc_AddPages(object sender, AddPagesEventArgs e)
{
printDoc.AddPage(ViewToPrint);
printDoc.AddPagesComplete();
}
private void PrintDoc_Paginate(object sender, PaginateEventArgs e)
{
PrintTaskOptions opt = Task.Options;
printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}
private void PrintDoc_GetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
printDoc.SetPreviewPage(e.PageNumber, ViewToPrint);
}
}
}
Then I create interface for it:
public interface IPrintUWPService
{
void Print(WebView viewToPrint, string htmlSource);
}
Now inside a class of my shared project I want to call this service as:
private readonly IPrintUWPService _printService = DependencyService.Get<IPrintUWPService>();
But it does not work. it says:
IPrintUWPService does not exist in the current context
So I try to access to UWP class as:
using MyCompany.ProjectName.App.UWP
But it says that "UWP" namespace does not exist. What am I doing wrong? is not possible call service on UWP project inside shared project? Regards
Call UWP DependencyService on Shared project
As #Jason mentioned in above comment, you need declare the interface in the Xamarin Forms project and implement it in the UWP client project.
And please note, after implementing the interface in each platform project, the platform implementations must be registered with the DependencyService, so that Xamarin.Forms can locate them at runtime. Use DependencyAttribute like the following.
[assembly: Dependency(typeof(UWP Client namesapce))]

How to make VSIX installer to register assembly automatically

I have developed a custom code generator and deploy it via a VSIX, the problem is I should register assembly via regasm.exe after installing VSIX, but I have seen some projects such as DSLTool with custom code generation that registers automatically, any body knows how can I have automatically registration in my VSIX project?
You should be able to do the following:
0. Remove old (bad practice) COM code
Edit your project build settings to not have "Register for COM interop" checked.
Edit your AssemblyInfo.cs and set ComVisible to false:
[assembly: ComVisible(false)]
Assuming your generator is named MyCodeGenerator, open the definition of MyCodeGenerator and add the attribute:
[ComVisible(true)]
1. Edit your VSIX project to enable generation of a pkgdef file.
Right click your project in Solution Explorer and select Unload Project.
Right click the unloaded project and select Edit MyProject.csproj, where MyProject is the name of your project.
Locate the XML element <GeneratePkgDefFile>.
If the element exists, ensure that its value is set to true.
Otherwise, add the following to the end of the first <PropertyGroup> element in your project file which does not have a Condition attribute (this is almost always the first PropertyGroup in the file).
<GeneratePkgDefFile>true</GeneratePkgDefFile>
Repeat step 3 to set <CopyBuildOutputToOutputDirectory> to true.
Save and close the .csproj file.
Right click the unloaded project in Solution Explorer and select Reload Project.
Open your project's source.extension.vsixmanifest file and locate the <Content> element. Add the following element as a child:
<VsPackage>|%CurrentProject%|</VsPackage>
If your extension does not provide any other content elements, the entire <Content> element would now be this:
<Content>
<VsPackage>|%CurrentProject%|</VsPackage>
</Content>
2. Define the required attribute types
At the end of this answer are sections for ProvideGeneratorAttribute.cs and ProvideAssemblyObjectAttribute.cs. Add these files to your project.
3. Register the code generator class
Open your project's AssemblyInfo.cs.
Assuming your custom code generator class is named MyCodeGenerator, add the following attribute to the assembly info file.
[assembly: ProvideAssemblyObject(typeof(MyCodeGenerator))]
4. Associate your code generator with the language service
Open your project's AssemblyInfo.cs.
Assuming your custom code generator class is named MyCodeGenerator, and you want to register the code generator with the C# language service, add the following attribute to the assembly info file.
[assembly: ProvideGenerator(
typeof(MyCodeGenerator),
VSConstants.UICONTEXT.CSharpProject_string,
Description = "Description of the generator",
GeneratesDesignTimeSource = true)]
Appendix A: ProvideGeneratorAttribute.cs
Disclaimer: This code is completely untested.
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideGeneratorAttribute : RegistrationAttribute
{
private readonly Type _generatorType;
private readonly Guid _languageServiceGuid;
private string _name;
private string _description;
private bool _generatesDesignTimeSource;
public ProvideGeneratorAttribute(Type generatorType, string languageServiceGuid)
{
if (generatorType == null)
throw new ArgumentNullException("generatorType");
if (languageServiceGuid == null)
throw new ArgumentNullException("languageServiceGuid");
if (string.IsNullOrEmpty(languageServiceGuid))
throw new ArgumentException("languageServiceGuid cannot be empty");
_generatorType = generatorType;
_languageServiceGuid = new Guid(languageServiceGuid);
_name = _generatorType.Name;
}
public Type GeneratorType
{
get
{
return _generatorType;
}
}
public Guid LanguageServiceGuid
{
get
{
return _languageServiceGuid;
}
}
public string Name
{
get
{
return _name;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (string.IsNullOrEmpty(value))
throw new ArgumentException("value cannot be empty");
_name = value;
}
}
public string Description
{
get
{
return _description;
}
set
{
_description = value;
}
}
public bool GeneratesDesignTimeSource
{
get
{
return _generatesDesignTimeSource;
}
set
{
_generatesDesignTimeSource = value;
}
}
private string RegistrationKey
{
get
{
return string.Format(#"Generators\{0}\{1}", LanguageServiceGuid.ToString("B"), Name);
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(RegistrationKey))
{
if (!string.IsNullOrEmpty(Description))
key.SetValue(string.Empty, Description);
key.SetValue("CLSID", GeneratorType.GUID.ToString("B"));
key.SetValue("GeneratesDesignTimeSource", GeneratesDesignTimeSource ? 1 : 0);
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(RegistrationKey);
}
}
Appendix B: ProvideAssemblyObjectAttribute.cs
Disclaimer: This code is completely untested.
using System;
using Microsoft.VisualStudio.Shell;
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class ProvideAssemblyObjectAttribute : RegistrationAttribute
{
private readonly Type _objectType;
private RegistrationMethod _registrationMethod;
public ProvideAssemblyObjectAttribute(Type objectType)
{
if (objectType == null)
throw new ArgumentNullException("objectType");
_objectType = objectType;
}
public Type ObjectType
{
get
{
return _objectType;
}
}
public RegistrationMethod RegistrationMethod
{
get
{
return _registrationMethod;
}
set
{
_registrationMethod = value;
}
}
private string ClsidRegKey
{
get
{
return string.Format(#"CLSID\{0}", ObjectType.GUID.ToString("B"));
}
}
public override void Register(RegistrationContext context)
{
using (Key key = context.CreateKey(ClsidRegKey))
{
key.SetValue(string.Empty, ObjectType.FullName);
key.SetValue("InprocServer32", context.InprocServerPath);
key.SetValue("Class", ObjectType.FullName);
if (context.RegistrationMethod != RegistrationMethod.Default)
_registrationMethod = context.RegistrationMethod;
switch (RegistrationMethod)
{
case Microsoft.VisualStudio.Shell.RegistrationMethod.Default:
case Microsoft.VisualStudio.Shell.RegistrationMethod.Assembly:
key.SetValue("Assembly", ObjectType.Assembly.FullName);
break;
case Microsoft.VisualStudio.Shell.RegistrationMethod.CodeBase:
key.SetValue("CodeBase", context.CodeBase);
break;
default:
throw new InvalidOperationException();
}
key.SetValue("ThreadingModel", "Both");
}
}
public override void Unregister(RegistrationContext context)
{
context.RemoveKey(ClsidRegKey);
}
}

Redirect Console.Write... Methods to Visual Studio's Output Window While Debugging

From a Console Application project in Visual Studio, I want to redirect Console's output to the Output Window while debugging.
Change application type to Windows before debugging. Without Console window, Console.WriteLine works like Trace.WriteLine. Don't forget to reset application back to Console type after debugging.
class DebugWriter : TextWriter
{
public override void WriteLine(string value)
{
Debug.WriteLine(value);
base.WriteLine(value);
}
public override void Write(string value)
{
Debug.Write(value);
base.Write(value);
}
public override Encoding Encoding
{
get { return Encoding.Unicode; }
}
}
class Program
{
static void Main(string[] args)
{
#if DEBUG
if (Debugger.IsAttached)
Console.SetOut(new DebugWriter());
#endif
Console.WriteLine("hi");
}
}
** note that this is roughed together almost pseudo code. it works but needs work :) **
You can change it to System.Diagnostics.Debug.Write();
Note if you're using dkackman's method but you want to write the output to BOTH the console window and the debug window, then you can slightly modify his code like this:
class DebugWriter : TextWriter
{
//save static reference to stdOut
static TextWriter stdOut = Console.Out;
public override void WriteLine(string value)
{
Debug.WriteLine(value);
stdOut.WriteLine(value);
base.WriteLine(value);
}
public override void Write(string value)
{
Debug.Write(value);
stdOut.Write(value);
base.Write(value);
}
public override Encoding Encoding
{
get { return Encoding.Unicode; }
}
}
Try Trace.Write and use DebugView
Actually, there is an easiest way: In the "Options" window of Visual Studio (from the Tools menu), go to "Debugging" then check the option "Redirect All Output Window Text to the Immediate Window".

Visual Studio Addin - "file in zombie state" error

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);
}
}

Resources