I am attempting to initialize and push an initial commit to GitLab repository using LibGit2Sharp.
if (!Directory.Exists("D:\\GitRepos\\" + repositoryName))
{
Directory.CreateDirectory("D:\\GitRepos\\" + repositoryName);
File.Create("D:\\GitRepos\\" + repositoryName + "\\README.md").Close();
}
Repository.Init("D:\\GitRepos\\" + repositoryName);
using (var repo = new Repository("D:\\GitRepos\\" + repositoryName))
{
repo.Index.Add("README.md");
Signature author = new Signature("user", "user#user.com", DateTime.Now);
Signature committer = author;
repo.Commit("Initial Commit", author, committer);
repo.Network.Remotes.Add("origin", validRepoHttpsUrl);
Remote remote = repo.Network.Remotes["origin"];
var options = new PushOptions
{
CredentialsProvider = (_url, _user, _cred) =>
new UsernamePasswordCredentials {Username = "validuser", Password = "validpassword"}
};
string pushRefSpec = #"refs/heads/master";
repo.Network.Push(remote, pushRefSpec, options);
}
}
The repository is created and initialized locally without issue. The README file is created and added to the repo index and commit succeeds. When I try to push the commit to the remote endpoint I receive an error stating :
"Request failed with status code: 411"
If I put a breakpoint right before the push and set the http.postBuffer for the repo with the following command:
git config http.postBuffer 524288000
I receive a new error when the push executes:
Failed to write chunk footer: The connection with the server was terminated abnormally
I was able to quickly stand up a bitbucket git repo and push to it without any issues, seems that this may be a problem with gitlab.
It looks like this is a known issue for libgit2sharp based on RobertN's comment. https://github.com/libgit2/libgit2sharp/issues/905
I was able to work around this temporarily by handling the push with a git CLI call.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.WorkingDirectory = "D:\\GitRepos\\" + repositoryName;
p.StartInfo.FileName = "git.exe";
p.StartInfo.Arguments = "push -u origin master";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Something to note is that when this is being run as a windows service as local system the call takes 2-3 minutes for a small commit to push. When i switched the service to run as a domain user it is immediate. Also, this only works because I have ssh and proper keys setup on my host, otherwise git would prompt for a username and password. I had to use the SSH URL instead of HTTP as stated in the original question.
Related
Plan
The plan is to disable and subsequently enable a device from inside a windows forms application. To test the first building block of my plan, I open cmd with admin privileges and the following works perfectly:
> devcon hwids =ports
> devcon hwids *VID_10C4*
> devcon disable *VID_10C4*
> devcon enable *VID_10C4*
I can see the device being disabled and enabled again in device manager.
I can also achieve all of this by putting the commands into a batch file and running it from cmd with admin privileges. The above tells me that my plan is essentially good.
Application
However, what I actually want to do is achieve the same thing from inside a windows forms application:
I've set the following in the app manifest:
requestedExecutionLevel level="requireAdministrator" uiAccess="false"
For the sake of baby steps, I have checked this, just to ensure that there are no stupid mistakes in paths and whatnot. And it works just fine. The log file shows me the expected output from the dir command.
// Build String
string strCmdText =
"'/c cd " + prodPath +
" && dir " +
" > logs\\logFileEnablePrt.txt \"'";
// Run command
var p = new System.Diagnostics.Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
However, this does not work. It always returns an empty log file and does not change the device as expected:
// Build String
string strCmdText =
"'/c cd " + prodPath +
" && devcon hwids =ports " +
" > logs\\logFileEnablePrt.txt \"'";
// Run command
var p = new System.Diagnostics.Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
Error from cmd window is :
'devcon' is not recognized as an internal or external command,
operable program or batch file.
What's going on?
The above has me stumped. I've proved the commands work. I've proved my C# code works. But when I join the 2 together, it doesn't work...
NB: My C# program is running on my D: drive, if that makes any difference...
Updates Based on Comments
#Compo
Using your code, it does exactly the same as with mine. I see an empty log file & no changes made to the device. I've altered the /c to /k so I can see what going on the cmd terminal and I see this:
I've even tried your code C:\\Windows\\System32\\devcon hwids =usb pointing directly at devcon. Also tried \devcon.exe for completeness. The inexplicable error is :
I can see the flipping devcon.exe file sitting right there in the folder! Is there any reason it would not recognise it?
Also, with the command as you wrote it, the log file name is actually named logFileEnablePrt.txt'. I agree that your command looks right, so don't ask me why this happens!
#Panagiotis Kanavos
using your code, I get the following error:
This is at the line p.Start();. I tried putting in devcon.exe, and even the whole path (I checked the folder was in my PATH, and it is). Can't get past this. I actually stumbled on that answer you shared and arrived at this brick wall already.
Here is the code works for me, I don't have ports devices so I change it to usb.
public static void Main()
{
string prodPath = #"c:\devcon\x64";
// Build String
string strCmdText =
"/c \"cd /d " + prodPath +
" && devcon hwids =usb " +
" > log.txt \"";
// Run command
var p = new Process();
var psi = new ProcessStartInfo("CMD.exe", strCmdText);
psi.Verb = "runas"; // admin rights
p.StartInfo = psi;
p.Start();
p.WaitForExit();
}
Worked through a few steps and think I may have an answer...
Just specifying devcon fails as expected...windows cant find the exe as the folder it is in is not in the %PATH% variable in windows..
IF I specify the full path however it works...
It wasnt clear from your original code but if your copy of devcon is sitting in either System32 or Syswow directories you may be hitting an emulation issue as well...see here....
EDIT1:: A way to prove this would be to do Direcory.GetFiles(directory containing devcon) and see if the results line up with what you expect
As for passing arguments through to devcon I'd try something like this as opposed to trying to concatenate one giant cmd line..
A similar example but with netstat:
EDIT 2::Another example but with devcon:
The target platform here for the build was x64
EDIT3::
With my application build set to x86:
After working through the answers and comments above, I seem to have something that reliably works, which obviously I'd like to share back for scrutiny and future use.
So, my function ended up looking like this:
private int enablePort(string action)
{
while (true)
{
// Command Arg
string devconPath = #"c:\Windows\SysNative";
string strCmdText =
"'/c \"cd /d \"" +
devconPath +
"\" && c:\\Windows\\SysNative\\devcon " + action + " *VID_10C4* " +
"> \"" + prodPath + "\\logs\\logFileEnablePrt.txt\"\"";
// Process
var p = new Process();
var psi = new ProcessStartInfo()
{
Arguments = strCmdText,
Verb = "runas",
FileName = "CMD.exe",
UseShellExecute = true
};
p.StartInfo = psi;
p.Start();
p.WaitForExit();
// Grab log output
string logPath = prodPath + "\\logs\\logFileEnablePrt.txt";
Console.WriteLine("logPath = " + logPath);
string tempFile = System.IO.File.ReadAllText(logPath);
System.Console.WriteLine("Contents of WriteText.txt = \n{0}", tempFile);
// Check if it worked
var success = false;
if (tempFile.Contains(action))
{
success = true;
return 0;
}
// Error -> Allow user to try again!
if (MessageBox.Show("Was unable to " + action + " Test Jig COM port. Unlug & Replug USB. Check COM port is enabled if not working.", "COM Port Problem", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
{
return -1;
}
}
}
And the calling code was:
this.enablePort("disable");
int milliseconds = 3000;
await Task.Delay(milliseconds);
this.enablePort("enable");
As you can see in the code above, I've logged everything to see what was going on... Stepping through with the debugger, I can now see after the disable:
USB\VID_10C4&PID_EA60\0001 : Disabled
1 device(s) disabled.
And then after the enable:
USB\VID_10C4&PID_EA60\0001 : Enabled
1 device(s) are enabled.
The one extra thing I need to stress is that during testing, I thought I could hook a serial peripheral onto the port and determine whether it could disable and enable successfully by checking the connection. THIS DOES NOT WORK. The above code only works when the port is idle. Perhaps someone who understands the underlying software could hazard an explanation of why this is.
I want to track a project that uses git in my winforms project. I don't want to clone the full repository and the full history, I just want the latest version, and I want to be able to update to new revisions from the remote project.
I have tried this
co.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = userName, Password = passWord };
Repository.Clone("Git/repo", #tmpRepoFolder, co);
, but this creates a copy of the entire repository (huge file size), and tracking changes makes the disk space even bigger (100mb of files now takes up over 2gb).
I don't need the history and i don't need the tags. I just want the latest version .
Basically you want a shallow clone (the equivalent of the git clone --depth command) which is not actually supported, there is an open issue for that
As an alternative you can launch a Process which do what you want using the git application.
Here an example:
using(System.Diagnostics.Process p = new Process())
{
p.StartInfo = new ProcessStartInfo()
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
FileName = #"C:\Program Files\Git\bin\git.exe",
Arguments = "clone http://username:password#path/to/repo.git" + " --depth 1"
};
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
I need to execute this command on our remote Skype server:
SEFAUtil.exe /server:lyncserver.domain1.co.uk sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10
which adds a colleague to my team call group.
I am able to run the command on the server itself, and the code below works when sending other commands to that server:
var processToRun = new[] { process };
var connection = new ConnectionOptions();
var wmiScope = new ManagementScope(String.Format("\\\\{0}\\root\\cimv2", LyncServer), connection);
var wmiProcess = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
var reason = wmiProcess.InvokeMethod("Create", processToRun);
However, when process is the string:
"cmd /c cd /d C:\\Program Files\\Microsoft Lync Server 2013\\ResKit && SEFAUtil.exe /server:lyncserver.domain1.co.uk sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10"
Then the user is not added to the team call group.
I can see that reason contains the uint 0, which usually indicates success - but the actual command is clearly failing.
I also tried adding > C:\users\user.name\desktop\output.txt and 2> C:\users\user.name\desktop\output.txt to the end of the command, but they just created empty text files, so not very useful!
Update
I tried changing the command to the following:
const string LyncServer = "server.domain1.co.uk";
const string ResKitPath = #"C:\Program Files\Microsoft Lync Server 2013\ResKit";
var command = "SEFAUtil.exe /server:{LyncServer} sip:MySelf#domain.com /addteammember:sip:OtherUser#domain.com /delayringteam:10";
var process = $"cmd /c cd /d \"{ResKitPath}\" && {command}";
So that the path containing spaces is double-quoted and the slashes are not being escaped, but with the same results.
Does anyone know of another way of debugging this or retrieving the output for the newly created process?
I've had a similar issue, mine was that the command shell needed to run elevated. SEFA is a bit naff at giving good error messages, and fails silently.
I'm trying to copy containers in Azure from one storage location to another. I'm using the AzCopy command for this. First I get a list of all the containers and then run AzCopy based on the container name from the command line, using c# code.
The problem that I was running into is that it does copy the containers from one location to another but after 4 containers, it seems to get stuck. And the test keeps running forever. When I cancel the test I see all the other containers get copied as well.
I was wondering how can I solve this issue of having the test be complete and all the folders get copied over. I tried to wait after each call to make sure there is enough time for the call to complete. Also tried using cmd.WaitForExit(); after each call but that just gets stuck.
Any suggestions on what I could be missing, one thing I wanted to do was get the output after each call, because right now it only outputs the result once all the commands are finished. Also was thinking of how to run the command lines call sequentially so run only after the first has finished.
Any help would be appreciated!
namespace Test2
{
[TestFixture]
class ContainerList
{
[Test]
public void CopyingContainerData()
{
CloudStorageAccount sourceCloudStorageAccount =
CloudStorageAccount.Parse("StorageAccountKey");
CloudBlobClient sourceCloudBlobClient = sourceCloudStorageAccount.CreateCloudBlobClient();
List<string> outputLines = new List<string>();
IEnumerable<CloudBlobContainer> containers = sourceCloudBlobClient.ListContainers();
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = false;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();
int i = 0;
foreach (CloudBlobContainer oneContainer in containers)
{
string outputLine = oneContainer.Name;
outputLines.Add(outputLine);
string container = oneContainer.Name;
string strCmdText = #"AzCopy /Source:https://location1.blob.core.windows.net/" + container + #" /Dest:https://location2.blob.core.windows.net/" + container + #" /SourceKey:abc /DestKey:abc123 /S /NC:8 /XO /Y";
string location = #"cd C:\Program Files (x86)\Microsoft SDKs\Azure\AzCopy";
cmd.StandardInput.WriteLine(location);
cmd.StandardInput.WriteLine(strCmdText);
//System.Threading.Thread.Sleep(20000);
//cmd.WaitForExit();
i++;
if (i == 15)
{
break;
}
}
string[] outputText = outputLines.ToArray();
File.WriteAllLines(#"C:\AzureTests\CopyData.txt", outputText);
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());
}
}
}
I suggest you use powershell to do this:
$SourceStorageAccount = "sourceStorageAccount"
$SourceStorageKey = "sourceKey"
$DestStorageAccount = "destStorageAccount"
$DestStorageKey = "destKey"
$SourceStorageContext = New-AzureStorageContext –StorageAccountName $SourceStorageAccount -StorageAccountKey $SourceStorageKey
$DestStorageContext = New-AzureStorageContext –StorageAccountName $DestStorageAccount -StorageAccountKey $DestStorageKey
$containers = Get-AzureStorageContainer -Context $SourceStorageContext
foreach($container in $containers) {
New-AzureStorageContainer -Context $DestStorageContext -Name $container.name -Permission Off
$Blobs = Get-AzureStorageBlob -Context $SourceStorageContext -Container $container.name
#Do the copy of everything
foreach ($Blob in $Blobs) {
Write-Output "Moving $Blob.Name"
Start-CopyAzureStorageBlob -Context $SourceStorageContext -SrcContainer $container.name -SrcBlob $Blob.Name `
-DestContext $DestStorageContext -DestContainer $container.name -DestBlob $Blob.Name
}
}
We had similar scenario of AzCopy.exe invocation not returning control to .Net. The reason was parallel execution of AzCopy.exe without specifying the journal files. It share the journal files by default and gets access violation. When we issued different journal files to different instances of AzCopy it stared working.
Running multiple instances of AzCopy.exe from .Net
If I run this from my command prompt it works fine.
psexec \ServerName cscript.exe iisapp.vbs /a AppName /r
I'm trying to do the same thing with C# console app. I'm using the below code but most of the time the application hangs and doesn't complete, and the few times it does it throws an error code. Am I doing this wrong? Does anyone know where I can look up the error or error code?
static void RecycleAppPool(string sServer)
{
Console.Clear();
ProcessStartInfo p = new ProcessStartInfo("psexec.exe", "\\\\" + sServer + " cscript.exe iisapp.vbs /a <AppName> /r");
p.RedirectStandardInput = true;
p.UseShellExecute = false;
Process.Start(p);
}
When it completes with an error, looks like this
"cscript.exe exited with error code -2147024664"
EDIT
Below code working well
static void RecycleAppPool(string sServer)
{
Console.Clear();
ProcessStartInfo p = new ProcessStartInfo("psexec.exe");
p.Arguments = #"\\" + sServer + #" cscript.exe iisapp.vbs /a AppName /r";
p.UseShellExecute = false;
Process.Start(p);
}
VS2003/8/10: Tools->Error Lookup. Paste in the error code in hex. 800700E8. It's "The pipe is being closed." Not very helpful - some issue with redirection i guess.
Do you really have in the ProcessStartInfo parameter, or is that being used to replace what your actual app name is?
Have you tried recycling using appcmd instead of iisapp.vbs?
And, in this thread they recycled a remote application pool using WMI.
If it's IIS7 then you can you the web admin namespace from C#:
using System;
using System.Xml.Serialization;
using Microsoft.Web.Administration;
using System.Linq;
using System.Runtime.InteropServices;
///...
var serverManager = ServerManager.OpenRemote(#"\\myiisserver");
var appPool = serverManager.ApplicationPools["my app pool name"];
appPool.Recycle();
You can learn more about the Web Admin Namespace here. So far it has worked very well for us. BUT must be installed on the client and remote machines.
I struggled with this a lot for the last 2 days trying every solution I found online. I'm trying to recycle an application pool on remote machines on a different domain. The first method I tried with PsExec returned error 3. I tried DirectoryEntry and failed on permissions as well and then tried using ServerManager but the same issue.
Finally, I moved to WMI and it worked:
public static void RecycleIis4(string user, string password, string serverName = "LOCALHOST", string appPoolName = "DefaultAppPool")
{
var processToRun = new[] { #"c:\Windows\system32\inetsrv\appcmd recycle APPPOOL " + appPoolName };
var connection = new ConnectionOptions { Username = user, Password = password };
var wmiScope = new ManagementScope(string.Format(#"\\{0}\root\cimv2", serverName), connection);
var wmiProcess = new ManagementClass(wmiScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
wmiProcess.InvokeMethod("Create", processToRun);
}
Hope this helps.