Finding builds in Team Explorer's "My Builds" - visual-studio-2012

I'm writing a Visual Studio 2012 add-in which extends Build Explorer - basically, I add a context menu option for every build (completed or running, but not queued). Following a blog post about doing this in VS2010, I managed to do so for builds that appear in Builder Explorer - hooray!
Now, my context menu also appear in Team Explorer's Builds pages, My Builds section. However, when I get the callback, I can't find the actual builds anywhere!
Here's my beforeQueryStatus event handler, where I try to find out whether I have a build to show or not:
private void OpenCompletedInBuildExplorerBeforeQueryStatus(object sender, EventArgs e)
{
var cmd = (OleMenuCommand)sender;
var vsTfBuild = (IVsTeamFoundationBuild)GetService(typeof(IVsTeamFoundationBuild));
// This finds builds in Build Explorer window
cmd.Enabled = (vsTfBuild.BuildExplorer.CompletedView.SelectedBuilds.Length == 1
&& vsTfBuild.BuildExplorer.QueuedView.SelectedBuilds.Length == 0); // No build _requests_ are selected
// This tries to find builds in Team Explorer's Builds page, My Builds section
var teamExplorer = (ITeamExplorer)GetService(typeof(ITeamExplorer));
var page = teamExplorer.CurrentPage as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageBase;
var vm = page.ViewModel;
// does not compile: 'Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel' is inaccessible due to its protection level
var vm_private = vm as Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel;
// But debugger shows that if it did, my builds would be here:
var builds = vm_private.MyBuilds;
}
Is there a way to get the list of builds?
More generally, is there a way to get some "window which this context menu belong to"? Currently I'm just looking around in parts of VS I assume would have builds...

I managed to get the build using reflection:
var teamExplorer = (ITeamExplorer)GetService(typeof(ITeamExplorer));
var BuildsPage = teamExplorer.CurrentPage as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageBase;
var PageViewModel = BuildsPage.ViewModel as Microsoft.TeamFoundation.Controls.WPF.TeamExplorer.TeamExplorerPageViewModelBase;
// PageViewModel is actually Microsoft.TeamFoundation.Build.Controls.BuildsPageViewModel. But, it's private, so get SelectedBuilds through reflection
var SelectedBuilds = PageViewModel.GetType().GetProperty("SelectedBuilds").GetValue(PageViewModel) as System.Collections.IList;
if (SelectedBuilds.Count != 1)
{
cmd.Enabled = false;
return;
}
object BuildModel = SelectedBuilds[0];
// BuildModel is actually Microsoft.TeamFoundation.Build.Controls.BuildModel. But, it's private, so get UriToOpen through reflection
var BuildUri = BuildModel.GetType().GetProperty("UriToOpen").GetValue(BuildModel) as Uri;
// TODO: Use BuildUri...
cmd.Enabled = true;

Related

How to use LibvlcSharp on Linux?

I'm trying to use LibvlcSharp on a linux installation (Ubuntu 18.04). I'm following all the instructions, including this one Getting started on LibVLCSharp.Gtk for Linux but my application always crash. It's working perfectly on windows, because there we can add VideoLAN.LibVLC.Windows package, but I couldn't find someting similar for Linux.
My code:
static void Main(string[] args)
{
// Record in a file "record.ts" located in the bin folder next to the app
var currentDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
var destination = Path.Combine(currentDirectory, "record.ts");
// Load native libvlc library
Core.Initialize();
using (var libvlc = new LibVLC())
//var libvlc = "/usr/lib/x86_64-linux-gnu/";
using (var mediaPlayer = new MediaPlayer(libvlc))
{
// Redirect log output to the console
libvlc.Log += (sender, e) => Console.WriteLine($"[{e.Level}] {e.Module}:{e.Message}");
// Create new media with HLS link
var urlRadio = "http://transamerica.crossradio.com.br:9126/live.mp3";
var media = new Media(libvlc, urlRadio, FromType.FromLocation);
// Define stream output options.
// In this case stream to a file with the given path and play locally the stream while streaming it.
media.AddOption(":sout=#file{dst=" + destination + "}");
media.AddOption(":sout-keep");
// Start recording
mediaPlayer.Play(media);
Console.WriteLine($"Recording in {destination}");
Console.WriteLine("Press any key to exit");
Console.ReadKey();
}
}
The error message:
Unhandled Exception: LibVLCSharp.Shared.VLCException: Failed to perform instanciation on the native side. Make sure you installed the correct VideoLAN.LibVLC.[YourPlatform] package in your platform specific project
at LibVLCSharp.Shared.Internal..ctor(Func1 create, Action1 release)
at RadioRecorderLibVlcSharp.Program.Main(String[] args) in /media/RadioRecorderLibVlcSharp/Program.cs:line 19
Anyone can help me?
thanks
Can you try apt-get install vlc? That seems to help getting all the required plugins/deps on your system (though it will pull vlc 2.x from the official ubuntu rep probably).

Azure ARM uniqueString function mimic

I need to deploy Sql Databases into an Azure Sql Server using to ways: the ARM template way, and a more custom way using C# code. There's a ARM template function called uniqueString(string) that generate a pseudo random hash of a given string. It's a deterministic pure function.
I need to find a way to exactly mimic the behaviour of this function from my C# code. ie I need to reproduce this function into my C# code.
Where can i find the algorithm used by the ARM Api ?
MSDN reference for uniqueString()
Update 2023-01-05 - As suggested by other answers, there's an easier way now - just reference the Azure.Deployments.Expression nuget package which contains all of the Arm functions and then use the following convenience wrapper:
using Azure.Deployments.Expression.Expressions;
using Newtonsoft.Json.Linq;
public static class ArmFunctions
{
public static string? UniqueString(params string[] values)
{
var parameters = values.Select(
arg => new FunctionArgument(
JToken.FromObject(arg)
)
).ToArray();
var result = ExpressionBuiltInFunctions.Functions
.EvaluateFunction("uniqueString", parameters, null);
return result.Value<string>();
}
}
// "zcztcwvu6iyg6"
var unique = ArmFunctions.UniqueString("tyeth");
Original answer for posterity:
I've been researching this myself on and off for a few years now, and I've finally hit paydirt...
// "zcztcwvu6iyg6"
var unique = ArmUniqueString("tyeth");
My ArmUniqueString function is a wrapper around some dlls that are distributed with the Azure Stack Hub Development Kit which is basically a virtual machine image that contains the Azure server-side platform that you can run locally...
private static string ArmUniqueString(string originalString)
{
var assembly = Assembly.GetAssembly(
typeof(Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.Engines.TemplateEngine)
);
var functions = assembly.GetType(
"Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.Expressions.TemplateExpressionBuiltInFunctions"
);
var uniqueString = functions.GetMethod(
"UniqueString",
BindingFlags.Static | BindingFlags.NonPublic
);
var parameters = new object[] {
"uniqueString",
new JToken[] {
(JToken)originalString
}
};
var result = uniqueString.Invoke(null, parameters).ToString();
return result;
}
You'll need to download the Azure Stack Hub Development Kit and unpack it to get the dlls:
Download the Azure Stack Hub Development Kit - warning: it's about 22Gb!
Run the installer to unpack a 55Gb *.vhdx
Mount the *.vhdx, or expand / unpack it locally
Inside the *.vhdx, find this file and unzip it somewhere:
CloudBuilder\CloudDeployment\NuGetStore\Microsoft.AzureStack.Setup.Services.ResourceManager.5.20.1335.300.nupkg
The content\Website\bin folder inside the *.nupkg contains the necessary dlls
To use them, add an assembly reference to Microsoft.WindowsAzure.ResourceStack.Frontdoor.Templates.dll (it has some dependencies on other files in the bin folder) and that contains the TemplateExpressionBuiltInFunctions class. The code above just uses reflection to invoke the private UniqueString function from that assembly, with a little bit of work to marshal the parameters into appropriate JToken types.
If you wanted to dig into the implementation details you could probably run a decompiler against the assembly to find out what it's doing under the covers...
Note - credits go to this blog article for pointing me in the right direction:
https://the.agilesql.club/2017/12/azure-arm-template-function-internals/
I found some PowerShell code to do this here: https://blogs.technet.microsoft.com/389thoughts/2017/12/23/get-uniquestring-generate-unique-id-for-azure-deployments/
I converted this code to C#:
public string GetUniqueString(string id, int length = 13)
{
string result = "";
var buffer = System.Text.Encoding.UTF8.GetBytes(id);
var hashArray = new System.Security.Cryptography.SHA512Managed().ComputeHash(buffer);
for(int i = 1; i <= length; i++)
{
var b = hashArray[i];
var c = Convert.ToChar((b % 26) + (byte)'a');
result = result + c;
}
return result;
}
This function is released in nuget: https://www.nuget.org/packages/Azure.Deployments.Expression/
The implementation:
https://msazure.visualstudio.com/One/_git/AzureUX-Deployments?path=%2Fsrc%2FExpressions%2FExpressions%2FExpressionBuiltInFunctions.cs&version=GBmaster&_a=contents
Example:
using Azure.Deployments.Expression.Expressions;
using Newtonsoft.Json.Linq;
var funcs = ExpressionBuiltInFunctions.Functions;
var jt = new JTokenExpression("test");
var output = funcs.EvaluateFunction("uniqueString", new JToken[] { jt.Value }).ToString();
Sam Cogan wrote a blog post on how to do this in C# here: https://samcogan.com/using-bicep-functions-in-c-if-you-really-want-to/
Inspired by Sam, I wrote a PowerShell module (for PowerShell 7) that does the same. You can install the module by running Install-Module -Name AzExpression which will give you command called New-AzUniqueString.
Here is an example on how to use it:
New-AzUniqueString -InputStrings 'test', 'value'
Which will output: bhxq2thzm5dym
I finally found a workaround. I used a very simple ARM template which goal is to only output the result of the uniqueStringcommand. Then I fetch this output in my C# code. This solution is not really the quickest one ;-), but it works as desired.
Here is a bicep template which will output a uniqueString for a resource group:
output unique string = uniqueString(resourceGroup().id)

Ordner nicht angegeben with OmniPascal in VSCode

People get the error when opening a file in Visual Studio Code when using OmniPascal:
Ordner nicht angegeben
which translates to:
Folder not specified
The first thought to ensure the paths in user settings.json are set:
objectpascal.delphiInstallationPath
objectpascal.objectpascal.searchPath
Would of course be a wrong tree to bark up:
settings.json:
// Place your settings in this file to overwrite the default settings
{
"objectpascal.delphiInstallationPath": "D:\\Programs\\Embarcadero\\Studio\\14.0",
"objectpascal.searchPath": "D:\\Delphi Components"
}
The error is definitely coming from OmniPascal, as it is a string inside
bin\win\OmniPascalServer.exe
I'm not the only person to get this
Anonymous has the same issue:
When I open a .pas file by right clicking on the file in windows explorer, the file opens correctly, but then a messagedialog appears with "Ordner nicht angegeben"' and an OK button.
Is there a way to debug Code?
I can see inside VSCode there is a variable to the workspace root path:
objectPascalServiceClient.js
var config = vscode.workspace.getConfiguration('objectpascal');
var delphiSDK = config.get('delphiInstallationPath', '');
var searchPath = config.get('searchPath', '');
var workspacePath = vscode.workspace.rootPath;
if (typeof delphiSDK == 'undefined')
delphiSDK = "";
if (typeof searchPath == 'undefined')
searchPath = "";
if (isWin) {
childProcess = cp.spawn(path.join(__dirname, 'bin/win/OmniPascalServer.exe'), [workspacePath, delphiSDK, searchPath]);
}
Is there source code?
It looks like OmniPascal is abandonware. Is there source code out there where someone can try to decipher exactly?
The real question is how to get rid of the modal dialog that blocks using the window.
It looks like OmniPascal is abandonware
No it's definetely not abandonware even though there was no new public release within the last months. OmniPascal is still in active development.
The real question is how to get rid of the modal dialog that blocks using the window.
This error message is coming from OmniPascalServer.exe shipped with the OmniPascal plugin for VSCode in (the current) version 0.10.0 released on 2016-04-14.
Workaround for version < 0.11.0
As far as I know this error message only appears when a file is opened in Visual Studio Code instead of a folder. So the simplest workaround is to open the folder which contains the file(s) you want to work with:
By command line: Type code C:\Projects\MyProjectRootFolder
With the Windows Explorer: Perform a right click on the folder (or a white area inside the folder) and select Open with Code. Do not select a .pas file to open VSCode!
From within VSCode: Go to File -> Open Folder...
Or apply the hotfix
Open the file C:\Users\USERNAME\.vscode\extensions\Wosi.omnipascal-0.10.0\objectPascalServiceClient.js
Replace this line
var workspacePath = vscode.workspace.rootPath;
with these lines
var workspacePath = vscode.workspace.rootPath;
if (typeof workspacePath == 'undefined') {
var filePath = vscode.workspace.textDocuments[0].fileName;
workspacePath = path.dirname(filePath);
}
Now the error should no longer appear.

Using cef for win64 - How to enable fullscreen

I'm using CEF and have built the cefsimple.exe. I can include any html file to the simple_app.cpp which will start after the doubleclick. But how is it possible to start this cefsimple.exe in fullscreen mode? Which build do I need? I work with VS2013 on a win64 system.
SimpleApp::SimpleApp() {
}
void SimpleApp::OnContextInitialized() {
CEF_REQUIRE_UI_THREAD();
// Information used when creating the native window.
CefWindowInfo window_info;
#if defined(OS_WIN)
// On Windows we need to specify certain flags that will be passed to
// CreateWindowEx().
window_info.SetAsPopup(NULL, "cefsimple");
// my first try: *************************************
/* RECT winrect;
winrect.bottom = 0;
winrect.left = 0;
winrect.right = 0;
winrect.top = 0;
window_info.SetAsChild(NULL, winrect);*/
#endif
// SimpleHandler implements browser-level callbacks.
CefRefPtr<SimpleHandler> handler(new SimpleHandler());
// Specify CEF browser settings here.
CefBrowserSettings browser_settings;
std::string url;
// Check if a "--url=" value was provided via the command-line. If so, use
// that instead of the default URL.
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
url = command_line->GetSwitchValue("url");
if (url.empty())
url = "file:///C:/Projekte/BOF-WENDT-HTML5/Fullscreen.html";
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler.get(), url,
browser_settings, NULL);
}
Not yet implemented in CEF, see:
https://code.google.com/p/chromiumembedded/issues/detail?id=562
Update: Changes for this feature have landed https://bitbucket.org/chromiumembedded/cef/issue/562

How to load types in the System namespace with Mono.Cecil?

I'm using Mono.Cecil (0.9.5.4) to inject code into some of my assemblies. Some of the calls I need to make are to objects in the System.ComponentModel namespace. How can I find those 'MethodReferences' that I need to call?
What I tried:
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath);
var objectModelRef = assembly.MainModule.AssemblyReferences.First(i => i.Name == "System.ObjectModel")
var objectModelAssembly = assembly.MainModule.AssemblyResolver.Resolve(objectModelRef);
But then objectmodelAssembly.MainModule.Types has no actual types in it.
I also tried this:
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath);
var system = new DefaultAssemblyResolver().Resolve("System");
var objectIWantToInject = assembly.MainModule.Import(FindType(...));
This works fine on a machine with the full .net 4.5 installed. But since my assembly is a PCL, when I try executing on WinPhone, I get FileNotFound for 'System'.
So if I wanted to get an instance of TypeDefinition for System.ComponentModel.ProgressChangedEventArgs that I could then make calls to some of the methods on, how would I?
In your code:
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath);
var system = new DefaultAssemblyResolver().Resolve("System");
var objectIWantToInject = assembly.MainModule.Import(FindType(...));
I think you are missing at least one import, e.g.
assembly.MainModule.Import(typeof(System.ObjectModel);
I believe you will also need to "Resolve" it to walk further down the tree.
Here is a working sample for anyone that is feeling the same pain:
assembly.MainModule.Import(typeof(string));
var methodBaseRef = assembly.MainModule.Import(typeof(System.Reflection.MethodBase));
var getMemberInfo = assembly.MainModule.Import(typeof(System.Reflection.MemberInfo));
var getMemberInfoResolver = getMemberInfo.Resolve();
var getCurrentMethodRef = assembly.MainModule.Import(typeof(System.Reflection.MethodBase).GetMethod("GetCurrentMethod"));
var get_DeclaringType = assembly.MainModule.Import(getMemberInfoResolver.Methods.Single(m => m.Name == "get_DeclaringType"));
var getTypeInfo = assembly.MainModule.Import(typeof(Type));
var name = assembly.MainModule.Import(typeof(Type).GetMethod("Name"));

Resources