I am looking for an MSbuild file parser. Currently I have written my own that is not complete... but I feel like I am reinventing the wheel building something that surely exists already.
Microsoft.Build.Construction.XXX in microsoft.build.dll (version 4.0+) is a "raw" parser of MSBuild files. It is powerful and complete and analogous to the XML DOM. It works on a single file, doing no evaluation. It's useful for example when you want to run a script over a tree of projects to edit them in some way, perhaps to add a common import statement.
Microsoft.Build.Evaluation.XXX works on evaluated projects -- ie., with all the properties evaluated, imported files pulled in and so forth. It's useful in a development environment - you can read off the files and properties in the project, add new files and so forth. Visual Studio uses it for this purpose.
Before 4.0, there was a completely different, much more limited, and less complete object model in microsoft.build.engine.dll. It still ships with 4.0 but cannot handle some 4.0 syntax. It is deprecated.
I designed and implemented these so I'd be interested in feedback if you have any.
Some info I have found here... http://social.msdn.microsoft.com/Forums/en/msbuild/thread/b3db4d7c-b7d1-4958-9145-bfd34cc75320
In addition there is a small projects with some highlevel samples: http://code.msdn.microsoft.com/msbuildho
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using System.Linq;
class Program
{
static void Main(string[] args)
{
Project testProj = new Project();
testProj.Xml.AddTarget("BuildProjects");
foreach (ProjectTargetElement pti in testProj.Xml.Targets.Where(pti => pti.Name == "BuildProjects"))
{
pti.AddTask("MSBuild");
}
testProj.Save(#"C:\testProj.proj");
}
}
Related
Just googling or duckduckgo'ing
unresolved external symbol IID_ICallbackWithNoReentrancyToApplicationSTA
Only brings up a single direct hit and that doesn't even help the person reporting the problem, so I'm hoping some C++/WinRT people run across this question.
While I can't share all the source (tons of interweaved proprietary files) I can share the scenario and a breakdown of what the code changes were; also, there's very little mention of IID_ICallbackWithNoReentrancyToApplicationSTA anywhere. Coincidentally, it appears on GitHub for some Kenny Kerr stuff. The project I'm having problems with is a C++/WinRT project, so that seems like a relevant trapping, especially since there are mentions of xlang which is supposed to be an abstraction of C++/WinRT.
Scenario: A C++/WinRT library is being consumed by a One Core UAP C++/WinRT application/service. The build breaks when trying to use the lib created by the library when building the app/service.
Code Changes: I implemented some PPL tasks into the library, specifically some concurrency::task<void> that do some I/O on a new thread used in the C++/WinRT lib that is being consumed by the app/service. It's an std::thread that uses a lambda that takes copies of objects and performs I/O. Something like this:
std::thread writer([content_vector, json_string, content_file_name, json_file_name]() {
auto write_content = Helper_IO::Overwrite_Lines_Concurrent(content_file_name, content_vector);
auto write_json = Helper_IO::Overwrite_File_Concurrent(json_file_name, json_string);
write_content.get();
write_json.get();
});
Helper_IO::Overwrite_*_Concurrent are both static and both return a concurrency::task<void>
I've tried using writer.detach() and writer.join(), but the results are the same.
Use Project > Properties > Linker > Input > "Additional Dependencies" setting, add uuid.lib.
Some background, identifiers whose names start with "IID" are {guids}. Data, not code. The MSDN documentation is often inadequate to tell you what library you need to link, too focused on documenting functions. My favorite technique is to use a grep-like tool (I use the Far file manager, a bit to obscure to recommend) and search the SDK's lib directory for the string.
For a long time, I have been very successful at non-invasively customizing many .NET Framework builds by setting CustomBeforeMicrosoftCommonTargets and CustomAfterMicrosoftCommonTargets as environment variables in a command-line shell that corresponds to a given development/build workspace.
I would set these environment variables to point to custom msbuild targets files that would then be automatically imported (before and after respectively) the import of the standard Microsoft provided targets files. This has worked great for a long time, but now .NET Core comes along and I find no mechanism quite like that.
I am aware of Directory.Build.props and that does not appear to be equivalent. For one, it is invasive requiring me to add a file to a source tree that I don't want to necessarily touch in order to customize its build (maybe its an open source project and I don't want to be injecting new files into it). For two, it doesn't provide the dual Before/After import hooks which are very important (if this duality weren't important Microsoft would never have provided it).
I also don't like dropping magic files in magic global locations as my build policies/customizations are themselves versioned source code which can vary from one developer workspace to another (even on the very same machine for the very same developer).
It seems odd that Microsoft would fail to retain such a long-standing and fundamentally useful msbuild customization capability in .NET Core. Am I missing an equivalently powerful, easy to use and non-invasive mechanism? Is it there and I just haven't found it?
CustomBeforeMicrosoftCommonTargets and CustomAfterMicrosoftCommonTargets are still part of MSBuild 15 which is included in VS 2017 and the .NET Core SDK.
Setting them as global variables will still import them and override the default locations used if not set. Use the /bl argument to generate a binary build log and the MSBuild structured log viewer to diagnose issues you may have with it.
I have used Rhapsody Java API, to create a plugin for my rhapsody project. My problem is that it is extremely slow. I have the following function:
private static void collectElements(final IRPModelElement curEl,
final IRPCollection elCol) {
// collect contained elements
for (Object it : curEl.getNestedElements().toList()) {
IRPModelElement element = (IRPModelElement) it;
if (!skipElement(element)) {
// add element itself
elCol.addItem(element);
// descend
collectElements(element, elCol);
}
}
}
that collects all the nested elements of the selected element. My project has about 7500 elements and it takes 22 seconds to do the above function. I tried to get all the elements with selectedElement.getNestedElementsRecursive() and to work with List or HashSet, but the .toList() function is also extremely slow. Any suggestion?
For some reason, Rhapsody add-ins run much (much) faster when run within the internal Rhapsody virtual machine.
To do this, compile your java into a .jar and configure your model with a helper file to link a Rhapsody trigger (generally a tools menu or context menu option) to the jar.
Running add-ins this way uses the common Rhapsody virtual machine and is faster, but beware! The java version depends on what the Rhapsody version you're using is set up for and name clashes can be a problem (if you have multiple add-ins with 2 classes of the same name, Rhapsody will load in only one).
More information on setting up helper files can be found on Andy Lapping (an IBM employee)'s website here.
I've got an old legacy application for communicating via serial port to an embedded controller communications bus. that someone else developed.
The application is written in VB6, and is structured as two projects - a DLL to handle the connection and communications logic, with an application GUI project.
I was hoping to be able to write a new application GUI (in C++ ideally) to use the existing DLL as-is, but I'm having lots of problems working out how to import it.
So I'm wondering, is it even going to be possible to use this old DLL into a C++ project as is? or is it possible to import into a C# project? or a VB.NET project? (would prefer not to use VB, but can if I have to)
Where I am now:
I have the existing compiled executable and DLL, and these run on my system.
I also have the project files, and they're all readable in notepad++ but I don't have VB6, and importing the project into visual studio VB.NET 2008 express isn't at all straightforward. Especially not without a working example to dig through and play with first (DLL project may be importable, but has 50+ things indicated as needing changing in the upgrade report. It also seems to be ignoring three .cls files that look very important to my not particularly VB6-savvy eyes... The application project has a message in the upgrade report about something "missing a design time license" and the only project files that actually seem to come into the project explorer for imported project is the project file itself, and the assembly info file.)
Most examples of how to import a DLL into VS C++ assume you have a solution with the DLL project all compiling nicely alongside your project that will use it. Or at least a .DLL and .lib and .h file... I spoke with the original developer of the code (in another city, we don't work directly) and got a .lib to match my .dll, but still have no .h file.
I'm usually fine to bash through something new, but without a baseline working example of the project even in VB6 that I can get my understanding from, it makes this very hard. Also a lack of similar questions anywher google can find them on the net makes me wonder if this is something i should be even attempting.
I'm working on getting a non-express copy of visual studio if that will make any difference (express worked fine for everything up until now so I never needed anything more) but that will take a number of weeks, most likely.
Any suggestions would be very much appreciated.
thanks for reading!
I have to disclaim this as I have no experience doing it, but merely found that it should be possible given some reading of the docs on the subject.
I'm not sure you'll have much luck with the VB to .NET import/conversion process if there is a lot of low level stuff going on. The existing dll is likely a COM object, no?
It seems like there is some MSDN documentation to get you started from C++ using COM object dlls - and it looks like the #import directive will generate some .h (header) files as well.
http://msdn.microsoft.com/en-us/library/8etzzkb6.aspx
So I would try simply adding an #import directive for it.
#import "somelibrary.dll"
and see what visual studio generates.
Have a look at the following example as well, (copied shamelessly from another forum)
#import "F:\proj\VB6\ActiveXDLL\VBTestDLL.dll"
using namespace VBTestLib;
void CDialogTestDlg::OnButton1()
{
HRESULT hresult;
CLSID clsid;
_CTest *t; // a pointer to the CTest object
_bstr_t bstrA = L"hello";
_bstr_t bstrB = L" world";
_bstr_t bstrR;
::CoInitialize(NULL);
hresult=CLSIDFromProgID(OLESTR("VBTestLib.CTest"), &clsid);
hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
__uuidof(_CTest),(LPVOID*) &t);
if(hresult == S_OK)
{
bstrR = t->vbConcat(bstrA , bstrB);
AfxMessageBox((char*)bstrR);
}
}
I'm working on a project that generates a iOS static library, and some sample code describing how to use the library... The code for the library will not be made public, but the sample code obviously will be. I also use the sample code as a simple test harness for the library, so during dev, I point it directly to the private source files, and test w/o the library dependency. The trouble is, I then have to manually make changes to the sample code project to get it ready for general consumption. I would like an easy way to test changes to the library while in dev mode, then build and package the library along with the sample code (now pointing to an actual .a file + headers) into a releasable file hierarchy. I know how to build everything in manual steps, my question is more to the point of how you set up your folder/project structure, as well as how to set up any build scripts to make the whole process automatic. I am using Xcode v4.3.2
Thanks!
You should setup a project that just builds your static library. It should be the only thing that contains the source for the library. Then you could have a separate project that imports that static library as well as the sample code in order to test it. You shouldn't have to ever point your test application directly at the source. It is best to develop your library from the perspective of people who will be using it (only having access to the public headers and the static library).