如何从ASP.NET执行SVN更新?

时间:2022-10-30 09:23:11

I'd like to call svn up from an asp.net page so people can hit the page to update a repository. (BTW: I'm using Beanstalk.com svn hosting which doesn't allow post-commit hooks, which is why I am doing it this way).

我想从asp.net页面调用svn,以便人们可以点击页面来更新存储库。 (顺便说一句:我正在使用Beanstalk.com svn托管,它不允许提交后挂钩,这就是我这样做的原因)。

See what I've got below. The process starts (it shows up in Processes in Task Manager) and exits after several seconds with no output message (at least none is outputted to the page). The repository does not get updated. But it does do something with the repository because the next time I try to manually update it from the command line it says the repo is locked. I have to run svn cleanup to get it to update.

看看我在下面得到了什么。该过程开始(它显示在任务管理器中的进程中)并在几秒钟后退出,没有输出消息(至少没有输出到页面)。存储库不会更新。但它确实对存储库做了一些事情,因为下次我尝试从命令行手动更新它时,它说repo被锁定了。我必须运行svn cleanup才能让它更新。

Ideas?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
    startInfo = New System.Diagnostics.ProcessStartInfo("svn")
    startInfo.RedirectStandardOutput = True     
    startInfo.UseShellExecute = False
    startInfo.Arguments = "up " & Request.QueryString("path")

    pStart.StartInfo = startInfo
    pStart.Start()
    pStart.WaitForExit()

    Response.Write(pStart.StandardOutput.ReadToEnd())
End Sub

4 个解决方案

#1


2  

You can also use the Subversion library that comes with Ankh SVN. I used it in a project to manage files in a Subversion repository and it worked well.

您还可以使用Ankh SVN附带的Subversion库。我在一个项目中使用它来管理Subversion存储库中的文件,它运行良好。

If you insist on using the command line client make sure you check the StandardError output for any error messages. Also make sure the user you run the process as has the appropriate rights.

如果您坚持使用命令行客户端,请确保检查StandardError输出是否有任何错误消息。还要确保您运行该进程的用户具有适当的权限。

#2


1  

You might be able to do this more effectively by using a .net SVN wrapper or library like this one. I'm sure there are others out there that would support the limitations of beanstalk as well.

您可以通过使用像这样的.net SVN包装器或库来更有效地执行此操作。我相信还有其他人会支持beanstalk的限制。

#3


0  

Using SharpSvn:

using(SvnClient client = new SvnClient())
{
   client.Update(Request["path"]);
}

But I would recommend not to use a user passed variable directly for security reasons.

但出于安全考虑,我建议不要直接使用用户传递的变量。

#4


0  

I have investigated this in detail. A loooong way to do it is to use Windows Messaging Subsystem (windows event log - you create your own log and write messages to it). Asp.Net creates a message. Then you need to write a windows service which reads the messages every 3 seconds or so. The moment it comes across an 'update svn please message', you run your cmd.exe /c svn.exe blah blah from your freshly created windows service...it works very well, buts its a lot of work...Then there is SharpSVN lib, but it requires a bit of setup and you can run into problems. Finally, most people seem to be trying to use ProcessStartInfo class, but few seem to get it right...Yes, its not easy and a long way around but here's the code......Here's code that will run svn.exe for you and log all the screen output to output buffer....

我已经详细研究了这一点。一个很好的方法是使用Windows Messaging Subsystem(Windows事件日志 - 您创建自己的日志并向其写入消息)。 Asp.Net创建了一条消息。然后你需要编写一个Windows服务,每隔3秒左右读取一次消息。它遇到'更新svn请消息'的那一刻,你从你刚刚创建的Windows服务中运行你的cmd.exe / c svn.exe等等......它工作得非常好,但它的工作很多......然后有SharpSVN lib,但它需要一些设置,你可能会遇到问题。最后,大多数人似乎都在尝试使用ProcessStartInfo类,但很少有人能够正确使用它...是的,它并不容易,而且还有很长的路要走,但这里是代码......这里的代码将运行svn。 exe为你并将所有屏幕输出记录到输出缓冲区....

    private static int lineCount = 0;
    private static StringBuilder outputBuffer = new StringBuilder();
    private void SvnOutputHandler(object sendingProcess,
                                  DataReceivedEventArgs e)
    {
        Process p = sendingProcess as Process;

        // Save the output lines here
        // Prepend line numbers to each line of the output.
        if (!String.IsNullOrEmpty(e.Data))
        {
            lineCount++;
            outputBuffer.Append("\n[" + lineCount + "]: " + e.Data);
        }
    }

    private void RunSVNCommand()
    {
        ProcessStartInfo psi = new ProcessStartInfo("cmd.exe",
                                                    string.Format("/c svn.exe --config-dir=%APPDATA%\\Subversion --username=yrname --password=yrpassword --trust-server-cert --non-interactive   update d:\\inetpub\\wwwroot\\yourpath"));

        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;

        // Redirect the standard output of the sort command.  
        // This stream is read asynchronously using an event handler.
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        Process p = new Process();

        // Set our event handler to asynchronously read the sort output.
        p.OutputDataReceived += SvnOutputHandler;
        p.ErrorDataReceived += SvnOutputHandler;
        p.StartInfo = psi;

        p.Start();

        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        p.WaitForExit();
    }

Quick explanation on svn.exe arguments and why we do it...You need to specify config-dir to whatever account has checked out the svn dir. IIS runs under a different account. If it can't find the config file for svn, you will get a stop message. --Non-interactive and --trust-server-certificate is to basically skip the prompt to accept the security challenges. Finally, you will need to specify username and password as this for some reason does not get sent (with my version of svn.exe anyway). Now, on top of this, connecting via https to the svn server was giving me errors as the hostname reported by IIS is different to a desktop hostname (ssl cert mismatch), hence it does not like the hostname in the config file - go figure. So, I figured, that if I reverse proxy from http to https (so now I have two websites on one server, with one being reversesvn.domain.com:80 proxing to svn.domain.com:8443) This will skip on all the certificate issues and that was the final piece of the puzzle. Here's how to do it - simple : https://blog.ligos.net/2016-11-14/Reverse-Proxy-With-IIS-And-Lets-Encrypt.html.

关于svn.exe参数的快速解释以及我们为什么这样做...您需要为任何已签出svn目录的帐户指定config-dir。 IIS在不同的帐户下运行。如果找不到svn的配置文件,您将收到一条停止消息。 - 非交互式和--trust-server-certificate基本上是跳过接受安全挑战的提示。最后,您需要指定用户名和密码,因为某些原因不会发送(无论如何我的svn.exe版本)。现在,除此之外,通过https连接到svn服务器给我的错误,因为IIS报告的主机名与桌面主机名(ssl证书不匹配)不同,因此它不喜欢配置文件中的主机名 - 去图。所以,我想,如果我将代理从http转换为https(所以现在我在一台服务器上有两个网站,其中一个是reverseesvn.domain.com:80,代理svn.domain.com:8443)这将跳过所有证书问题,这是拼图的最后一块。以下是如何操作 - 简单:https://blog.ligos.net/2016-11-14/Reverse-Proxy-With-IIS-And-Lets-Encrypt.html。

#1


2  

You can also use the Subversion library that comes with Ankh SVN. I used it in a project to manage files in a Subversion repository and it worked well.

您还可以使用Ankh SVN附带的Subversion库。我在一个项目中使用它来管理Subversion存储库中的文件,它运行良好。

If you insist on using the command line client make sure you check the StandardError output for any error messages. Also make sure the user you run the process as has the appropriate rights.

如果您坚持使用命令行客户端,请确保检查StandardError输出是否有任何错误消息。还要确保您运行该进程的用户具有适当的权限。

#2


1  

You might be able to do this more effectively by using a .net SVN wrapper or library like this one. I'm sure there are others out there that would support the limitations of beanstalk as well.

您可以通过使用像这样的.net SVN包装器或库来更有效地执行此操作。我相信还有其他人会支持beanstalk的限制。

#3


0  

Using SharpSvn:

using(SvnClient client = new SvnClient())
{
   client.Update(Request["path"]);
}

But I would recommend not to use a user passed variable directly for security reasons.

但出于安全考虑,我建议不要直接使用用户传递的变量。

#4


0  

I have investigated this in detail. A loooong way to do it is to use Windows Messaging Subsystem (windows event log - you create your own log and write messages to it). Asp.Net creates a message. Then you need to write a windows service which reads the messages every 3 seconds or so. The moment it comes across an 'update svn please message', you run your cmd.exe /c svn.exe blah blah from your freshly created windows service...it works very well, buts its a lot of work...Then there is SharpSVN lib, but it requires a bit of setup and you can run into problems. Finally, most people seem to be trying to use ProcessStartInfo class, but few seem to get it right...Yes, its not easy and a long way around but here's the code......Here's code that will run svn.exe for you and log all the screen output to output buffer....

我已经详细研究了这一点。一个很好的方法是使用Windows Messaging Subsystem(Windows事件日志 - 您创建自己的日志并向其写入消息)。 Asp.Net创建了一条消息。然后你需要编写一个Windows服务,每隔3秒左右读取一次消息。它遇到'更新svn请消息'的那一刻,你从你刚刚创建的Windows服务中运行你的cmd.exe / c svn.exe等等......它工作得非常好,但它的工作很多......然后有SharpSVN lib,但它需要一些设置,你可能会遇到问题。最后,大多数人似乎都在尝试使用ProcessStartInfo类,但很少有人能够正确使用它...是的,它并不容易,而且还有很长的路要走,但这里是代码......这里的代码将运行svn。 exe为你并将所有屏幕输出记录到输出缓冲区....

    private static int lineCount = 0;
    private static StringBuilder outputBuffer = new StringBuilder();
    private void SvnOutputHandler(object sendingProcess,
                                  DataReceivedEventArgs e)
    {
        Process p = sendingProcess as Process;

        // Save the output lines here
        // Prepend line numbers to each line of the output.
        if (!String.IsNullOrEmpty(e.Data))
        {
            lineCount++;
            outputBuffer.Append("\n[" + lineCount + "]: " + e.Data);
        }
    }

    private void RunSVNCommand()
    {
        ProcessStartInfo psi = new ProcessStartInfo("cmd.exe",
                                                    string.Format("/c svn.exe --config-dir=%APPDATA%\\Subversion --username=yrname --password=yrpassword --trust-server-cert --non-interactive   update d:\\inetpub\\wwwroot\\yourpath"));

        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;

        // Redirect the standard output of the sort command.  
        // This stream is read asynchronously using an event handler.
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        Process p = new Process();

        // Set our event handler to asynchronously read the sort output.
        p.OutputDataReceived += SvnOutputHandler;
        p.ErrorDataReceived += SvnOutputHandler;
        p.StartInfo = psi;

        p.Start();

        p.BeginOutputReadLine();
        p.BeginErrorReadLine();

        p.WaitForExit();
    }

Quick explanation on svn.exe arguments and why we do it...You need to specify config-dir to whatever account has checked out the svn dir. IIS runs under a different account. If it can't find the config file for svn, you will get a stop message. --Non-interactive and --trust-server-certificate is to basically skip the prompt to accept the security challenges. Finally, you will need to specify username and password as this for some reason does not get sent (with my version of svn.exe anyway). Now, on top of this, connecting via https to the svn server was giving me errors as the hostname reported by IIS is different to a desktop hostname (ssl cert mismatch), hence it does not like the hostname in the config file - go figure. So, I figured, that if I reverse proxy from http to https (so now I have two websites on one server, with one being reversesvn.domain.com:80 proxing to svn.domain.com:8443) This will skip on all the certificate issues and that was the final piece of the puzzle. Here's how to do it - simple : https://blog.ligos.net/2016-11-14/Reverse-Proxy-With-IIS-And-Lets-Encrypt.html.

关于svn.exe参数的快速解释以及我们为什么这样做...您需要为任何已签出svn目录的帐户指定config-dir。 IIS在不同的帐户下运行。如果找不到svn的配置文件,您将收到一条停止消息。 - 非交互式和--trust-server-certificate基本上是跳过接受安全挑战的提示。最后,您需要指定用户名和密码,因为某些原因不会发送(无论如何我的svn.exe版本)。现在,除此之外,通过https连接到svn服务器给我的错误,因为IIS报告的主机名与桌面主机名(ssl证书不匹配)不同,因此它不喜欢配置文件中的主机名 - 去图。所以,我想,如果我将代理从http转换为https(所以现在我在一台服务器上有两个网站,其中一个是reverseesvn.domain.com:80,代理svn.domain.com:8443)这将跳过所有证书问题,这是拼图的最后一块。以下是如何操作 - 简单:https://blog.ligos.net/2016-11-14/Reverse-Proxy-With-IIS-And-Lets-Encrypt.html。