I am using the following code to try to programmatically create Visual Studio 2015 projects on the fly from within an existing Console Application. Why you ask? We are putting together a library of all our code snippets and we want a test/proof test solution for each one, and since we have hundreds of these, we aren't going to do it manually.
Ultimately this will be in an MVC5 app as its own project (class library?) but for now we are just trying to get it functional within this console application.
I am trying to create a new solution with 2 projects (a console application and a unit test project).I am also not even sure I need the unit test project, or whether one even works with a console app since there is no option to add a unit test to a console app in VS2015 solution generation.
Here is the code;
public class CreateConsoleProjectsProgrammatically
{
private const string Vs2015Type = "VisualStudio.DTE.14.0";
private const string Vs2015ConsoleProject = #"X:\Code Library\Helpers\ConsoleApplication\csConsoleApplication.vstemplate";
private const string Vs2015UnitTestProject = #"X:\Code Library\Helpers\UnitTestProject\UnitTestProject.vstemplate";
private const string Vs2015CodeLibraryBasepath = #"X:\Code Library";
public static void CreateVsConsoleProjectProgrammatically(string filename)
{
// Create a solution with two projects in it, based on project
// templates, a console project and a unit test project.
var vsType = Type.GetTypeFromProgID(Vs2015Type);
//error line is below
var vsInstance= Activator.CreateInstance(vsType, true);
EnvDTE.DTE dte = (EnvDTE.DTE)vsInstance;
dte.MainWindow.Visible = false; // optional: set to true if you want to see VS doing its thing
// create a new solution
dte.Solution.Create(#"X:\Code Library\", filename);
var solution = dte.Solution;
// create a C# console application
solution.AddFromTemplate(Vs2015ConsoleProject,Path.Combine(Vs2015CodeLibraryBasepath,filename), filename);
// create a unit test project
solution.AddFromTemplate(Vs2015UnitTestProject, Path.Combine(Vs2015CodeLibraryBasepath, filename + "_Test"), filename + "_Test");
// save and quit
dte.ExecuteCommand("File.SaveAll");
dte.Quit();
}
}
Here is the error which is from the Activator.CreateInstance
Creating an instance of the COM component with CLSID {A2FA2136-EB44-4D10-A1D3-6FE1D63A7C05} from the IClassFactory failed due to the following error: 8001010a The message filter indicated that the application is busy. (Exception from HRESULT: 0x8001010A (RPC_E_SERVERCALL_RETRYLATER)).
Not sure why I am getting a server busy error. It almost seems like its because VS is already open? But how else would the new solution be generated? I tried closing the solution and reopening it but that did nothing to solve the issue.
I also thought it may have been a connectivity issue, so I moved all the files and directories to C:\ but it produced the same error, so it wasn't an issue of using a networked drive location.
I also tried using
EnvDTE80.DTE2 dte2 = (EnvDTE100.DTE2)vsInstance;
but DTE2 is not an available property/method on EnvDTE100 according to the editor, even though I found some examples using it on the net.
Related
I have created a Windows shell extension that provides a menu to users when they right-click in File Explorer. This then invokes a small dialogue App.
I'm a novice at software development so there is probably some schoolboy error I'm making but I just can't see it.
For testing purposes I am hard-coding the path to the EXE and ensuring it's present on the VM.
private void CallExteralAddLocation(string sFullPath)
{
string sEXE = Path.Combine(Application.StartupPath, "AddLocation.exe");
WriteLog(sEXE);
// during testing, hard-code this path
sEXE = "C:\\temp\\AddLocation.exe";
System.Diagnostics.Process.Start(sEXE, sFullPath);
}
private void WriteLog(string sText)
{
using (StreamWriter sr = new StreamWriter("C:\\Temp\\ShellExtLog.txt"))
{
sr.WriteLine(sText);
}
}
It works fine on my host machine but when running on a VM running Windows 10, which is where I am testing it, the dialogue App does not get invoked.
I have checked that I can invoke the AddLocation.exe from a command window on the VM and that works as expected. So it looks like it's just not getting called.
As it's a shell extension it's very difficult to debug. I tried using MessageBoxes and writing to the console but those wouldn't work, so I have added the WriteLog so that I have some idea of what it's doing.
This works on the host machine i.e. a log file is created and it shows the path to the EXE, but no log file is created on the VM.
NOTE: When testing on either machine, I'm installing afresh from the application's MSI. Also note that the host is running Windows 11 and the VM is running Windows 10.
So, why does the same code fail to either run the EXE or create a log file on the VM?
I eventually worked out that the problem was how C# handles strings.
If you read through my problem above you will see that, weirdly the same code worked fine on Windows 11 but not on Windows 10.
The problem was that I was letting the compiler interpret the path string. I had 'escaped' the slashes as shown here and it should have worked fine:
sEXE = "C:\\temp\\AddLocation.exe";
Changing it to the following resolved the problem so that it works on both now:
sEXE = #"C:\temp\AddLocation.exe";
Similarly, whereas it wouldn't create a log file on Win10, changing the path to the log file to the following fixed it:
using (StreamWriter sr = new StreamWriter(#"C:\Temp\ShellExtLog.txt"))
First I run the following setup
Xamarin Forms - Entity Framework Core 2.2 - SQLite - Android - DEBUG
And everything works fine. The .db file is generated properly and queries are executed on the database.
Then I prepared the application for production and I changed the DEBUG to RELEASE compiled, and packed into an apk. As installed on the device the application always crashes when calling either Database.Migrate() or Database.EnsureCreated()
The scenario is the same on every application I tried. App runs properly in emulator and on the device being in DEBUG mode. App crashes on every Android device when creating the database.
This is the instantiation of the DbContext
public ItemContext(DbContextOptions<ItemContext> options)
: base(options)
{
//Database.Migrate();
Database.EnsureCreated();
}
This is how the constructor is called
public void Load()
{
string databasePath = DependencyService.Get<ILocalFileStorageService>().GetDatabaseFilePath("ItemSQLite.db");
string connectionString = $"Filename={databasePath}";
DbContextOptions<ItemContext> options = new DbContextOptionsBuilder<ItemContext>()
.UseSqlite(connectionString)
.Options;
dataService = new DataService(new ItemContext(options));
}
This is how I retrieve the filepath on Android.
public string GetDatabaseFilePath(string fileName)
{
string path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(path, fileName);
}
When looking on the Android Device Monitor a very long error is displayed
The beginning is
somewhere later there is the EnsureCreated method listed
The Question: Why is this happening and how to make the application runnable on production?
Do you have linking enabled in your release build configuration? According to this https://github.com/aspnet/EntityFrameworkCore/issues/10963 the compiler requires hints to not link assemblies accessed through reflection internally in EF Core. You can try switching to "Link sdk assemblies only" to see if that fixes the issue. If it does then you will need to identify the assemblies and mark them to be preserved. There's some more info on that here: Xamarin iOS Linker Issue and here: https://learn.microsoft.com/en-us/xamarin/android/deploy-test/linker#linkskip.
I can't personally test at the moment but I think putting [assembly: Preserve (typeof (System.Linq.Queryable), AllMembers = true)] (or whatever assembly might be causing it) in your App.xaml.cs should do it.
I'm trying to run a local SSIS package from a C# console application. I've built both the package and the application using .Net 4.5.1 in VisualStudio 2012. When I say "local" I mean the SSIS package hasn't been deployed to a SQL Server; I'm just trying to call the .dtsx file from the file system. The SSIS package runs fine from within VisualStudio. Here's my code:
string pkgLocation = #"C:\Users\06717\Documents\Visual Studio 2012\Projects\RMA_Data_Cleanup\RMA_Data_Cleanup\";
string pkgName = "Package.dtsx";
Application app = new Application();
Package pkg = new Package();
DTSExecResult pkgResults = new DTSExecResult();
try
{
pkg = app.LoadPackage(pkgLocation + pkgName, null);
There's more after this, obviously, but the problem comes with the app.LoadPackage line. When I try to run it, this exception gets thrown:
The package failed to load due to error 0xC0011008 "Error loading from XML. No further detailed error information can be specified for this problem because no Events object was passed where detailed error information can be stored.". This occurs when CPackage::LoadFromXML fails.
I've googled this error message, and I haven't found anything that seems to apply to my case. One thing that occurs to me is that maybe I'm calling the wrong dtsx file. There's another one in the obj\Development folder. I've tried calling that one too, but I get the same exception. Am I calling the right file? Is there something I need to do from within Visual Studio, other than build the package, before I can do this? (pkgResults = Success, BTW)
I have the following function that I am attempting to use to determine the length of an MP3 file:
public static string GetMP3DurationBackup(string Filename)
{
string Duration = null;
WMPLib.WindowsMediaPlayer w = new WMPLib.WindowsMediaPlayer();
WMPLib.IWMPMedia m = w.newMedia(Filename);
if (m != null)
{
Duration = m.durationString;
}
w.close();
return Duration;
}
I have run into an issue where I get the following error:
Retrieving the COM class factory for component with CLSID
{6BF52A52-394A-11D3-B153-00C04F79FAA6} failed due to the following
error: 80040154..
when I call the above function from my web application (call below):
string test = MediaUtil.GetMP3DurationBackup(#"C:\Temp\Audio\bad.mp3");
But when I call it from a console application test harness I created (exact same call as above) it works fine. I have set the project that contains the function to target x86 in the Build properties, but that did not fix the issue.
Does anyone know why this would happen? Suggestions on where to start to debug this?
UPDATED FOR BOUNTY:
Ok, I've tried a number of things but I am still getting this error. Among other things I have tried the steps below which I felt were the most promising, but no dice:
Went into my registry and confirmed that the value at:
HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{6BF52A52-394A-11d3-B153-00C04F79FAA6}\InprocServer32
is refering to C:\WINDOWS\SysWOW64\wmp.dll
Opened command prompt,
navigated to C:\WINDOWS\SysWow64, ran: regsvr32.exe wmp.dll
I have created a console app test harness and I am able to reproduce the error if I run the test project in x64. If I switch it to x86 it works fine.
Does anyone have any idea of why the above would not resolve the issue? Suggestions on where to look next?
You say it doesn't work in x64, but you try to register the 32-bit version of wmp.dll (C:\Windows\SysWow64 contains 32-bit assemblies).
Try to register the x64 version of wmp.dll, which is located in C:\Windows\System32 on a 64-bit platform.
If you don't have this file then there probably is no 64bit Windows Media Player available for your platform. But there is a workaround:
Create a 32-bit console application that takes the mp3 filename as command line argument and outputs the duration to stdout using Console.WriteLine, then in the webapp, you call the console application and capture the output like in this example on MSDN
Give this lib a whirl. Its fast and has no special requirements for software to be installed on the machine.
http://naudio.codeplex.com/
I am trying to connect to skydrive with this code, it is console C# application:
var client = new SkyDriveServiceClient();
client.LogOn("username", "password");
and I got this exception: The operation has timed out.
Anyone know what is solution for this problem?
Ok, download the latest version (Changset 68942) from this
location. After download open the project (located in folder trunk/src/SkyDriveServiceClient.sln) in Visual Studio and change the variable SkyDocsServiceUri in the class SkyDocsServiceClient to the following:
public static readonly Uri SkyDocsServiceUri = new Uri("https://docs.live.net/SkyDocsService.svc");
After the change compile the project to build the assembly file. Then you need to reference the assembly from your project and try to execute your code again.