TFS Query History with Physical File Path Exception - c#

I have a piece of code that queries the history of tfs but on my machine I get an exception
saying:
There is no working folder mapping for C:\SDAM.
However if I run this same piece of code in colleagues machine there is no problem.
I am using:
Microsoft.TeamFoundation.Client; version 10
Microsoft.TeamFoundation.VersionControl.Client; version 10
VS2012 Project Update 4
4.5 Framework
Things I have tried:
Refreshing the cache
Delete the cache.
Checked the working folders and added them using Team Foundation Sidekicks to be sure I have source control folder and local folder mapped.
I have passed in the source control folder path $/SDAM and I get history. I go into to tfs explorer and check that $/SDAM is mapped to C:\SDAM
I am completely baffled and any suggestions would be appreciated. This code is already being used widely by us and I need to reuse it.
The results of
tf workspaces /format:detailed /collection:http://XXXX/tfs/
Workspace : XXXXXXXX
Owner : Domain\zzzzzzz
Computer : XXXXXXXX
Comment :
Collection : cccc\ddddd
Permissions: Private
Location : Server
File Time : Current
Working folders:
$/SDAM: C:\SDAM
IEnumerable tfsHistory;
string SourceControlPath = #"C:\SDAM";
var tfsUri = new Uri(#"http://XXXX/tfs/");
var tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri);
var vcs = tfs.GetService<VersionControlServer>();
VersionSpec fromVersion = null, toVersion = null;
fromVersion = new ChangesetVersionSpec(1);
toVersion = new ChangesetVersionSpec(2);
tfsHistory =
vcs.QueryHistory(
SourceControlPath,
LatestVersionSpec.Instance,
0,
RecursionType.Full,
null,
fromVersion,
toVersion,
Int32.MaxValue,
true,
false);
if (tfsHistory != null)
{
//Do something
}

Your tool cannot find a working folder mapping because it is not in the working folder cache for the version of the SDK you're building against. If you do not specify a Team Project Collection and want to get connected to TFS by only a local path, TFS will look in the working folder cache to determine what server and server path correspond to that local path.
If you're building against version 10.0 of the SDK, then it's looking for the working folder cache created by Visual Studio 10.0 (ie, Visual Studio 2010.)
However, if you're running Visual Studio 11.0 and tf 11.0, then it will store the working folder information in the working folder cache for Visual Studio 11.0 (ie, Visual Studio 2012.)
Thus, your tool cannot bootstrap itself with only a working folder mapping. You need to either:
Have your tool connect to the TFS server in question so that it will obtain a fresh copy of the working folder information
Match the version of the SDK you build against to the version of TFS you use with Visual Studio
If you want to dynamically load the newest SDK, you may be able to bind an assembly resolution handler.

Related

Is there a way to provide IIS with the location of a DLL that your MVC solution depends on?

I am building an application that scaffolds a SSIS package using EzAPI (Version 0.8.5). The code runs perfect within visual studio, no errors or bugs until I publish the MVC application (.NET 4.5) to the IIS server (Version 10.0.14298). This is when the function fails and doesn't save the package. The following error is thrown on save:
{"The system cannot find the file specified. (Exception from HRESULT:
0x80070002)":null} source: Microsoft.SqlServer.ManagedDTS
I have ensured that SSIS, Integration services have been installed on the IIS server, exact same version as my local instance MSSQL2017 so the DLL's I require are all in the same folders. I deployed to my local instance of IIS and get the same error as well.
using Microsoft.SqlServer.SSIS.EzAPI;
EzPackage _package = new EzPackage() { Name = "Package" };
_package.SaveToFile(#"C:\Package.dtsx"); // Fails here with error
The expectation would be that the package would be generated and then I would be able to view it within the C drive but it looks like it fails when it tries to build / finalize the package
Stack Trace:
" at Microsoft.SqlServer.Dts.Runtime.Package.SaveToXML(String&
packageXml, IDTSEvents events)\r\n at
Microsoft.SqlServer.SSIS.EzAPI.EzPackage.SaveToXML(IDTSEvents
events)\r\n at
Microsoft.SqlServer.SSIS.EzAPI.EzPackage.SaveToFile(String
fileName)\r\n at method(ViewModel model) in Logic.cs:line 641"
Try creating a folder in C:. For example, C:\packages. Make sure the app pool user has read/write access to the folder. Try adding IUSR or the app pool ( IIS AppPool\ApplicationPoolName ) user to the C:\packages folder with read write permissions.

.NET executables do not work after overwritten with new versions

I faced very strange behaviour - after I overwrite .NET exectables with new versions from network drive it cannot start.
When try to start from Windows Explorer it shows me following error:
[Window Title]
C:\Programs\zzz\clients.net\zzzNet.exe
[Content]
C:\Programs\zzz\clients.net\zzzNet.exe
The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail.
I tried to execute following commands:
SxsTrace Trace -logfile:SxsTrace.etl
SxStrace Parse -logfile:SxSTrace.etl -outfile:SxSTrace.txt
And got following result:
=================
Begin Activation Context Generation.
Input Parameter:
Flags = 0
ProcessorArchitecture = AMD64
CultureFallBacks = en-US;en;ru-RU;ru
ManifestPath = C:\Programs\zzz\clients.net\zzzNet.exe
AssemblyDirectory = C:\Programs\zzz\clients.net\
Application Config File = C:\Programs\zzz\clients.net\zzzNet.exe.Config
-----------------
INFO: Parsing Application Config File C:\Programs\zzz\clients.net\zzzNet.exe.Config.
INFO: Parsing Manifest File C:\Programs\zzz\clients.net\zzzNet.exe.
INFO: Manifest Definition Identity is (null).
ERROR: Line 0: XML Syntax error.
ERROR: Activation Context generation failed.
End Activation Context Generation.
It is quite simple .NET application (1 exe + 8 dll files). It was built for .NET 3.5 Client Profile.
I not defined any special "manifest" there. Just clicked "New Windows Forms Project" in Visual Studio and developed it.
Also app.config does not contain anything special - only primitive standard settings - appSettings and userSettings sections.
On PC where I developed it all is perfectly works. Problems only began when I copy these binaries to this particular VM and try to start.
Also please note - these executables were not installed in GAC or such, I just copied them into a folder on VM and started. And when it was 1st time all was working fine.
So, the problem pattern is following:
Copy .NET execuatbles to new VM (it is Win 7 x64), run it, all is working fine. Close it.
Build new version of .NET execuatbles on host PC, copy new .NET execuatbles to VM (with files overwriting).
Try to start - got mentioned problem.
After some shaman-style actions (like OS reboot, etc) it begin to work but why that happened at all?!
Why replacing .NET executables with new versions is causing SUCH HUGE PROBLEMS?!
Also the BIG QUESTION - is there any special procedure to replace .NET executables to keep them working? Because it is a new app development, I do not want lost so much time on every new executables installation. :-\
Could you please help? Because it looks completely weird!
Thank you in adance.
PS. I checked all VS projects - all they have PlatformTarget=AnyCPU. Also in run-time I can see ProcessType=MSIL (I show this info in AboutBox for application). So, there is no mix of x86/x64 binaries.
It seems that was related to mapped network drive behavior.
When I copied new files from network drive folder it copied wrong files - a strange random mess of new files and older ones (which were there before I updated them on VM host).
The scenario to make it working:
on VM: delete all files in a folder on network drive
on VM host: copy new files into a folder which is mapped as network drive on VM
on VM: copy files into target folder
on VM: run application - it works now
Weird thing. I remember I have seen something similar with Windows Explorer on Windows 2008 behaviour when copying updated win32 binaries.

TuesPechkin unable to load DLL 'wkhtmltox.dll'

I've been using TuesPechkin for some time now and today I went to update the nuget package to the new version 2.0.0+ and noticed that Factory.Create() no longer resolved, so I went to read on the GitHub the changes made and noticed it now expects the path to the dll?
IConverter converter =
new ThreadSafeConverter(
new PdfToolset(
new StaticDeployment(DLL_FOLDER_PATH)));
For the past few hours I've tried almost all the paths I can think of, "\bin", "\app_data", "\app_start", etc and I can't seem to find or figure out what it wants for the path and what dll?
I can see the TuesPechkin dll in my bin folder and it was the first path I tried, but I got the following error:
Additional information: Unable to load DLL 'wkhtmltox.dll': The
specified module could not be found. (Exception from HRESULT:
0x8007007E)
Where is that dll and now can I get it as the library doesn't seem to contain it, I tried installing the TuesPechkin.Wkhtmltox.Win32 package but the dll still is nowhere to be found. Also I am using this in a asp.net website project so I assume that using the following should work for obtaining the path, right?
var path = HttpContext.Current.Server.MapPath(#"~\bin\TuesPechkin.dll");
Further information: https://github.com/tuespetre/TuesPechkin/issues/57
The Tuespechkin has a zip file as a resource in the Win32 and Win64 embedded packages for the 'wkhtmltox.dll' file.
What it does when you use the Win32 or Win64 Embedded package is unzips the file and places it in the directory that you specify.
I have been putting a copy of the wkhtmltox dll at the root portion of my web app directory and pointing the DLL_FOLDER_PATH to it using the server physical path of my web app to get to it.
According to the author, you must set the converter in a static field for best results.
I do that, but set the converter to null when I am finished using it, and that seems to work.
Tuespechkin is wrapper for the wmkhtmlox dll file.
The original file is written in C++ and so will not automatically be usable in C# or VB.NET or any of the other managed code domains.
The Tuespechkin.dll file DOES NOT contain a copy of 'wkhtmltox.dll'. You either have to use one of the other embedded deployment modules or install a copy of the 'wkhtmltox.dll' in your web app after downloading it from the internet. That is what I do, and it seems to work just fine.
I am using Team Foundation Server, and attempts to compile code after using the Tuespechkin routines will fail the first time because the 'wkhtmltox.dll' file gets locked, but all you have to do is simply retry your build and it will go through.
I had issues with the 32-bit routine not working in a 64-bit environment and the 64-bit environment not being testable on localhost. I went with the workaround I came up with after examining the source code for Tuespechkin and the Win32 and Win64 embedded deployment packages.
It works well as long as you specify a url for the input rather than raw html.
The older package didn't render css very well.
If you are using a print.aspx routine, you can create the url for it as an offset from your main url.
I don't have the source code I am using with me at this point to offset to your base url for your web application, but it is simply an offshoot of HttpRequest.
You have to use the physical path to find the .dll, but you can use a web path for the print routine.
I hope this answers your question a bit.
If you are getting this error -> Could not load file or assembly 'TuesPechkin.Wkhtmltox.Win64' or one of its dependencies. An attempt was made to load a program with an incorrect format.
In Visual Studio Go to -
Tools -> Options -> Projects and Solutions -> Web Projects -> Use the 64 bit version of IIS Express for web sites and projects.
I installed TuesPechkin.Wkhtmltox.Win64 Nuget package and used the following code in a singleton:
public class PechkinPDFConvertor : IPDFConvertor
{
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
public byte[] Convert(string html)
{
// return PechkinSync.Convert(new GlobalConfig(), html);
return converter.Convert(new HtmlToPdfDocument(html));
}
}
The web application then has to be run in x64 otherwise you will get an error about trying to load an x64 assembly in an x86 environment. Presumably you have to choose x64 or x86 at design time and use the corresponding nuget package, it would be nicer to choose this in the web.config.
EDIT: The above code failed on one server with the exact same message as yours - it was due to having not installed VC++ 2013. So the new code is running x86 as follows
try
{
string path = Path.Combine(Path.GetTempPath(), "MyApp_PDF_32");
Converter = new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new StaticDeployment(path))));
}
catch (Exception e)
{
if (e.Message.StartsWith("Unable to load DLL 'wkhtmltox.dll'"))
{
throw new InvalidOperationException(
"Ensure the prerequisite C++ 2013 Redistributable is installed", e);
}
else
throw;
}
If you do not want run the installer for wkhtmltox just to get the dll, you can do the following:
As #Timothy suggests, if you use the embedded version of wkhtmltox.dll from TuesPechkin, it will unzip it and place it in a temp directory. I copied this dll and referenced it with the StaticDeployment option without any issues.
To find the exact location, I just used Process Monitor (procmon.exe). For me it was C:\Windows\Temp\-169958574\8\0.12.2.1\wkhtmltox.dll
In my case, I am deploying on a 64-bit VPS then I got this error. I have solved the problem by installing the wkhtmltopdf that I downloaded from http://wkhtmltopdf.org/downloads.html. I chose the 32-bit installer.
In my case, I have solved the problem by installing the Wkhtmltox for win32 at https://www.nuget.org/packages/TuesPechkin.Wkhtmltox.Win32/
This error: Unable to load DLL 'wkhtmltox.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) is returned in two situations:
1- Deploy dependency not installed:
For solve this, you can install nuget package "TuesPechkin.Wkhtmltox.Win64" and use this code (for WebApplications running in IIS):
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!
byte[] result = converter.Convert(document);
In runtime this code will copy the dependency "wkhtmltox.dll" in a temporary directory like: "C:\Windows\Temp\1402166677\8\0.12.2.1". It's possible to get the destination of file using:
var deployment = new Win64EmbeddedDeployment(new TempFolderDeployment());
Console.WriteLine(deployment.Path);
2- Microsoft Visual C++ 2013 Redistributable not installed:
As described here:
https://github.com/tuespetre/TuesPechkin/issues/65#issuecomment-71266114, the Visual C++ 2013 Runtime is required.
The solution from README is:
You must have Visual C++ 2013 runtime installed to use these packages. Otherwise, you will need to download the MingW build of wkhtmltopdf and its dependencies from their website and use that with the library. https://github.com/tuespetre/TuesPechkin#wkhtmltoxdll
or, you can install the Microsoft Visual C++ 2013 Redistributable:
choco install msvisualcplusplus2013-redist
Here is AnyCpu version, also support iis-base or winform application
using TuesPechkin.Wkhtmltox.AnyCPU;
...
var converter = PDFHelper.Factory.GetConverter();
var result = converter.Convert(This.Document);
Reference : https://github.com/tloy1966/TuesPechkin
Installing the Visual C++ Redistributable for Visual Studio 2013 resolved the error for me.
https://www.microsoft.com/en-us/download/details.aspx?id=40784

TFS API: GetLocalWorkspaceInfo always returns null

On one of my machines, I get a return value of null from any GetLocalWorkspaceInfo call. I have isolated to problem to where it even fails for this simple program:
namespace WorkstationTest
{
using Microsoft.TeamFoundation.VersionControl.Client;
class Program
{
static void Main()
{
string workspaceLocalPath = #"C:\Dev";
var info = Workstation.Current
.GetLocalWorkspaceInfo(workspaceLocalPath);
// info is always null here
}
}
}
What I have already checked:
The exact same code works on my other machine the way it should.
I have verified that I have a workspace at C:\Dev
I have created a new workspace and in a different directory and changed the workspaceLocalPath variable in the code to match.
I have consulted the documentation which states that the return value will be null if the path is not in a workspace. From the above image, the path should be in a workspace.
Yet, everything seems to suggest this should work. Is there anything I could be missing?
After migrating from TFS2013 to TFS2017 in the company I work for I had the same problem with Workstation.Current.GetLocalWorkspaceInfo.
What worked for me is a call to Workstation.EnsureUpdateWorkspaceInfoCache:
TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("<your-tfs-uri-here>"));
VersionControlServer tfServer = tpc.GetService<VersionControlServer>();
Workstation.Current.EnsureUpdateWorkspaceInfoCache(tfServer, tfServer.AuthorizedUser);
I added the above code lines to the constructor of my TFS proxy class that uses GetLocalWorkspaceInfo.
When executing tf workspaces (on my computer) in the Visual Studio 2010 command prompt it says No workspace matching * found on this computer, but when executing the same command in Visual Studio 2012 it returns back all my expected workspaces.
The issue can be resolved by doing any of the following:
Reference the version of the Microsoft.TeamFoundation.VersionControl.Client dll that was connected with Visual Studio 2012 instead of the dll connected with Visual Studio 2010.
Open Visual Studio 2010 and connect it to TFS to where it will create the workspaces for Visual Studio 2010
I know this is an old post, but just like to share the workaround that we have, by using VersionControlServer.QueryWorkspaces to query all the workspaces for the user on his/her machine.
private static Workspace FindWorkspaceByPath(TfsTeamProjectCollection tfs, string workspacePath)
{
VersionControlServer versionControl = tfs.GetService<VersionControlServer>();
WorkspaceInfo workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(workspacePath);
if (workspaceInfo != null)
{
return versionControl.GetWorkspace(workspaceInfo);
}
// No Workspace found using method 1, try to query all workspaces the user has on this machine.
Workspace[] workspaces = versionControl.QueryWorkspaces(null, Environment.UserName, Environment.MachineName);
foreach (Workspace w in workspaces)
{
foreach (WorkingFolder f in w.Folders)
{
if (f.LocalItem.Equals(workspacePath))
{
return w;
}
}
}
throw new Exception(String.Format("TFS Workspace cannot be determined for {0}.", workspacePath));
}
In my case, this issue occurred because of VersionControl.config file put under TFS cache folder (C:\Users\DeepakR\AppData\Local\Microsoft\Team Foundation\5.0\Cache\Volatile\0cb76a25-2556-4bd6-adaa-5e755ac07355_http) goes for a toss i.e. the configured workspace information weren't available as expected.
So, it basically needs a refresh of VersionControl.config file. Auto Refresh happens when Visual Studio gets loaded again i.e. it pulls the configured workspace information from Server and updates the config file or even if we execute tf command utility (tf.exe workspaces /collection:TFSURL)
Microsoft.TeamFoundation.VersionControl.Client's (v12.0.0.0) Workstation class has a function EnsureUpdateWorkspaceInfoCache which will do the same trick
VersionControlServer vcs = (VersionControlServer)tpc.GetService(typeof(VersionControlServer));
Workstation.Current.EnsureUpdateWorkspaceInfoCache(vcs, Environment.UserName);
https://msdn.microsoft.com/en-us/library/microsoft.teamfoundation.versioncontrol.client.workstation.ensureupdateworkspaceinfocache(v=vs.120).aspx
Hope the suggestion helps to resolve the issue.
I had this issue recently (today) using Visual Studio 2017, plus several other versions installed and a number of local workspaces.
I ended up updating the 'Team Foundation Server Client' NuGet package to the latest version (15.x) through the 'Manage NuGet Packages' menu and that fixed it.
I did also remove the existing project references first but that part might depend on what you need.
Simply run with the tricks.
Nothing is going to work properly without a proper DLL reference. The below had fixed the same issue i had for 5 days as it was screwing my time up.
Place the below DLL's in the bin folder of your project and give a reference to the whole solution for all the DLL's. If any error comes up like 'Reference could not be given' ignore it and skip that DLL from giving reference instead just place also the error creating DLL in bin folder which the project will automatically take during build
DLL's:
Microsoft.TeamFoundation.Client.dll
Microsoft.TeamFoundation.Common.dll
Microsoft.TeamFoundation.Core.WebApi.dll
Microsoft.TeamFoundation.TestManagement.Client.dll
Microsoft.TeamFoundation.TestManagement.Common.dll
Microsoft.TeamFoundation.Work.WebApi.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader.dll
Microsoft.TeamFoundation.WorkItemTracking.Client.dll
Microsoft.TeamFoundation.WorkItemTracking.Common.dll
Microsoft.TeamFoundation.WorkItemTracking.Controls.dll
Microsoft.TeamFoundation.WorkItemTracking.Proxy.dll
Microsoft.TeamFoundation.WorkItemTracking.WebApi.dll
Microsoft.VisualStudio.Services.Client.Interactive.dll
Microsoft.VisualStudio.Services.Common.dll
Microsoft.VisualStudio.Services.WebApi.dll
Microsoft.WITDataStore32.dll
Microsoft.WITDataStore64.dll
The above dll's can be found in the below path if the System is installed with MTM or TFS
Path: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer
In my C:\Users\<username>\AppData\Local\Microsoft\Team Foundation folder I had 2 folders:
7.0
8.0
Within the 8.0 folder was the following folder:
\Cache\Volatile\c1dbda02-c575-4dd2-b221-e83f7cb63665_http
But within the 7.0 folder the \Cache\Volatile folder was empty
So all I did was copy across the c1dbda02-c575-4dd2-b221-e83f7cb63665_http folder into 7.0\Cache\Volatile\
After this GetLocalWorkspaceInfo call returned the workspace info successfully
This is how to find workspace when you have server path:
Workspace[] workspaces = _versionControl.QueryWorkspaces(null, Environment.UserName, Environment.MachineName);
return workspaces.FirstOrDefault(w => !string.IsNullOrEmpty(w.TryGetLocalItemForServerItem(ConstDefaultFlowsTfsPath)));
Where ConstDefaultFlowsTfsPath is server path with "$" for instance : "$/MyCompany/Services/DiagnosticsFlows"
You could also replace the last line to:
return workspaces.FirstOrDefault(w => !string.IsNullOrEmpty(w.GetServerItemForLocalItem(myLocalPath)));
and that should work for you too.

How do I get a list of Team Foundation Server Servers available on my PC?

I need to get Team Foundation Server list programmatically with C#.
This is needed for the TfsTeamProjectCollection object.
I had a scan through the documentation and couldn't find anything useful. I believe #samy is correct and there is no discovery mechanism.
However if you are running this on a client machine that already has established connections to TFS then there is a history of servers stored in the registry:
Visual Studio 2008 location:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\TeamFoundation\Servers
Visual Studio 2010:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\TeamFoundation\Instances\
Visual Studio 2012
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\TeamFoundation\Instances\
Visual Studio 2013
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0\TeamFoundation\Instances\
Visual Studio 2015
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0\TeamFoundation\Instances\
I think the responsibility of keeping track of the servers is your responsibility. There's no discovery options for the servers as far as i know. So you need the uris
For Visual Studio 2012, the location in the registry key is:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\11.0\TeamFoundation\Instances\tfs
To list all workspaces that "tf workspaces" would return (which includes URI and mapped paths):
var allWorkspaceInfos = Workstation.Current.GetAllLocalWorkspaceInfo();
To get the TFS workspace containing a particular directory:
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(#"C:\Users\joey\tfs");
I found this by decompiling TF.exe. But there is documentation for the Workstation class.
These methods return WorkspaceInfo objects. To perform source control operations, you need to connect to the server and get a Workspace object:
var collection = new TfsTeamProjectCollection(workspaceInfo.ServerUri);
collection.Authenticate();
var server = collection.GetService<VersionControlServer>();
var workspace = server.GetWorkspace(scriptRoot);

Categories