I have created a VSIX with 2 templates, one is for VS2012 and another is for VS2013.
But if I use the VSIX, both templates are visible for both VS versions in "New Project" window. I want to restrict it. Is there any way?
This is not a great solution, but only one I've found for this problem.
You can register your package to initialize early on in the Visual Studio startup with the following attribute.
[ProvideAutoLoad(UIContextGuids80.NoSolution)]
public sealed YourPackage : Package
Then in your override void Initialize() method you'll want to register a new DTEEvent.
DTEEvents dte_events;
private void RegisterStartupEvents()
{
if(dte == null)
dte = (DTE)GetService(typeof(DTE));
if (dte != null)
{
dte_events = dte.Events.DTEEvents;
dte_events.OnStartupComplete += OnStartupComplete;
}
}
The OnStartupComplete will fire on startup before any templates have been initialized. To remove them from the list for the current VS version, the bundled zip template files that are copied when your VSIX package is installed will have to be deleted. This method could probably be nicer, but you get the idea.
private void OnStartupComplete()
{
dte_events.OnStartupComplete -= OnStartupComplete;
dte_events = null;
var cleanupList = TemplateCleanupByVsVersion[MajorVisualStudioVersion];
foreach (var deleteTemplate in cleanupList)
{
DirectoryInfo localVsDir = new DirectoryInfo(UserLocalDataPath);
// Locate root path of your extension installation directory.
var packageDllFileInfo = localVsDir.GetFiles("MyVsPackage.dll", SearchOption.AllDirectories)[0];
DirectoryInfo extensionDirInfo = packageDllFileInfo.Directory;
if (extensionDirInfo == null)
{
// Failed to locate extension install directory, bail.
return;
}
var files = extensionDirInfo.GetFiles(deleteTemplate + ".zip", SearchOption.AllDirectories);
if (files.Length > 0)
{
File.Delete(files[0].FullName);
}
}
ServiceProvider.GetWritableSettingsStore().SetPackageReady(true);
}
TemplateCleanupByVsVersion is a Dictionart<int,List<string>> that maps Visual Studio Major version with a list of zip file names (without extension) that you don't want showing up in the mapped Visual Studio version. Eg,
public readonly Dictionary<int, List<string>> TemplateCleanupByVsVersion = new Dictionary<int, List<string>>
{
{11,new List<string> { "MyTemplate1.csharp", "MyTemplate2.csharp", "MyTemplate3.csharp" } },
{12,new List<string> { "MyTemplate1.csharp" }},
{14,new List<string>()}
};
MajorVisualStudioVersion comes from parsing dte.Version. eg,
public int MajorVisualStudioVersion => int.Parse(dte.Version.Substring(0, 2));
The result being specific Visual Studio versions can remove any templates from your VSIX that don't work well. Hope that helps.
Related
I am trying to access the full repository history of an IFile object programatically from an Eclipse plugin. When the file has never been renamed or moved, the following code snippet works:
public long getFileHistoryTimestamp(IFile file, IProgressMonitor monitor, boolean lastModified) {
IProject project = file.getProject();
RepositoryProvider rProv = RepositoryProvider.getProvider(project);
long createdMillis, lastModifiedMillis;
if (rProv !=null) {
IFileHistoryProvider fhp = rProv.getFileHistoryProvider();
if (fhp != null) {
IFileHistory fHist = fhp.getFileHistoryFor((IResource) file,
IFileHistoryProvider.NONE, null);
IFileRevision[] revs = fHist.getFileRevisions();
Arrays.sort(revs, new Comparator<IFileRevision>(){
public int compare(IFileRevision o1, IFileRevision o2) {
return Long.compare(o1.getTimestamp(), o2.getTimestamp());
}
});
for (IFileRevision rev : revs) {
if (rev.getTimestamp() >= 0) {
createdMillis = rev.getTimestamp();
break;
}
}
if (revs.length > 0) {
lastModifiedMillis = revs[revs.length - 1].getTimestamp();
}
}
return lastModified ? lastModifiedMillis : createdMillis;
}
But, if the file has been moved (e.g. with a multi-module maven project to a new or different module/project), then the values returned above are only for the file in it's current location - i.e. it does not track any rename/moves. The same file in the Eclipse Team History view does track the full version history.
How can I access this full history within the Eclipse Team API?
I'm using wixsharp to build my installer. Everytime I give a new build I want to update all my exe, dlls and other binaries but I want to retain manually changed settings like we have an option to store some keys in database that will create some folders inside application folder in program files. I want to retain this data and to replace binaries but when I upgrade it is deleting this data as well.
I'm using below wixsharp code to implement upgrade.
project.UpgradeCode= new Guid("some GUID here, keeping it same in all builds");
project.ProductId = new Guid("GUID here, changing it in all incremental build");
project.Version = new Version(6, 1, 1, 1); // upgrading it in incremental builds
project.MajorUpgrade = new MajorUpgrade
{
Schedule = UpgradeSchedule.afterInstallValidate,
AllowSameVersionUpgrades = true,
MigrateFeatures =true,
IgnoreRemoveFailure=true,
DowngradeErrorMessage="A new version of this product is already installed."
};
One more issue with this I'm facing is when we are installing 2nd build it is not showing the upgrade option but showing install option only (like fresh installation) and at last it is asking user's permission to uninstall the product, that is uninstalling old product it seems but it doesn't look user friendly as user might feel why he/she is uninstalling the product.
I just want an upgrade option that can do the upgrade without showing user what is going in backend.
Question 1:
If you want to have some static files which ones adds if not exist but not update them with new one installation. You need to mark them with Permanent="yes" NeverOverwrite="yes" attributes.
For more information link here: Wix Component Element
How to make it with WixSharp?
Here is my code how to make index.html and web.config immutable:
var immutableFiles =
{
#"index.html",
#"web.config"
};
// ....
var wixObjects = new WixObject[]
{
new Dir(
#"%ProgramFiles%\YourProductFolderName\",
WixFilesBuilderUtils.BuildDirectoryInfo(BinariesRoot, immutableFiles)),
// Properties etc...
}.ToArray();
var project = new ManagedProject("name", wixObjects);
Builder code:
public class WixFilesBuilderUtils
{
public static WixEntity[] BuildDirectoryInfo(string currentRoot, IEnumerable<string> immutableFiles)
{
var result = new List<WixEntity>();
var currentRootDictionaryInfo = new DirectoryInfo(currentRoot);
var localImmutableFiles = immutableFiles.Select(fileName => fileName.ToLower()).ToArray();
var currentRootDirList = currentRootDictionaryInfo
.GetDirectories()
.Select(dirInfoSub => dirInfoSub.FullName).ToArray();
result.AddRange(
Directory.GetFiles(currentRootDictionaryInfo.FullName)
.Select(
filePath => new WixSharp.File(filePath)
{
Attributes = MarkFileAsPersonal(filePath, localImmutableFiles)
})
.Cast<WixEntity>());
if (currentRootDirList.Any())
{
var subDirs = currentRootDirList
.Select(dirPath => new DirectoryInfo(dirPath))
.Select(
rootSubDirInfo =>
new Dir(rootSubDirInfo.Name,
BuildDirectoryInfo(rootSubDirInfo.FullName, localImmutableFiles)))
.Cast<WixEntity>();
result.AddRange(subDirs);
}
return result.ToArray();
}
private static Dictionary<string, string> MarkFileAsPersonal(string path, IEnumerable<string> immutableFiles)
{
return immutableFiles.Any(path.ToLower().EndsWith)
? new Dictionary<string, string>
{
{ "Component:Permanent", "yes" },
{ "Component:NeverOverwrite", "yes" }
}
: new Dictionary<string, string>();
}
}
Question 2:
Please try to have same UpdateCode and ProductCode GUIDs each one build and this one strategy:
MajorUpgradeStrategy = new MajorUpgradeStrategy
{
RemoveExistingProductAfter = Step.InstallInitialize,
UpgradeVersions = VersionRange.OlderThanThis,
PreventDowngradingVersions = VersionRange.NewerThanThis,
NewerProductInstalledErrorMessage = "."
};
When I try to execute the first-n-integers extension example:
show noise:first-n-integers 5
I receive an error "ERROR: Expected command. " in the console or in the code tab.
I have mostly copied and pasted the class examples as is, just renaming them and putting them in a different package. I wish the error was a little more descriptive, as I suspect I am making a simple error somewhere.
I'm using 5.0.4 without the JRE and a 1.7.0_45 JRE/JDK on a x64 Windows 7 machine.
My manifest.txt file with fully-qualified class-manager and crlf at the end of the version line--
Manifest-Version: 1.0
Extension-Name: noise
Class-Manager: org.xyz.extensions.NoiseExtension
NetLogo-Extension-API-Version: 5.0 <--there is a crlf here
the jar is in a subfolder with my model file
test/
test.nlogo
noise/
noise.jar
This is my Class-Manager:
package org.xyz.extensions;
import org.nlogo.api.*;
public class NoiseExtension extends DefaultClassManager {
public void load(PrimitiveManager primitiveManager) {
primitiveManager.addPrimitive(
"first-n-integers", new org.xyz.extensions.NoiseGenerator());
}
}
This is the NoiseGenerator file:
package org.xyz.extensions;
import org.nlogo.api.*;
public class NoiseGenerator extends DefaultReporter {
public Syntax getSyntax() {
return Syntax.reporterSyntax(
new int[] {Syntax.NumberType()}, Syntax.ListType());
}
public Object report(Argument args[], Context context) throws ExtensionException {
// create a NetLogo list for the result
LogoListBuilder list = new LogoListBuilder();
int n ;
// use typesafe helper method from
// org.nlogo.api.Argument to access argument
try {
n = args[0].getIntValue();
}
catch(LogoException e) {
throw new ExtensionException( e.getMessage() ) ;
}
if (n < 0) {
// signals a NetLogo runtime error to the modeler
throw new ExtensionException
("input must be positive");
}
// populate the list. note that we use Double objects; NetLogo
// numbers are always Doubles
for (int i = 0; i < n; i++) {
list.add(Double.valueOf(i));
}
return list.toLogoList();
}
}
Thanks for any help.
AJB
This was asked and answered here:
https://groups.google.com/d/msg/netlogo-devel/eIq8drflsc8/7y_Ooh6R0sgJ
The answer was to correct the spelling of getSynax to getSyntax.
Inside an Eclipse plugin, I'd like to open a file in editor.
I know the full package and class name
How can I determine the path of the .java file from this?
Take a look at IJavaProject.findType( name ) method. Once you have an IType, you can use getPath or getResource methods to locate the file. This method searches across a project and everything visible from that project.
To search the whole workspace, iterate through all the Java projects in the workspace, calling the findType method on each in turn.
You also need to know the source folder.
IProject prj = ResourcePlugin.getWorkspace().getRoot().getProject("project-name");
IFile theFile = prj.getFile(sourceFolder + packageName.replace('.','/') + className + ".java");
Generally you specify the file for an editor with an IFile. You can also ask an IFile for variants of the file's path.
I know this is a bit old but I had the same need and I had a look at how eclipse does it for stack trace elements (they have a hyperlink on them). The code is in org.eclipse.jdt.internal.debug.ui.console.JavaStackTraceHyperlink (the link is "lazy" so the editor to open is resolved only when you click on it).
What it does is it first searches for the type in the context of the launched application, then for in the whole workspace (method startSourceSearch) :
IType result = OpenTypeAction.findTypeInWorkspace(typeName, false);
And then opens the associated editor (method processSearchResult, source is the type retrieved above) :
protected void processSearchResult(Object source, String typeName, int lineNumber) {
IDebugModelPresentation presentation = JDIDebugUIPlugin.getDefault().getModelPresentation();
IEditorInput editorInput = presentation.getEditorInput(source);
if (editorInput != null) {
String editorId = presentation.getEditorId(editorInput, source);
if (editorId != null) {
try {
IEditorPart editorPart = JDIDebugUIPlugin.getActivePage().openEditor(editorInput, editorId);
if (editorPart instanceof ITextEditor && lineNumber >= 0) {
ITextEditor textEditor = (ITextEditor)editorPart;
IDocumentProvider provider = textEditor.getDocumentProvider();
provider.connect(editorInput);
IDocument document = provider.getDocument(editorInput);
try {
IRegion line = document.getLineInformation(lineNumber);
textEditor.selectAndReveal(line.getOffset(), line.getLength());
} catch (BadLocationException e) {
MessageDialog.openInformation(JDIDebugUIPlugin.getActiveWorkbenchShell(), ConsoleMessages.JavaStackTraceHyperlink_0, NLS.bind("{0}{1}{2}", new String[] {(lineNumber+1)+"", ConsoleMessages.JavaStackTraceHyperlink_1, typeName})); //$NON-NLS-2$ //$NON-NLS-1$
}
provider.disconnect(editorInput);
}
} catch (CoreException e) {
JDIDebugUIPlugin.statusDialog(e.getStatus());
}
}
}
}
Code has copyright from eclipse. Hopfully I'm allowed to reproduced it if this is mentionned.
I have check very long logs after each start of Tomcat (from Eclipse).
Does exist a plugin or editor that I can use inside Eclipse? At least it must have colored for errors, debug and info messages.
Thanks.
I would recommend using Log4j:
http://logging.apache.org/log4j/1.2/
http://en.wikipedia.org/wiki/Log4j
It works great with eclipse and has the color scheme built in. It's highly customizable, takes some time to figure out but it's worth it.
The code to do this is rather simple, aside from syntax coloring. Just start a plugin project, add dependancies for org.eclipse.ui.console and do something like this:
public void log() {
BufferedReader br = new BufferedReader(new FileReader("path of log file"));
String line = null;
while (br.nextLine ) {
line = br.readLine();
if (line == null) {
Thread.sleep(1000);
}
else {
MessageConsole console = findConsole("tomcat log");
MessageConsoleStream stream = console.newMessageStream();
stream.println(message);
}
}
}
private MessageConsole findConsole(String name) {
ConsolePlugin plugin = ConsolePlugin.getDefault();
IConsoleManager conMan = plugin.getConsoleManager();
IConsole[] existing = conMan.getConsoles();
for (IConsole element : existing)
if (name.equals(element.getName()))
return (MessageConsole) element;
// no console found, so create a new one
MessageConsole myConsole = new MessageConsole(name, null);
conMan.addConsoles(new IConsole[] { myConsole });
return myConsole;
}