TFS SDK launch threeway merge - c#

There is a class for ThreeWayMerge in TFS SDK. There is a function to Run it. There is a property to run merge in external tool. But when I run code like this to resolve conflict, nothing is happening. No error. No result. Output temporary file gets deleted. When I would expect tool to be launched like it does with Difference.VisualDiffItems. Am I wrong in my expectations or doing something wrong?
public void Merge(string sourceFile)
{
string tempBase = Path.GetTempFileName();
string tempLatest = Path.GetTempFileName();
string tempModified = Path.GetTempFileName();
string tempOutput = Path.GetTempFileName();
Conflict[] conflicts = workSpace.QueryConflicts(new string[] { sourceFile }, false);
Conflict cnf = conflicts[0];
cnf.DownloadBaseFile(tempBase);
//cnf.DownloadYourFile(tempModified);
File.Copy(cnf.LocalPath, tempModified,true);
cnf.DownloadTheirFile(tempLatest);
int baseCodePage = FileType.Detect(tempBase, null);
int latestCodePage = FileType.Detect(tempLatest, null);
int modifiedCodePage = FileType.Detect(tempModified, null);
ThreeWayMerge threeWayMerge = new ThreeWayMerge();
threeWayMerge.UseExternalMergeTool = true;
threeWayMerge.UseExternalAutomergeTool = true;
threeWayMerge.VersionControlServerGuid = VCS.ServerGuid;
threeWayMerge.LatestFileName = tempLatest;
threeWayMerge.LatestFileEncoding = Encoding.GetEncoding(latestCodePage);
threeWayMerge.ModifiedFileName = tempModified;
Encoding modifiedEncoding = Encoding.GetEncoding(modifiedCodePage);
threeWayMerge.ModifiedFileEncoding = modifiedEncoding;
threeWayMerge.OriginalFileName = tempBase;
threeWayMerge.OriginalFileEncoding = Encoding.GetEncoding(baseCodePage);
threeWayMerge.MergedFileName = tempOutput;
threeWayMerge.MergedFileEncoding = modifiedEncoding;
if (threeWayMerge.Run())
{
Console.WriteLine("Something");
}
}

Related

Azure File Storage: Create nested directories

My code looks like this
CloudFileClient client = ...;
client.GetShareReference("fileStorageShare")
.GetRootDirectoryReference()
.GetDirectoryReference("one/two/three")
.Create();
This errors if directories one or two don't exist. Is there a way to create these nested directories with a single call?
It is impossible. The SDK does not support it this way, you should create them one by one.
A issue has already submitted here.
If you wanna create them one by one, you can use the following sample code:
static void NestedDirectoriesTest()
{
var cred = new StorageCredentials(accountName, accountKey);
var account = new CloudStorageAccount(cred, true);
var client = account.CreateCloudFileClient();
var share = client.GetShareReference("temp2");
share.CreateIfNotExists();
var cloudFileDirectory = share.GetRootDirectoryReference();
//Specify the nested folder
var nestedFolderStructure = "Folder/SubFolder";
var delimiter = new char[] { '/' };
var nestedFolderArray = nestedFolderStructure.Split(delimiter);
for (var i=0; i<nestedFolderArray.Length; i++)
{
cloudFileDirectory = cloudFileDirectory.GetDirectoryReference(nestedFolderArray[i]);
cloudFileDirectory.CreateIfNotExists();
Console.WriteLine(cloudFileDirectory.Name + " created...");
}
}
Following the advice of Ivan Yang, I adapted my code using Azure.Storage.Files.Shares (Version=12.2.3.0).
Here's my contribution:
readonly string storageConnectionString = "yourConnectionString";
readonly string shareName = "yourShareName";
public string StoreFile(string dirName,string fileName, Stream fileContent)
{
// Get a reference to a share and then create it
ShareClient share = new ShareClient(storageConnectionString, shareName);
share.CreateIfNotExists();
// Get a reference to a directory and create it
string[] arrayPath = dirName.Split('/');
string buildPath = string.Empty;
var tempoShare = share;
ShareDirectoryClient directory = null; // share.GetDirectoryClient(dirName);
// Here's goes the nested directories builder
for (int i=0; i < arrayPath.Length; i++)
{
buildPath += arrayPath[i];
directory = share.GetDirectoryClient(buildPath);
directory.CreateIfNotExists();
buildPath += '/';
}
// Get a reference to a file and upload it
ShareFileClient file = directory.GetFileClient(fileName);
using (Stream stream = fileContent)
{
file.Create(stream.Length);
file.UploadRange(new HttpRange(0, stream.Length), stream);
}
return directory.Path;
}
Here is a simplified version of Hagen's code:
public async Task<ShareFileClient> CreateFileClient(string connection, string shareName, string path)
{
var share = new ShareClient(connection, shareName);
await share.CreateIfNotExistsAsync();
var dir = share.GetRootDirectoryClient();
var pathChain = path.Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
int dirCount = pathChain.Length - 1;
for (int i = 0; i < dirCount; ++i)
{
dir = dir.GetSubdirectoryClient(pathChain[i]);
await dir.CreateIfNotExistsAsync();
}
return dir.GetFileClient(pathChain[dirCount]);
}

Creating Large List<T>

I have the following code:
var lstMusicInfo = new List<MediaFile>();
var LocalMusic = Directory.EnumerateFiles(AppSettings.Default.ComputerMusicFolder, "*.*", SearchOption.AllDirectories).AsParallel().ToList<string>();
LocalMusic = (from a in LocalMusic.AsParallel()
where a.EndsWith(".mp3") || a.EndsWith(".wma")
select a).ToList<string>();
var DeviceMusic = adb.SyncMedia(this.dev, AppSettings.Default.ComputerMusicFolder, 1);
Parallel.ForEach(LocalMusic, new Action<string>(item =>
{
try
{
UltraID3 mFile = new UltraID3();
FileInfo fInfo;
mFile.Read(item);
fInfo = new FileInfo(item);
bool onDevice = true;
if (DeviceMusic.Contains(item))
{
onDevice = false;
}
// My Problem starts here
lstMusicInfo.Add(new MediaFile()
{
Title = mFile.Title,
Album = mFile.Album,
Year = mFile.Year.ToString(),
ComDirectory = fInfo.Directory.FullName,
FileFullName = fInfo.FullName,
Artist = mFile.Artist,
OnDevice = onDevice,
PTDevice = false
});
//Ends here.
}
catch (Exception) { }
}));
this.Dispatcher.BeginInvoke(new Action(() =>
{
lstViewMusicFiles.ItemsSource = lstMusicInfo;
blkMusicStatus.Text = "";
doneLoading = true;
}));
#endregion
}));
The first part of the code gives me almost instant result containing:
Address on computer of 5780 files.
Get list of all music files on an android device compare it with those 5780 files and return a list of files found on computer but not on device (in my case it returns a list with 5118 items).
The block of code below is my problem, I am filling data into a class, then adding that class into a List<T>, doing it for 5780 times takes 60 seconds, how can I improve it?
// My Problem starts here
lstMusicInfo.Add(new MediaFile
{
Title = mFile.Title,
Album = mFile.Album,
Year = mFile.Year.ToString(),
ComDirectory = fInfo.Directory.FullName,
FileFullName = fInfo.FullName,
Artist = mFile.Artist,
OnDevice = onDevice,
PTDevice = false
});
//Ends here.
Update:
Here is the profiling result and I see it's obvious why it's slowing down >_>
I suppose I should look for a different library that reads music file information.
One way to avoid loading everything once, up front, would be to lazy load the ID3 information as necessary.
You'd construct your MediaFile instances thus...
new MediaFile(filePath)
...and MediaFile would look something like the following.
internal sealed class MediaFile
{
private readonly Lazy<UltraID3> _lazyFile;
public MediaFile(string filePath)
{
_lazyFile = new Lazy<UltraID3>(() =>
{
var file = new UltraID3();
file.Read(filePath);
return file;
});
}
public string Title
{
get { return _lazyFile.Value.Title; }
}
// ...
}
This is possibly less ideal than loading them as fast as you can in the background, if you do something like MediaFiles.OrderBy(x => x.Title).ToList() and nothing has been lazy loaded then you'll have to wait for every file to load.
Loading them in the background would make them available for use immediately after the background loading has finished. But you might have to concern yourself with not accessing some items until the background loading has finished.
You biggest bottleneck is new FileInfo(item), but you don't need FileInfo just to get the Directory and File names. You can use Path.GetDirectoryName and Path.GetFileName, which are must faster since no I/O is involved.
UltraID3 mFile = new UltraID3();
//FileInfo fInfo;
mFile.Read(item);
//fInfo = new FileInfo(item);
bool onDevice = true;
if (DeviceMusic.Contains(item))
{
onDevice = false;
}
// My Problem starts here
lstMusicInfo.Add(new MediaFile()
{
Title = mFile.Title,
Album = mFile.Album,
Year = mFile.Year.ToString(),
ComDirectory = Path.GetDirectoryName(item), // fInfo.Directory.FullName,
FileFullName = Path.GetFileName(item), //fInfo.FullName,
Artist = mFile.Artist,
OnDevice = onDevice,
PTDevice = false
});
//Ends here.

WebConsumer.ProcessUserAuthorization returns null

I use DotNetOpenAuth.
So.. I am getting looking good response which has state Authenticated.
That is fine.
Now I want to get user profile info but always getting NULL.
Here is the code.
private ServiceProviderDescription GetServiceDescription()
{
string ValidateTokenEndPoint = ConfigurationManager.AppSettings["identityOAuthValidateTokenEndPointUrl"];
string ValidateAuthorizationHeaderEndPoint = ConfigurationManager.AppSettings["identityOAuthValidateAuthorizationHeaderEndPointUrl"];
string AccessTokenEndPoint = ConfigurationManager.AppSettings["identityOAuthAccessTokenURL"];
bool UseVersion10A = Convert.ToBoolean(ConfigurationManager.AppSettings["identityOAuthUseVersion10a"]);
string RequestTokenStr = ConfigurationManager.AppSettings["identityOAuthRequestTokenURL"];
string UserAuthStr = ConfigurationManager.AppSettings["identityOAuthAuthorizeUserURL"];
string AccessTokenStr = ConfigurationManager.AppSettings["identityOAuthAccessTokenURL"];
string InvalidateTokenStr = ConfigurationManager.AppSettings["identityOAuthRequestInvalidateTokenURL"];
return new ServiceProviderDescription
{
AccessTokenEndpoint = new MessageReceivingEndpoint(AccessTokenStr, HttpDeliveryMethods.PostRequest),
RequestTokenEndpoint = new MessageReceivingEndpoint(RequestTokenStr, HttpDeliveryMethods.PostRequest),
UserAuthorizationEndpoint = new MessageReceivingEndpoint(UserAuthStr, HttpDeliveryMethods.PostRequest),
TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
ProtocolVersion = DotNetOpenAuth.OAuth.ProtocolVersion.V10a
};
}
void GetUserProfile()
{
var tokenManager = TokenManagerFactory.GetTokenManager(TokenManagerType.InMemoryTokenManager);
tokenManager.ConsumerKey = ConfigurationManager.AppSettings["identityOAuthConsumerKey"];
tokenManager.ConsumerSecret = ConfigurationManager.AppSettings["identityOAuthConsumerSecret"];
var serviceDescription = GetServiceDescription();
var consumer = new WebConsumer(serviceDescription, tokenManager);
var result = consumer.ProcessUserAuthorization(response);
if (result != null) // It is always null
{
}
Well I checked 10 times and I am pretty sure that all URLs to create ServiceProviderDescription are correct.
Any clue?
Well
finally check your web.config app keys
add key="identityOAuthConsumerKey" value="put here correct data!!!"
add key="identityOAuthConsumerSecret" value="put here correct data!!!"
and if you use hosts file you have to put correct sitename as well
127.0.0.1 site1.host1.com

Execute tf.exe (TFS) from C# halts

I need to get the revision number from TFS, if i run tf.exe from a Process the process halts. If i run the same command from command promts it works?
int revision;
var repo = "path to repo"
var psi = new ProcessStartInfo("cmd", #"/c ""C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe"" properties $/MYProject -recursive /version:W")
{
UseShellExecute = false,
ErrorDialog = false,
CreateNoWindow = false,
WorkingDirectory = repo,
RedirectStandardOutput = true,
RedirectStandardError = true
};
using (var p = Process.Start(psi))
{
p.WaitForExit();
if (p.ExitCode != 0)
{
using (var standardError = p.StandardError)
{
Console.WriteLine(standardError.ReadToEnd());
}
}
else
{
using (var standardOutput = p.StandardOutput)
{
revision = int.Parse(standardOutput.ReadToEnd());
}
}
}
edit:
I did this, works, should I go with it?
public int GetLatestChangeSet(string url, string project)
{
var server = new TeamFoundationServer(new Uri(url));
var version = server.GetService(typeof(VersionControlServer)) as VersionControlServer;
var items = version.GetItems(string.Format(#"$\{0}", project), RecursionType.Full);
return items.Items.Max(i => i.ChangesetId);
}
you better use the below namespace which contains all you need to achieve that
Microsoft.TeamFoundation.VersionControl.Client
//this is just an example
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.VersionControl.Client;
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("http://myserver:8080/"));
VersionControlServer sourceControl = tpc.GetService<VersionControlServer>();
return sourceControl.GetLatestChangesetId();
http://msdn.microsoft.com/en-us/library/ms228232(v=vs.80)
The error occurs because your StandardOutput stream buffer is full and thus blocks. To read standard input/output it's recommended to subscribe to the OutputDataReceived event. Alternatively, spin up another thread to constantly read the data from the StandardOutput stream.
See the example on the OutputDataReceived event docs for a complete code sample.
A better solution would be to use the TFS API as suggested by Massimiliano Peluso. But this is the reason for your approach failing.
I ended up with this solution which uses the local workspace revision
public class ReadTfsRevisionTask : Task
{
public override bool Execute()
{
try
{
ChangesetId = GetLatestChangeSet(Server, Project);
return true;
}
catch
{
return false;
}
}
private int GetLatestChangeSet(string url, string project)
{
project = string.Format(#"$/{0}", project);
var server = new TeamFoundationServer(new Uri(url));
var version = server.GetService<VersionControlServer>();
var workspace = version.QueryWorkspaces(null, WindowsIdentity.GetCurrent().Name, System.Environment.MachineName).First();
var folder = workspace.Folders.First(f => f.ServerItem == project);
return workspace.GetLocalVersions(new[] { new ItemSpec(folder.LocalItem, RecursionType.Full) }, false)
.SelectMany(lv => lv.Select(l => l.Version)).Max();
}
[Required]
public string Server { get; set; }
[Required]
public string Project { get; set; }
[Output]
public int ChangesetId { get; set; }
}

Encoder SDK 4 - Push to Publishing Point

I'm coding an application in c# using EC4 SP2 SDK.
I want to publish my file to a media server publishing point. I've searched and found 2 examples regarding seting up and auth on publishing points, but either are from older sdk's or do not work (and are for console). basicly my application doesn't encode nothing, as if it had nothing to encode.
When in degub mode checkpont i can see the correct properties for the source file and for the server.
The encoding process takes 0secs to process. I checked the logs on the server events and i get a warning "the security system has received and auth request that could not be decoded". I just havo no knowledge to break up further than this. Any help would be appreciated.
this is the piece of code:
private void broadcastSourceFileToMediaServer2()
{
using (LiveJob job = new LiveJob())
{
String filetoencode = #"c:\temp\niceday.wmv";
LiveFileSource filesource = job.AddFileSource(filetoencode);
filesource.PlaybackMode = FileSourcePlaybackMode.Loop;
job.ActivateSource(filesource);
job.ApplyPreset(LivePresets.VC1Broadband4x3);
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
job.PublishFormats.Add(pubpoint);
job.PreConnectPublishingPoint();
job.StartEncoding();
statusBox.Text = job.NumberOfEncodedSamples.ToString();
job.StopEncoding();
job.Dispose();
}
}
public static string _myUserName { get; set; }
public static SecureString _pw { get; set; }
//codificação de Password a enviar
private static SecureString PullPW(string pw)
{
SecureString s = new SecureString();
foreach (char c in pw) s.AppendChar(c);
return s;
}
static void job_AcquireCredentials(object sender, AcquireCredentialsEventArgs e)
{
e.UserName = _myUserName;
e.Password = _pw;
e.Modes = AcquireCredentialModes.None;
}
Progresses:
I managed to authenticate (at least get a positive audit event) on the server.
I changed from this:
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
To this:
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = #"mediaservername\user";
_pw = PullPW("user_password");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
If you see on one side if had to include the domain (either domain or computername) before username. this changed the failed audit events on the server, so i could eliminate the manual credentials pubpoint.username and pubpoint.Password.
Now I'm just dealing with a lack of output format exception. On to it.
How about using SMOOTH Streaming, I managed to get my project going but I didn't get much more beyond Look below, to the part that has the PUBLISH switch type. ignore the file portion
internal bool StartStream()
{
Busy = true;
// Instantiates a new job for encoding
//
//***************************************Live Stream Archive******************************
if (blnRecordFromFile)
{
// Sets up publishing format for file archival type
FileArchivePublishFormat fileOut = new FileArchivePublishFormat();
// job.ApplyPreset(LivePresets.VC1512kDSL16x9);
// Gets timestamp and edits it for filename
string timeStamp = DateTime.Now.ToString();
timeStamp = timeStamp.Replace("/", "-");
timeStamp = timeStamp.Replace(":", ".");
// Sets file path and name
string path = "C:\\output\\";
string filename = "Capture" + timeStamp + ".ismv";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
fileOut.OutputFileName = Path.Combine(path, filename);
// Adds the format to the job. You can add additional formats as well such as
// Publishing streams or broadcasting from a port
job.PublishFormats.Add(fileOut);
}
//******************************END OF Stream PORTION****************************************
////////////////////////////////////////////////////////////////////////////////////////////////////
//*************************************** Process Files or Live Stream******************************
if (blnRecordFromFile)
{
job.ApplyPreset(LivePresets.VC1IISSmoothStreaming720pWidescreen);
job = new LiveJob();
// Verifies all information is entered
if (string.IsNullOrWhiteSpace(sourcePath) || string.IsNullOrWhiteSpace(destinationPath))
return false;
job.Status += new EventHandler<EncodeStatusEventArgs>(StreamStatus);
LiveFileSource fileSource;
try
{
// Sets file to active source and checks if it is valid
fileSource = job.AddFileSource(sourcePath);
}
catch (InvalidMediaFileException)
{
return false;
}
// Sets to loop media for streaming
// fileSource.PlaybackMode = FileSourcePlaybackMode.Loop;
// Makes this file the active source. Multiple files can be added
// and cued to move to each other at their ends
job.ActivateSource(fileSource);
}
//******************************END OF FILE PORTION****************************************
// Sets up variable for fomat data
switch (publishType)
{
case Output.Archive:
// Verifies destination path exists and if not creates it
try
{
if (!Directory.Exists(destinationPath))
Directory.CreateDirectory(destinationPath);
}
catch (IOException)
{
return false;
}
FileArchivePublishFormat archiveFormat = new FileArchivePublishFormat();
// Gets the location of the old extention and removes it
string filename = Path.GetFileNameWithoutExtension(sourcePath);
// Sets the archive path and file name
archiveFormat.OutputFileName = Path.Combine(destinationPath, filename + ".ismv");
job.PublishFormats.Add(archiveFormat);
break;
case Output.Publish:
// Setups streaming of media to publishing point
job = new LiveJob();
// Aquires audio and video devices
Collection<EncoderDevice> devices = EncoderDevices.FindDevices(EncoderDeviceType.Video);
EncoderDevice video = devices.Count > 0 ? devices[0] : null;
for (int i = 0; i < devices.Count; ++i)
// devices[i].Dispose();
devices.Clear();
devices = EncoderDevices.FindDevices(EncoderDeviceType.Audio);
EncoderDevice audio = devices.Count > 0 ? devices[0] : null;
for (int i = 1; i < devices.Count; ++i)
devices[i].Dispose();
devices.Clear();
// Checks for a/v devices
if (video != null && audio != null)
{
//job.ApplyPreset(Preset.FromFile(#"C:\Tempura\LivePreset3.xml"));
job.ApplyPreset(LivePresets.H264IISSmoothStreamingLowBandwidthStandard);
job.OutputFormat.VideoProfile.SmoothStreaming = true;
deviceSource = job.AddDeviceSource(video, audio);
// Make this source the active one
job.ActivateSource(deviceSource);
}
else
{
error = true;
}
PushBroadcastPublishFormat publishFormat = new PushBroadcastPublishFormat();
try
{
// checks the path for a valid publishing point
publishFormat.PublishingPoint = new Uri(destinationPath);
}
catch (UriFormatException)
{
return false;
}
// Adds the publishing format to the job
try
{
// job.ApplyPreset(LivePresets.VC1IISSmoothStreaming480pWidescreen);
job.PublishFormats.Add(publishFormat);
job.PreConnectPublishingPoint();
}
catch (Exception e)
{
MessageBox.Show(e.StackTrace.ToString());
}
break;
default:
return false;
}
job.StartEncoding();
return true;
}
Sadly I dont have enough rep to comment, so I have to write it as an answer.
Due to you are starting a live job, in order to stream you should not call job.StopEncoding() right after StartEncoding. I think usually you would use an event to stop the encoding. If you start encoding and immediately stop it, it is only logical you have no, or only a very small output.
I changed your code to the following and it seems work well. I guess your problem is that you disposed the instance of LiveJob class. You have to keep the instance alive before it finished encoding the whole stream. So change the using part and remove the StopEncoding and Dispose will be OK.
private void broadcastSourceFileToMediaServer2()
{
LiveJob job = new LiveJob();
String filetoencode = #"c:\temp\niceday.wmv";
LiveFileSource filesource = job.AddFileSource(filetoencode);
filesource.PlaybackMode = FileSourcePlaybackMode.Loop;
job.ActivateSource(filesource);
job.ApplyPreset(LivePresets.VC1Broadband4x3);
//don't know which one is good to use
job.AcquireCredentials += new EventHandler<AcquireCredentialsEventArgs>(job_AcquireCredentials);
_myUserName = "indes";
_pw = PullPW("indes");
Uri url = new Uri("http://192.168.1.74:8080/live");
PushBroadcastPublishFormat pubpoint = new PushBroadcastPublishFormat();
pubpoint.PublishingPoint = url;
pubpoint.UserName = _myUserName;
pubpoint.Password = _pw;
job.PublishFormats.Add(pubpoint);
job.PreConnectPublishingPoint();
job.StartEncoding();
statusBox.Text = job.NumberOfEncodedSamples.ToString();
}
public static string _myUserName { get; set; }
public static SecureString _pw { get; set; }
//codificação de Password a enviar
private static SecureString PullPW(string pw)
{
SecureString s = new SecureString();
foreach (char c in pw) s.AppendChar(c);
return s;
}
static void job_AcquireCredentials(object sender, AcquireCredentialsEventArgs e)
{
e.UserName = _myUserName;
e.Password = _pw;
e.Modes = AcquireCredentialModes.None;
}

Categories