Trying to get the appconfig path from the debug environment for a component but I keep getting nulls errors from this when I build the solution is vs2017. any help appreciated.
public string GetAppConfigPath()
{
var devenv = (DTE)_c.Site.GetService(typeof(DTE));
var projects = (Array)devenv.ActiveSolutionProjects;
var activeProject = (Project)projects.GetValue(0);
foreach (ProjectItem item in activeProject.ProjectItems)
{
if (!item.Name.Equals("app.config")) continue;
var info = new System.IO.FileInfo(activeProject.FullName);
if (info.Directory != null)
return info.Directory.FullName + "\\" + item.Name;
}
return null;
}
Related
Hi I am having a problem, with a custom build task inside of a Visual Studio Extension. I need to identify projects of my custom project type. I can do this fine if they are on the root of the solution, but the problem occurs when it is inside of a solution folder. I can get the solution folder as a EnvDTE.Project, but am not sure how to get projects from within that folder.
I thought I would be able to get it from the projects Collection property but that is null.
Any assistance would be greatly appreciated.
if (Scope == EnvDTE.vsBuildScope.vsBuildScopeSolution)
{
DTE2 dte2 = Package.GetGlobalService(typeof(EnvDTE.DTE)) as DTE2;
var sol = dte2.Solution;
EnvDTE.DTE t = dte2.DTE;
var x = t.Solution.Projects;
foreach(var proj in x)
{
try
{
var project = proj as EnvDTE.Project;
var guid = GetProjectTypeGuids(project);
if (guid.Contains("FOLDERGUID"))
{
//here is where I would get the project from the folder
}
I managed to resolve this with a bit more research and some trial and error. In case anybody else comes up with this problem, I changed the main code to
if (Scope == EnvDTE.vsBuildScope.vsBuildScopeSolution)
{
errorListProvider.Tasks.Clear();
DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2;
var sol = dte2.Solution;
var projs = sol.Projects;
foreach(var proj in sol)
{
var project = proj as Project;
if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder)
{
var innerProjects = GetSolutionFolderProjects(project);
foreach(var innerProject in innerProjects)
{
//carry out actions here.
}
}
}
}
The code for the GetSolutionFolderForProjects was
private IEnumerable<Project> GetSolutionFolderProjects(Project project)
{
List<Project> projects = new List<Project>();
var y = (project.ProjectItems as ProjectItems).Count;
for(var i = 1; i <= y; i++)
{
var x = project.ProjectItems.Item(i).SubProject;
var subProject = x as Project;
if (subProject != null)
{
//Carried out work and added projects as appropriate
}
}
return projects;
}
Hope this helps somebody else.
I had a similar question within a T4 template, where I had to find a project by name within the solution, at any level: root, folder, nested folder.
For reference purposes, I'm pasting it here. It's totally based on the solution from #DaveGreen, so credits to him:
<## import namespace="System.Linq" #>
<#
var dte = (DTE)hostServiceProvider.GetService(typeof(DTE));
var project = GetProject(dte.Solution, "ProjectName");
#>
<#+
public static Project GetProject(Solution solution, string name)
{
var project = GetProject(solution.Projects.OfType<Project>(), name);
if (project == null)
{
throw new Exception($"Project {name} not found in solution");
}
return project;
}
public static Project GetProject(IEnumerable<Project> projects, string name)
{
foreach (Project project in projects)
{
var projectName = project.Name;
if (projectName == name)
{
return project;
}
else if (project.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder)
{
var subProjects = project
.ProjectItems
.OfType<ProjectItem>()
.Where(item => item.SubProject != null)
.Select(item => item.SubProject);
var projectInFolder = GetProject(subProjects, name);
if (projectInFolder != null)
{
return projectInFolder;
}
}
}
return null;
}
#>
I'm working on a project in which I am creating a IronPython compiler depend on IronPython ,
But I have some problem on debugging the Script and can use breakpoint ? could you please give me some help ? thanks. all my code is there: [https://github.com/heyxEvget/IronPython-Debugger]
public ScriptEngine GetEngine()
{
if (_engine != null)
return _engine;
_engine = Python.CreateEngine();
_engine.Runtime.IO.SetOutput(_stream, Encoding.UTF8);
_engine.Runtime.IO.SetErrorOutput(_stream, Encoding.UTF8);
string path = Environment.CurrentDirectory;
string ironPythonLibPath = string.Format(#"{0}\IronPythonLib.zip", path);
var paths = _engine.GetSearchPaths() as List<string> ?? new List<string>();
paths.Add(path);
paths.Add(ironPythonLibPath);
path = Environment.GetEnvironmentVariable("IRONPYTHONPATH");
if (!string.IsNullOrEmpty(path))
{
var pathStrings = path.Split(';');
paths.AddRange(pathStrings.Where(p => p.Length > 0));
}
_engine.SetSearchPaths(paths.ToArray());
return _engine;
}
private void GetPythonVarsInfo(ScriptScope scope)
{
_varList.Clear();
var items = scope.GetItems();
foreach (var item in items)
{
_varList.Add(new VarValue
{
VarName = item.Key,
Value = item.Value
});
}
valueListView.ItemsSource = _varList;
}
private void OnExecuteButtonClick(object sender, ItemClickEventArgs e)
{
string outPutString = string.Empty;
outPutString = "*************************************" +
"Excute Date: " + DateTime.Now.ToLocalTime().ToString(CultureInfo.InvariantCulture);
ExeceutePython(document, outPutString);
TabControl.SelectedIndex = 2;
}
private void ExeceutePython(EditorDocument document, string outPutString)
{
ScriptEngine engine = GetEngine();
string script = document.Text;
ScriptSource source = engine.CreateScriptSourceFromString(script);
ScriptScope scope = _engine.CreateScope();
try
{
source.Compile();
OutputTextBox.AppendText(outPutString + Environment.NewLine);
var result = source.Execute(scope);
if (result != null)
{
OutputTextBox.AppendText(engine.Operations.Format(result));
}
OutputTextBox.AppendText(Environment.NewLine);
GetPythonVarsInfo(scope);
}
catch (Exception ex)
{
var eo = engine.GetService<ExceptionOperations>();
var eoString = eo.FormatException(ex);
OutputTextBox.AppendText(eoString);
return;
}
}
Given this setup code to create the IronPython script engine
var engine = IronPython.Hosting.Python.CreateEngine(new Dictionary<string, object> { { "Debug", ScriptingRuntimeHelpers.True }});
Debug.Assert(engine.Runtime.Setup.DebugMode);
var source = engine.CreateScriptSourceFromFile("script.py");
dynamic result = source.Execute();
You can then use
System.Diagnostics.Debugger.Break()
inside your scripts to get the debugger to break.
You can use visual studio isolated shell for that
Visual Studio Isolated Shell
I hope someone can advise me on the situation I have. I have two asp mvc applications, one is the desktop and the other the mobile version. I want to be able to write files uploaded on the mobile version to a folder in the desktop version, because this latter holds the administrative section of the application. I can download files from one to the other with the WebClient class of .Net, but I haven't been able to upload files from one to the other. I have a console application to test the uploading and whenever I try it I get an error saying "access is denied" to the folder in the application. I tried creating a folder in the application outside of the App_Data folder because I thought this folder is restricted, but I get the same error. Can someone please advise me what to do? I've read googling here and there that this can be easily solved from the IIS administration, but I doubt the guys in my hosting company will be willing to grant me any rights on the administration of any application.
The code I wrote only fails when I try to save the files. Here is the code of the site that receives the request:
[HttpPost]
[AllowAnonymous]
public string SubirArchivosRegistro(HttpPostedFileBase file)
{
string MensajeError = "";
string path = "";
string Success = " El (los) diplomas subidos exitosamente ";
try
{
if (file != null && file.ContentLength > 0)
{
path = Path.Combine(Server.MapPath("~/ArchivosRegistroUsuarios"), file.FileName);
file.SaveAs(path);
Success += file.FileName +",";
}
///return path;
return Success;
}
catch(Exception ex)
{
MensajeError = "Ha ocurrido un error, no se pudieron subir los archivos solicitados "+ex.Message;
return MensajeError;
}
}
And this is the code in the client part (none of the codes is failing, it's just a permissions issue):
try
{
WebClient cliente = new WebClient();
if (GendarmeriaCertNombre != null && GendarmeriaCertNombre.ElementAt(0) != null)
{
gendarmeria = new List<Guid?>();
gendarmeriaNombre = new List<string>();
foreach (HttpPostedFileBase file in GendarmeriaCertNombre)
{
if (file != null)
{
string filename = Path.GetFileName(file.FileName);
Guid guidnum = _fileStore.SaveUploadedFile(file, "gendarmeria");
gendarmeria.Add(guidnum);
gendarmeriaNombre.Add(file.FileName);
string ruta = _fileStore.GetDiskLocation(guidnum);
byte[] respuesta = cliente.UploadFile("http://localhost/DiplomadoEnMandoPolicial/Account/SubirArchivosRegistro", "POST", ruta);
response = System.Text.Encoding.ASCII.GetString(respuesta);
}
}
if (gendarmeria != null && gendarmeria.Count > 0 && gendarmeriaNombre != null && gendarmeriaNombre.Count > 0)
{
registro.GendarmeriaCertificado = String.Join(",", gendarmeria.Select(t => t.Value.ToString("D")));
registro.GendarmeriaCertNombre = String.Join(",", gendarmeriaNombre);
}
}
if (CursoInacipeCertNombre != null && CursoInacipeCertNombre.ElementAt(0) != null)
{
inacipe = new List<Guid?>();
inacipeNombre = new List<string>();
foreach (HttpPostedFileBase file in CursoInacipeCertNombre)
{
if (file != null)
{
string filename = Path.GetFileName(file.FileName);
Guid guidnum = _fileStore.SaveUploadedFile(file, "inacipe");
inacipe.Add(guidnum);
inacipeNombre.Add(file.FileName);
string ruta = _fileStore.GetDiskLocation(guidnum);
byte[] respuesta = cliente.UploadFile("http://localhost/DiplomadoEnMandoPolicial/Account/SubirArchivosRegistro", "POST", ruta);
response = System.Text.Encoding.ASCII.GetString(respuesta);
}
}
if (inacipe != null && inacipe.Count > 0 && inacipeNombre != null && inacipeNombre.Count > 0)
{
registro.CursoInacipeCertificado = String.Join(",", inacipe.Select(t => t.Value.ToString("D")));
registro.CursoInacipeCertNombre = String.Join(",", inacipeNombre);
}
}
if (CursoCideCertNombre != null && CursoCideCertNombre.ElementAt(0) != null)
{
cide = new List<Guid?>();
cideNombre = new List<string>();
foreach (HttpPostedFileBase file in CursoCideCertNombre)
{
if (file != null)
{
string filename = Path.GetFileName(file.FileName);
Guid guidnum = _fileStore.SaveUploadedFile(file, "cide");
cide.Add(guidnum);
cideNombre.Add(file.FileName);
string ruta = _fileStore.GetDiskLocation(guidnum);
byte[] respuesta = cliente.UploadFile("http://localhost/DiplomadoEnMandoPolicial/Account/SubirArchivosRegistro", "POST", ruta);
response = System.Text.Encoding.ASCII.GetString(respuesta);
}
}
if (cide != null && cide.Count > 0 && cideNombre != null && cideNombre.Count > 0)
{
registro.CursoCideCertificado = String.Join(",", cide.Select(t => t.Value.ToString("D")));
registro.CursoCideCertNombre = String.Join(",", cideNombre);
}
cliente.Dispose();
}
}
Well, that's the problem, I'm open to any suggestions.
I need to retrieve items from the 'Inbox\test\final' Exchange folder using EWS. The folder is provided by a literal path as written above. I know I can split this string into folder names and recursively search for the necessary folder, but is there a more optimal way that can translate a string path into a folder instance or folder ID?
I'm using the latest EWS 2.0 assemblies. Do these assemblies provide any help, or am I stuck with manual recursion?
You could use an extended property as in this example
private string GetFolderPath(ExchangeService service, FolderId folderId)
{
var folderPathExtendedProp = new ExtendedPropertyDefinition(26293, MapiPropertyType.String);
var folderPropSet = new PropertySet(BasePropertySet.FirstClassProperties) { folderPathExtendedProp };
var folder = Folder.Bind(service, folderId, folderPropSet);
string path = null;
folder.TryGetProperty(folderPathExtendedProp, out path);
return path?.Replace("\ufffe", "\\");
}
Source: https://social.msdn.microsoft.com/Forums/en-US/e5d07492-f8a3-4db5-b137-46e920ab3dde/exchange-ews-managed-getting-full-path-for-a-folder?forum=exchangesvrdevelopment
Since Exchange Server likes to map everything together with Folder.Id, the only way to find the path you're looking for is by looking at folder names.
You'll need to create a recursive function to go through all folders in a folder collection, and track the path as it moves through the tree of email folders.
Another parameter is needed to track the path that you're looking for.
public static Folder GetPathFolder(ExchangeService service, FindFoldersResults results,
string lookupPath, string currentPath)
{
foreach (Folder folder in results)
{
string path = currentPath + #"\" + folder.DisplayName;
if (folder.DisplayName == "Calendar")
{
continue;
}
Console.WriteLine(path);
FolderView view = new FolderView(50);
SearchFilter filter = new SearchFilter.IsEqualTo(FolderSchema.Id, folder.Id);
FindFoldersResults folderResults = service.FindFolders(folder.Id, view);
Folder result = GetPathFolder(service, folderResults, lookupPath, path);
if (result != null)
{
return result;
}
string[] pathSplitForward = path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
string[] pathSplitBack = path.Split(new[] { #"\" }, StringSplitOptions.RemoveEmptyEntries);
string[] lookupPathSplitForward = lookupPath.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
string[] lookupPathSplitBack = lookupPath.Split(new[] { #"\" }, StringSplitOptions.RemoveEmptyEntries);
if (ArraysEqual(pathSplitForward, lookupPathSplitForward) ||
ArraysEqual(pathSplitBack, lookupPathSplitBack) ||
ArraysEqual(pathSplitForward, lookupPathSplitBack) ||
ArraysEqual(pathSplitBack, lookupPathSplitForward))
{
return folder;
}
}
return null;
}
"ArraysEqual":
public static bool ArraysEqual<T>(T[] a1, T[] a2)
{
if (ReferenceEquals(a1, a2))
return true;
if (a1 == null || a2 == null)
return false;
if (a1.Length != a2.Length)
return false;
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < a1.Length; i++)
{
if (!comparer.Equals(a1[i], a2[i])) return false;
}
return true;
}
I do all the extra array checking since sometimes my clients enter paths with forward slashes, back slashes, starting with a slash, etc. They're not tech savvy so let's make sure the program works every time!
As you go through each directory, compare the desired path to the iterated path. Once it's found, bubble up the Folder object that it's currently on. You'll need to create a search filter for that folder's id:
FindItemsResults<item> results = service.FindItems(foundFolder.Id, searchFilter, view);
Loop through the emails in results!
foreach (Item item in results)
{
// do something with item (email)
}
Here's my recursive descent implementation, which attempts to fetch as little information as possible on the way to the target folder:
private readonly FolderView _folderTraversalView = new FolderView(1) { PropertySet = PropertySet.IdOnly };
private Folder TraceFolderPathRec(string[] pathTokens, FolderId rootId)
{
var token = pathTokens.FirstOrDefault();
var matchingSubFolder = _exchangeService.FindFolders(
rootId,
new SearchFilter.IsEqualTo(FolderSchema.DisplayName, token),
_folderTraversalView)
.FirstOrDefault();
if (matchingSubFolder != null && pathTokens.Length == 1) return matchingSubFolder;
return matchingSubFolder == null ? null : TraceFolderPathRec(pathTokens.Skip(1).ToArray(), matchingSubFolder.Id);
}
For a '/'-delimited path, it can be called as follows:
public Folder TraceFolderPath(string folderPath)
{ // Handle folder names with '/' in them
var tokens = folderPath
.Replace("\\/", "<slash>")
.Split('/')
.Select(t => t.Replace("<slash>", "/"))
.ToArray();
return TraceFolderPathRec(tokens, WellKnownFolderName.MsgFolderRoot);
}
No, you don't need recursion and you efficiently go straight to the folder. This uses the same extended property as Tom, and uses it to apply a search filter:
using Microsoft.Exchange.WebServices.Data; // from nuget package "Microsoft.Exchange.WebServices"
...
private static Folder GetOneFolder(ExchangeService service, string folderPath)
{
var propertySet = new PropertySet(BasePropertySet.IdOnly);
propertySet.AddRange(new List<PropertyDefinitionBase> {
FolderSchema.DisplayName,
FolderSchema.TotalCount
});
var pageSize = 100;
var folderView = new FolderView(pageSize)
{
Offset = 0,
OffsetBasePoint = OffsetBasePoint.Beginning,
PropertySet = propertySet
};
folderView.Traversal = FolderTraversal.Deep;
var searchFilter = new SearchFilter.IsEqualTo(ExchangeExtendedProperty.FolderPathname, folderPath);
FindFoldersResults findFoldersResults;
var baseFolder = new FolderId(WellKnownFolderName.MsgFolderRoot);
var localFolderList = new List<Folder>();
do
{
findFoldersResults = service.FindFolders(baseFolder, searchFilter, folderView);
localFolderList.AddRange(findFoldersResults.Folders);
folderView.Offset += pageSize;
} while (findFoldersResults.MoreAvailable);
return localFolderList.SingleOrDefault();
}
...
public static class ExchangeExtendedProperty
{
/// <summary>PR_FOLDER_PATHNAME String</summary>
public static ExtendedPropertyDefinition FolderPathname { get => new ExtendedPropertyDefinition(0x66B5, MapiPropertyType.String); }
}
The path will need to be prefixed with a backslash, ie. \Inbox\test\final.
I'm working on a utility processing files being under source control using TFS 2010.
If an item is not yet checked-out for edit, I'm getting an exception, what is definitely predictable because file is in read-only mode.
What ways exist to check-out a file?
P.S. I want something for programmatic rather then Process.Start("tf.exe", "..."); if that's applicable.
Some of the other approaches mentioned here only work for certain versions of TFS or make use of obsolete methods. If you are receiving a 404, the approach you are using is probably not compatible with your server version.
This approach works on 2005, 2008, and 2010. I don't use TFS any longer, so I haven't tested 2013.
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
using (var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri))
{
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
}
private const string tfsServer = #"http://tfsserver.org:8080/tfs";
public void CheckOutFromTFS(string fileName)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(tfsServer)))
{
if (pc != null)
{
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(fileName);
if (null != workspaceInfo)
{
Workspace workspace = workspaceInfo.GetWorkspace(pc);
workspace.PendEdit(fileName);
}
}
}
FileInfo fi = new FileInfo(fileName);
}
Note that Microsoft.TeamFoundation.Client.TeamFoundationServerFactory is obsolete: The TeamFoundationServer class is obsolete. Use the TeamFoundationProjectCollection or TfsConfigurationServer classes to talk to a 2010 Team Foundation Server.
In order to talk to a 2005 or 2008 Team Foundation Server use the TeamFoundationProjectCollection class. The corresponding factory class for that is the TfsTeamProjectCollectionFactory.
You can use Team Foundation Version Control client API.
The method is PendEdit()
workspace.PendEdit(fileName);
Checkout detailed example on MSDN
http://blogs.msdn.com/b/buckh/archive/2006/03/15/552288.aspx
First get the workspace
var tfs = new TeamFoundationServer("http://server:8080/tfs/collection");
var version = (VersionControlServer)tfs.GetService(typeof(VersionControlServer));
var workspace = version.GetWorkspace("WORKSPACE-NAME", version.AuthorizedUser);
With the workspace you can checkout the file
workspace.PendEdit(fileName);
var registerdCollection = RegisteredTfsConnections.GetProjectCollections().First();
var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(registerdCollection);
var versionControl = projectCollection.GetService<VersionControlServer>();
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(_fileName);
var server = new TeamFoundationServer(workspaceInfo.ServerUri.ToString());
var workspace = workspaceInfo.GetWorkspace(server);
workspace.PendEdit(fileName);
I have two approaches how to do that: simple and advanced.
1). Simple:
#region Check Out
public bool CheckOut(string path)
{
using (TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri(ConstTfsServerUri)))
{
if (pc == null) return false;
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(path);
Workspace workspace = workspaceInfo?.GetWorkspace(pc);
return workspace?.PendEdit(path, RecursionType.Full) == 1;
}
}
public async Task<bool> CheckoutAsync(string path)
{
return await Task.Run(() => CheckOut(path));
}
#endregion
2). Advanced (with receiving status):
private static string GetOwnerDisplayName(PendingSet[] pending)
{
var result = pending.FirstOrDefault(pendingSet => pendingSet.Computer != Environment.MachineName) ?? pending[0];
return result.OwnerDisplayName;
}
private string CheckoutFileInternal(string[] wsFiles, string folder = null)
{
try
{
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(folder);
var server = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
var workspace = workspaceInfo.GetWorkspace(server);
var request = new GetRequest(folder, RecursionType.Full, VersionSpec.Latest);
GetStatus status = workspace.Get(request, GetOptions.None);
int result = workspace.PendEdit(wsFiles, RecursionType.Full, null, LockLevel.None);
if (result == wsFiles.Length)
{
//TODO: write info (succeed) to log here - messageText
return null;
}
var pending = server.GetService<VersionControlServer>().QueryPendingSets(wsFiles, RecursionType.None, null, null);
var messageText = "Failed to checkout !.";
if (pending.Any())
{
messageText = string.Format("{0}\nFile is locked by {1}", messageText, GetOwnerDisplayName(pending));
}
//TODO: write error to log here - messageText
return messageText;
}
catch (Exception ex)
{
UIHelper.Instance.RunOnUiThread(() =>
{
MessageBox.Show(Application.Current.MainWindow, string.Format("Failed checking out TFS files : {0}", ex.Message), "Check-out from TFS",
MessageBoxButton.OK, MessageBoxImage.Error);
});
return null;
}
}
public async Task<string> CheckoutFileInternalAsync(string[] wsFiles, string folder)
{
return await Task.Run(() => CheckoutFileInternal(wsFiles, folder));
}