How do I use Roslyn with a Website project? - roslyn

In my Visual Studio Package I get the VisualStudioWorkspace as described by Josh Varty
https://joshvarty.com/2014/09/12/learn-roslyn-now-part-6-working-with-workspaces/
Using the EnvDTE.Project object, I look for a matching Roslyn project in VisualStudioWorkspace.Projects by comparing the properties CodeAnalysis.Project.FilePath and EnvDTE.Project.FileName.
If I find a match, then I know that the project supports Roslyn and that I can find documents in the CodeAnalysis.Project.Documents collection. This has so far worked fine for C# and VB projects.
If I do not find a match, then it might be a C++ project, which does not support Roslyn.
However, I have now found that WebSite projects behave quite differently.
I have created a new WebSite project in Visual Studio 2019. Althouth the solution only contains one project, the VisualStudioWorkspace contains two CodeAnalysis.Project objects, as follows:
?VSWorkspace.CurrentSolution.Projects(0)
1_Default.aspx
AdditionalDocumentIds: Count = 0
AdditionalDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.TextDocument)}
AllProjectReferences: Length = 1
AnalyzerConfigDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of System.Collections.Generic.KeyValuePair(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.AnalyzerConfigDocumentState), Microsoft.CodeAnalysis.AnalyzerConfigDocument)}
AnalyzerOptions: {Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions}
AnalyzerReferences: Length = 0
AssemblyName: "1_Default"
CompilationOptions: {Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions}
DefaultNamespace: ""
DocumentIds: Count = 2
Documents: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.Document)}
FilePath: Nothing
HasDocuments: True
Id: (ProjectId, #ca6b1f58-967a-4c31-a874-71d7720dd972 - 1_Default.aspx)
IsSubmission: False
Language: "C#"
LanguageServices: {Microsoft.CodeAnalysis.Host.Mef.MefLanguageServices}
MetadataReferences: Length = 56
Name: "1_Default.aspx"
OutputFilePath: Nothing
OutputRefFilePath: Nothing
ParseOptions: {Microsoft.CodeAnalysis.CSharp.CSharpParseOptions}
ProjectReferences: {System.Linq.Enumerable.WhereEnumerableIterator(Of Microsoft.CodeAnalysis.ProjectReference)}
Solution: {Microsoft.CodeAnalysis.Solution}
SupportsCompilation: True
Version: {2019-10-13T06:46:42.2691386Z-10141-0}
?VSWorkspace.CurrentSolution.Projects(1)
2_App_Code
AdditionalDocumentIds: Count = 0
AdditionalDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.TextDocument)}
AllProjectReferences: Length = 0
AnalyzerConfigDocuments: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of System.Collections.Generic.KeyValuePair(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.AnalyzerConfigDocumentState), Microsoft.CodeAnalysis.AnalyzerConfigDocument)}
AnalyzerOptions: {Microsoft.CodeAnalysis.Diagnostics.AnalyzerOptions}
AnalyzerReferences: Length = 0
AssemblyName: "App_Code.yy7qumxk"
CompilationOptions: {Microsoft.CodeAnalysis.CSharp.CSharpCompilationOptions}
DefaultNamespace: ""
DocumentIds: Count = 5
Documents: {System.Linq.Enumerable.WhereSelectEnumerableIterator(Of Microsoft.CodeAnalysis.DocumentId, Microsoft.CodeAnalysis.Document)}
FilePath: Nothing
HasDocuments: True
Id: (ProjectId, #12ab68ac-7b29-4252-87c2-67dc2f3d0696 - 2_App_Code)
IsSubmission: False
Language: "C#"
LanguageServices: {Microsoft.CodeAnalysis.Host.Mef.MefLanguageServices}
MetadataReferences: Length = 53
Name: "2_App_Code"
OutputFilePath: Nothing
OutputRefFilePath: Nothing
ParseOptions: {Microsoft.CodeAnalysis.CSharp.CSharpParseOptions}
ProjectReferences: {System.Linq.Enumerable.WhereEnumerableIterator(Of Microsoft.CodeAnalysis.ProjectReference)}
Solution: {Microsoft.CodeAnalysis.Solution}
SupportsCompilation: True
Version: {2019-10-13T06:46:41.6118955Z-10139-2}
First of all, the FilePath property in both projects is null, so I was not able to identify the project by its filename.
The two projects contain a total of seven documents, which are:
"C:\DotNetTestPrograms\2019\CS\WebSite1\Default.aspx.cs"
"C:\DotNetTestPrograms\2019\CS\WebSite1\Default.aspx"
"C:\DotNetTestPrograms\2019\CS\WebSite1\App_Code\BundleConfig.cs"
"C:\DotNetTestPrograms\2019\CS\WebSite1\App_Code\IdentityModels.cs"
"C:\DotNetTestPrograms\2019\CS\WebSite1\App_Code\RouteConfig.cs"
"C:\DotNetTestPrograms\2019\CS\WebSite1\App_Code\Startup.Auth.cs"
"C:\DotNetTestPrograms\2019\CS\WebSite1\App_Code\Startup.cs"
This is not a complete list of documents in the project. The project contains seven additional-code behind files:
Account\Login.apsx.cs
Account\Manage.apsx.cs
Account\OpenAuthProviders.ascx.cs
Account\Register.apsx.cs
Account\RegisterExternalLogin.apsx.cs
Site.master.cs
ViewSwitcher.ascx.cs
My question is, can I work with Roslyn in a WebSite project?
Clearly, there is not a one-to-one relationship between EnvDTE and CodeAnalysis projects. I guess that I could work around that.
But what about the missing files? Are there not Roslyn documents for the seven additional code-behind files?

I finally looked at this problem again and I have found the following solution.
This method only works if the document is open in Visual Studio. Therefore I start of with
projectItem.Open ( EnvDTE.Constants.vsViewKindTextView ) ;
(I already have the project item in my function, so this is easy.)
Then, with the full path to the file (FullPath) and the VisualStudioWorkspace (VSWorkspace), I can get the Roslyn Document with
var docid = VSWorkspace.CurrentSolution.GetDocumentIdsWithFilePath(FullPath).FirstOrDefault() ;
if ( docid != null )
{
var RoslynDoc = VSWorkspace.CurrentSolution.GetDocument ( docid ) ;
}
If the document was not already open, it would probably be good practice to close it again, when you are finished. You can determine whether the document was previously open with
var wasOpen = projectItem.IsOpen ( EnvDTE.Constants.vsViewKindTextView ) ;
By the way, opening the document like this does not make the window visible in Visual Studio (which in my application is fine). If you want to make it visible you can open it like this:
var wnd = projectItem.Open ( EnvDTE.Constants.vsViewKindTextView ) ;
wnd.Visible = true ;

Related

Offline Maps HERE-SDK - offline search and navigation

I am using HERE-Android-SDK to build a simple navigation solution with offline maps.
While using the offline mode for the search addresses and calculation of a route, I can see that there are results returned from the address-search, which are not included in the installed offline map datasets. Is there anything additional which I need to do, in order to get only search results which are located inside the offline-map data installed on my device?
I am using the following code snippets.
download offline maps for a specific country:
mapsLoader.selectDataGroup(MapPackage.SelectableDataGroup.TruckAttributes)
mapsLoader.installMapPackages(listOf(mapPackageId))
search request for addresses:
val term = "New York"
val center = GeoCoordinate(lastWayPoint.latitude, lastWayPoint.longitude)
val request = SearchRequest(term)
request.connectivity = Request.Connectivity.OFFLINE
request.locale = Locale.GERMAN
request.setSearchCenter(center)
request.collectionSize = 5
request.execute { data, error ->
if (error != ErrorCode.NONE) return
// handle search results here
}
Thanks for all of your help in advance!

OpenFileDialog component in Visual Studio 2017

I'm working on a VB project in Visual Studio 2017. It's a Blank App (Universal Windows) project. When trying to work with this type of app, it doesn't seem to have an OpenFileDialog like the Windows Forms App (.NET Framework) has. Is there a way to do one of two things:
Create a Windows Forms App that has the same look and feel as the Blank App (Universal Windows)
Add the OpenFileDialog option to the Blank App (Universal Windows)
The following code is a VB version of the MS example at https://learn.microsoft.com/en-us/uwp/api/Windows.Storage.Pickers.FileOpenPicker.
Imports Windows.Storage
Imports Windows.Storage.Pickers
Public NotInheritable Class MainPage
Inherits Page
Private Async Sub Button_Click(sender As Object, e As RoutedEventArgs)
Dim openPicker As New FileOpenPicker()
openPicker.ViewMode = PickerViewMode.Thumbnail
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary
openPicker.FileTypeFilter.Add(".jpg")
openPicker.FileTypeFilter.Add(".jpeg")
openPicker.FileTypeFilter.Add(".png")
Dim file As StorageFile = Await openPicker.PickSingleFileAsync()
If (file IsNot Nothing) Then
Debug.WriteLine($"Picked File: {file.Name}")
Else
Debug.WriteLine("Operation Cancelled.")
End If
End Sub
End Class
What I ended up doing to get the same(ish) look was to just play around with some of the properties of the form and the buttons. This gave me the look that I was after. It wasn't exact, but I'll take it.
As for OpenFileDialog, I ended up using the following:
Dim myStream As IO.Stream = Nothing
Dim openFileDialog1 As New OpenFileDialog()
' Open file dialog parameters
openFileDialog1.InitialDirectory = "c:\" ' Default open location
openFileDialog1.Filter = "Executable Files (*.exe)|*.exe|All Files (*.*)|*.*"
openFileDialog1.FilterIndex = 2
openFileDialog1.RestoreDirectory = True
If openFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
myStream = openFileDialog1.OpenFile()
If (myStream IsNot Nothing) Then
' Insert code to read the stream here.
Textbox1.Text = openFileDialog1.FileName
' Even though we're reading the entire path to the file, the file is going to be ignored and only the path will be saved.
' Mostly due to me lacking the ability to figure out how to open just the directory instead of a file. Resolution threadbelow.
' http://www.vbforums.com/showthread.php?570294-RESOLVED-textbox-openfiledialog-folder
' Setting the public variable so it can be used later
Dim exepath As String
exepath = IO.Path.GetDirectoryName(Me.txtExeLocation.Text)
End If
Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. Original error: " & Ex.Message)
Finally
' Check this again, since we need to make sure we didn't throw an exception on open.
If (myStream IsNot Nothing) Then
myStream.Close()
End If
End Try
End If

mediawiki: is there a way to automatically create redirect pages that redirect to the current page?

My hobby is writing up stuff on a personal wiki site: http://comp-arch.net.
Currently using mediawiki (although I often regret having chosen it, since I need per page access control.)
Often I create pages that define several terms or concepts on the same page. E.g. http://semipublic.comp-arch.net/wiki/Invalidate_before_writing_versus_write_through_is_the_invalidate.
Oftentimes such "A versus B" pages provide the only definitions of A and B. Or at least the only definitions that I have so far gotten around to writing.
Sometimes I will define many more that two topics on the same page.
If I create such an "A vs B" or other paging containing multiple definitions D1, D2, ... DN, I would like to automatically create redirect pages, so that I can say [[A]] or [[B]] or [[D1]] .. [[DN]] in other pages.
At the moment the only way I know of to create such pages is manually. It's hard to keep up.
Furthermore, at the time I create such a page, I would like to provide some page text - typicaly a category.
Here;s another example: variant page names. I often find that I want to create several variants of a page name, all linking to the same place. For example
[[multithreading]],
[[multithreading (MT)]],
[[MT (multithreading)]],
[[MT]]
Please don;t tell me to use piped links. That's NOT what I want!
TWiki has plugins such as
TOPICCREATE automatically create topics or attach files at topic save time
More than that, I remember a twiki plugin, whose name I cannot remember or google up, that included the text of certain subpages within your current opage. You could then edit all of these pages together, and save - and the text would be extracted and distributed as needed. (By the way, if you can remember the name of tghat package, please remind me. It had certain problems, particularly wrt file locking (IIRC it only locked the top file for editing, bot the sub-topics, so you could lose stuff.))
But this last, in combination with parameterized templtes, would be almost everything I need.
Q: does mediawiki have something similar? I can't find it.
I suppose that I can / could should wrote my own robot to perform such actions.
It's possible to do this, although I don't know whether such extensions exist already. If you're not averse to a bit of PHP coding, you could write your own using the ArticleSave and/or ArticleSaveComplete hooks.
Here's an example of an ArticleSaveComplete hook that will create redirects to the page being saved from all section titles on the page:
$wgHooks['ArticleSaveComplete'][] = 'createRedirectsFromSectionTitles';
function createRedirectsFromSectionTitles( &$page, &$user, $text ) {
// do nothing for pages outside the main namespace:
$title = $page->getTitle();
if ( $title->getNamespace() != 0 ) return true;
// extract section titles:
// XXX: this is a very quick and dirty implementation;
// it would be better to call the parser
preg_match_all( '/^(=+)\s*(.*?)\s*\1\s*$/m', $text, $matches );
// create a redirect for each title, unless they exist already:
// (invalid titles and titles outside ns 0 are also skipped)
foreach ( $matches[2] as $section ) {
$nt = Title::newFromText( $section );
if ( !$nt || $nt->getNamespace() != 0 || $nt->exists() ) continue;
$redirPage = WikiPage::factory( $nt );
if ( !$redirPage ) continue; // can't happen; check anyway
// initialize some variables that we can reuse:
if ( !isset( $redirPrefix ) ) {
$redirPrefix = MagicWord::get( 'redirect' )->getSynonym( 0 );
$redirPrefix .= '[[' . $title->getPrefixedText() . '#';
}
if ( !isset( $reason ) ) {
$reason = wfMsgForContent( 'editsummary-auto-redir-to-section' );
}
// create the page (if we can; errors are ignored):
$redirText = $redirPrefix . $section . "]]\n";
$flags = EDIT_NEW | EDIT_MINOR | EDIT_DEFER_UPDATES;
$redirPage->doEdit( $redirText, $reason, $flags, false, $user );
}
return true;
}
Note: Much of this code is based on bits and pieces of the pagemove redirect creating code from Title.php and the double redirect fixer code, as well as the documentation for WikiPage::doEdit(). I have not actually tested this code, but I think it has at least a decent chance of working as is. Note that you'll need to create the MediaWiki:editsummary-auto-redir-to-section page on your wiki to set a meaningful edit summary for the redirect edits.

ColdFusion HTTP POST large strings

Has anyone noticed that if you try to post a string that exceeds 1,000,000 characters, it simply does not include the field with the request?
...and doesn't throw()!
eg.
<cfscript>
var h = new http( url = "http://...", method = "post" );
h.addParam( type = "formField", name = "a", value = repeatString("a",5000) );
h.addParam( type = "formField", name = "b", value = repeatString("b",1000000) );
h.addParam( type = "formField", name = "c", value = repeatString("c",1000001) );
var p = h.send().getPrefix();
writeDump( var = p, abort = true );
</cfscript>
The "a" and "b" fields are present in the form scope of the recipient page.
The "c" field is missing!
ColdFusion 9,0,1,274733 + chf9010002.jar, Mac OS X 10.6.8, Java 1.6.0_31
Edit: It now works as expected!
Not sure what has changed? My cf admin configuration remains the same. The only possible candidate I can come up with is a recent Apple Java update. Could that be it?
You may need to specify
enctype="multipart/form-data"
This is a setting within CF administrator.
In Coldfusion 9 (this setting has existed for a while, but may exist elsewhere in other versions):
Click on "server settings" group to expand, click on "settings" link (top link). On the settings page:
Maximum size of post data 100 MB (default)
Limits the amount of data that can be posted to the server in a single request. ColdFusion rejects requests larger than the specified limit.
It's interesting that you're hitting a limit right at 100,000 ; sounds like someone got a little lazy with the "bytes" computation. :) At any rate, I'd try tinkering with this setting.
Just an FYI: You'll encounter a similar issue with data truncation on data inserts/updates unless you set your datasource to allow "Long Text Buffer (chr)" greater than the 64,000 default limit.

Quickly enter command-line parameters for Visual Studio debugging?

I want to change my command-line arguments and then debug my executable.
With the default Visual Studio UI, this takes me several tortuous mouse and keyboard actions:
Project ... right click ... Configuration Properties ... Debugging ... Command Arguments ... type args ... ENTER ... F5
Is there a way to make this common action as easy as other common operations, for example, searching all files for a pattern which goes:
CNTL+SHIFT+F ... type search pattern ... ENTER
For example, is there an way to create a custom edit box to allow quick access to the debug command-line arguments? Or a way to have a key-binding pop up a simple "debug dialog" where the args can be entered and debugging started directly? e.g.
ALT+F5 ... type args ... ENTER
I am using C++ and Visual Studio 2010 Express. Thanks!
The extension CLIArgsMadeEasy 2010/2012 is a great little thing that puts the project's debug session's command line arguments right in a little text box on the visual studio toolbar, IMO, its alot easier and less tedious than using macros.
The Link
http://visualstudiogallery.msdn.microsoft.com/8159cd7d-2c81-47f3-9794-a347ec1fba09?SRC=VSIDE
You can just type CLIArgsMadeEasy in your search box in the extensions manager which will find it fairly quickly in the gallery, thats how I installed it, if you need to know. Hope this helps!
Macro below should help. Open "Tools->Macros->Macro Explorer", then create new module, edit it, and copy-paste code below. Required command is SetCommandArgsProperty. UI is not nice, but it works (VS 2005, I hope this will also work in VS 2010). Then add any shortcut you like to run this macro.
Here are some details:
Find startup project
Select it active configuration and find property with name "CommandArguments"
Create edit box with the current value in it
Update property if OK is selected
Sub SetCommandArgsProperty()
Dim newVal As Object
newVal = InputValue(GetCommandArgsPropertyValue())
If TypeOf newVal Is String Then
SetCommandArgsProperty(newVal)
End If
End Sub
Function InputValue(ByVal defaultText As String)
Dim frm As New System.Windows.Forms.Form
Dim btn As New System.Windows.Forms.Button
Dim edit As New System.Windows.Forms.TextBox
edit.Text = defaultText
edit.Width = 100
btn.Text = "OK"
btn.DialogResult = System.Windows.Forms.DialogResult.OK
frm.Text = "Input command line properties"
frm.Controls.Add(btn)
btn.Dock = System.Windows.Forms.DockStyle.Bottom
frm.Controls.Add(edit)
edit.Dock = System.Windows.Forms.DockStyle.Top
frm.Height = 80
frm.Width = 300
If frm.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Return edit.Text
End If
Return System.DBNull.Value
End Function
Function GetCommandArgsProperty() As EnvDTE.Property
Dim solution As Solution
Dim project As Project
Dim sb As SolutionBuild
Dim str As String
Dim cm As ConfigurationManager
Dim config As Configuration
Dim properties As Properties
Dim prop As EnvDTE.Property
solution = DTE.Solution
sb = solution.SolutionBuild
For Each str In sb.StartupProjects
project = solution.Item(str)
cm = project.ConfigurationManager
config = cm.ActiveConfiguration
properties = config.Properties
For Each prop In properties
If prop.Name = "CommandArguments" Then
Return prop
End If
Next
Next
End Function
Function GetCommandArgsPropertyValue()
Return GetCommandArgsProperty().Value
End Function
Sub SetCommandArgsProperty(ByVal value As String)
GetCommandArgsProperty().Value = value
End Sub
At least in Visual Studio 2012, you can use Alt+F7 shortcut to directly access project properties.
Furthermore, the opened Property Pages normally remembers the last opened item, i.e. Configuration Properties -> Debugging.