I have installed the winui extension to Visual Studio 19. I created a new project using the Win UI desktop template. I have built the two projects created (one is the package). I try to run the project before adding any code and it immediately crashes at start up. The error is
COMException: Class not registered (0x80040154 (REGDB_E_CLASSNOTREG))
The error occurs at the last line of this subroutine (marked with **)
public static class Program
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.UI.Xaml.Markup.Compiler"," 0.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.STAThreadAttribute]
static void Main(string[] args)
{
global::WinRT.ComWrappersSupport.InitializeComWrappers();
**global::Microsoft.UI.Xaml.Application.Start((p) => {
var context = new global::Microsoft.UI.Dispatching.DispatcherQueueSynchronizationContext(global::Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread());**
global::System.Threading.SynchronizationContext.SetSynchronizationContext(context);
new App();
});
}
}
I'm at a loss to fix the error.
I managed to solve the problem. with the help of this post
https://gitmemory.com/issue/microsoft/microsoft-ui-xaml/5054/845542110
I need to deploy the solution. (Go to solution properties, Configuration and check the build and deploy boxes.
Deploy the package application.
Set the package application to the Startup project.
run the project.
I want to execute Visual Studio command to import/export settings file in C#.
Can I do this using DTE2. If yes how to do?
How to initialize DTE2 and do..Please give the complete code.
Can I make use of this?
ExecuteCommand("Tools.ImportandExportSettings", "/export:\"C:/temp/setttings.vssettings\"")
If yes - then how to initialize dte2 and call the method?
You can try the following code to execute Visual Studio command to import/export settings file in c#.
First, you need to install nuget package ->EnvDTE.
Second, you can use the following console app to get the settings file.
class Program
{
static void Main(string[] args)
{
var filename = "D:\\own.vssettings";
var dte = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.
GetActiveObject("VisualStudio.DTE.16.0"); // version neutral
dte.ExecuteCommand("Tools.ImportandExportSettings", "/export:" + filename);
}
}
We need to note that if your vs version is vs 2010, we should use VisualStudio.DTE.10.0,
If your vs version is vs2013, we should use VisualStudio.DTE.12.0, If your vs version is
vs2017 or later, we should use VisualStudio.DTE.16.0.
My vs version is vs2017, so I used VisualStudio.DTE.16.0.
Result:(The part of setting file)
I print output on the console in WPF and ASP.NET-MVC applications by:
System.Diagnostics.Debug.WriteLine("text");
how to programatically clear the output window?
// Import EnvDTE and EnvDTE80 into your project
using EnvDTE;
using EnvDTE80;
protected void ClearOutput()
{
DTE2 ide = (DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.12.0");
ide.ToolWindows.OutputWindow.OutputWindowPanes.Item("Debug").Clear();
System.Runtime.InteropServices.Marshal.ReleaseComObject(ide);
}
This is what I use in VS2013, Win10, x64:
private static void ClearVS2013DebugWindow()
{
// add reference to "C:\Program Files (x86)\Common Files\microsoft shared\MSEnv\PublicAssemblies\envdte.dll"
EnvDTE.DTE ide = (EnvDTE.DTE)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.12.0");
if (ide != null)
{
ide.ExecuteCommand("Edit.ClearOutputWindow", "");
System.Runtime.InteropServices.Marshal.ReleaseComObject(ide);
}
}
Credit to the answers above.
Within the underlying APIs, the debug output is a forward only stream - you shouldn't assume that it is only viewable within Visual Studio. Debug output can only be written by an application, and if you need more detailed control, it should be shown within the User Interface of your application (whether that is a console window, which can be cleared; or a WinForms application, or WPF, etc.)
I'm working for a custom installer developed in Visual Studio 2008 (Setup & Deployment > Setup project) for a C# project. I'd like to run a batch file (*.bat) after installation is finished. How can I do that?
You will have to extend the Installer class and override the Committed event.
Here is an example. Hope you will be able to find how to run a .bat file in C#.
[RunInstaller(true)]
public class ServiceInstaller : Installer
{
string strServiceName = "MyServiceName";
public ServiceInstaller()
{
// .............
this.Committed += new InstallEventHandler(ServiceInstaller_Committed);
}
void ServiceInstaller_Committed(object sender, InstallEventArgs e)
{
// Run your batch file
}
}
Custom Install Action is another option. Here is a similar thread for that.
You can run a batch file using cmd.exe, anyway it is what executes batch files.
Start it this way: cmd.exe /c <path-to-batch>\batchfile.bat.
I have written an installation class that extends Installer and overrides afterInstall, but I'm getting a null pointer exception. How can I go about debugging my class?
Something that is handy for hard to debug sections of code is
System.Diagnostics.Debugger.Break()
Will throw a breakpoint caught by any installed debugger (VStudio, WinDbg, Remote debugger etc...).
Use it to debug really tricky areas where regular F5+Go or "Attach to Process" is difficult or impossible to perform, some examples include:
short-lived processes
time-sensitive processes
breaking into spawned sub-processes
installers
service stop/start
distributed systems
The best way I've found is to write a unit test, and new up and initialize your installer class from your unit test:
[TestClass] public class InstallerTest {
[TestMethod]
public void InstallTest() {
// substitute with your installer component here
DataWarehouseInstall installer = new DataWarehouseInstall();
string assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string installLogFilePath = Path.Combine(assemblyDirectory, "install.log");
installer.Context = new System.Configuration.Install.InstallContext(installLogFilePath, null);
// Refactor to set any parameters for your installer here
installer.Context.Parameters.Add("Server", ".");
//installer.Context.Parameters.Add("User", "");
//installer.Context.Parameters.Add("Password", "");
installer.Context.Parameters.Add("DatabaseName", "MyDatabaseInstallMsiTest");
//installer.Context.Parameters.Add("DatabasePath", "");
// Our test isn't injecting any save state so we give a default instance for the stateSaver
installer.Install(new Hashtable());
} }
At least then it takes advantage of the IDE tooling better. This is especially helpful for very large installers with LOTS of components. Then you can also create ordered unit tests and run them in sequence to mimic your installer during debug or your automated builds.
Another tip would be general SOLID/GRASS software principles...develop in neat/thin layers, keeping your actual "custom action" installer logic very simple and instead call into any reusable API stuff you have that is specific to your installer(s), just as we are used to with UI development. (The installer is just another UI anyway.) This is especially key if your goal is to have a certain UI experience shared across all installers of your products.
Surprised no one has actually answered. Put a MessageBox.Show("hello") into your custom action's Install() member. Build the deployment in debug config. Install. When the MessageBox appears, go into VS IDE, Debug, Attach Process and look for the instance of msiexec that is labeled "Managed". Attach the debugger to that instance of msiexec. Now go back to the source of your custom action and place a breakpoint right after the call to MessageBox.Show(). Close the MessageBox and your breakpoint will be hit, and you're debugging in the IDE!
attach the installer process to Visual studio in Debug->Processes->Attach or CTRL + ALT + P
set the breakpoint and you should be able to go
In your installer method add Debugger.Launch() statement which will launch "Visual Studio just in time debugger" where you can attach an instance of visual studio and debug your installer class (MSI). This should work in Visual Studio 2010 as well. But you need to have administrative rights to do this. If you don't have administrative rights, you might have issues. So, log in as administrator for debugging MSI. For example:
public override void Install(System.Collections.IDictionary stateSaver)
{
Debugger.Launch();
base.Install(stateSaver);
}
In visual studio 2005, even Debugger.Break() use to work but somehow this does not work with Visual Studio 2010.
This is what actually worked for me.
System.Diagnostics.Debugger.Launch();
Then right click on the Installer Project and press "Install"
None of above worked for me. This is what actually worked. Note that you need to put insert "both" lines.
using System.Diagnostics;
MessageBox.Show("Test is about to begin");
Debugger.Launch();
I use EventLog.WriteEntry("source", "message"), and check the EventLog when installing. Maybe not optimal, but works for me :)
I use the following class to write a simple log into the target directory. In my opinion, it's easier than trying to use the Visual Studio debugger.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyCompany.Deployment
{
/// <summary>
/// Enables a quick and easy method of debugging custom actions.
/// </summary>
class LogFile
{
const string FileName = "MyCompany.Deployment.log";
readonly string _filePath;
public LogFile(string primaryOutputPath)
{
var dir = Path.GetDirectoryName(primaryOutputPath);
_filePath = Path.Combine(dir, FileName);
}
public void Print(Exception ex)
{
File.AppendAllText(_filePath, "Error: " + ex.Message + Environment.NewLine +
"Stack Trace: " + Environment.NewLine + ex.StackTrace + Environment.NewLine);
}
public void Print(string format, params object[] args)
{
var text = String.Format(format, args) + Environment.NewLine;
File.AppendAllText(_filePath, text);
}
public void PrintLine() { Print(""); }
}
}
For logging purposes (in 3.5) what about using:
Context.LogMessage("My message");
Write the following code in the beginning of the method that you want to debug
#if DEBUG
MessageBox.Show(Process.GetCurrentProcess().Id.ToString());
#endif
So when your method is called, the above code will be hit and you can then attach the debugger to the process(ctrl+alt+p) using the above process ID. You may have to start VS with elevated permissions.
build a VM, install Visual studio, make a copy of it (or create a differencing Virtual HDD) and run the installer under the debugger under the VM.
That is what I would do (but I'm no expert).
You can also use the installUtil.exe utility to test your installer component.
In case you created a c# class assembly with your Installer class, Change your debug settings to start the external program 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe'
and enter your commandline arguments accordingly (e.g. /Args=myargument "path to the assembly")
As last set your breakpoints, press f5 and you're set to debug your code.
--paralax
You might automate debugging of installer projects by adding following section to either .csproj or .csproj.user file:
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<StartAction>Program</StartAction>
<StartProgram>$(MSBuildBinPath)\installutil.exe</StartProgram>
<StartArguments>$(AssemblyName).dll</StartArguments>
</PropertyGroup>
Use project file if you want other developers benefit from this change and .user file if you want to use it by yourself.