`Merge remote-tracking branch 'Microsoft/master' into Socket

# Conflicts:
#	.gitmodules
#	src/Common/Core/Impl/Disposables/CountdownDisposable.cs
#	src/Common/Core/Impl/Extensions/StringExtensions.cs
#	src/Common/Core/Impl/Microsoft.R.Common.Core.csproj
#	src/Common/Core/Impl/Security/ISecurityService.cs
#	src/Common/Core/Test/Fixtures/ServiceManagerFixture.cs
#	src/Common/Core/Test/Microsoft.Common.Core.Test.csproj
#	src/Common/Core/Test/Stubs/Shell/SecurityServiceStub.cs
#	src/Common/Core/Test/Utility/TestFiles.cs
#	src/Common/Wpf/Impl/Microsoft.Common.Wpf.csproj
#	src/Containers/Impl/Microsoft.R.Containers.csproj
#	src/Debugger/Impl/project.json
#	src/EditorTestApp/project.json
#	src/Host/Broker/Impl/Microsoft.R.Host.Broker.csproj
#	src/Host/Broker/Impl/Resources.resx
#	src/Host/Broker/Impl/Security/TlsConfiguration.cs
#	src/Host/Client/Impl/Host/BrokerClient.cs
#	src/Host/Client/Impl/Host/LocalBrokerClient.cs
#	src/Linux/Containers/Impl/Microsoft.R.Containers.Linux.csproj
#	src/Linux/Host/Broker/Impl/Microsoft.R.Host.Broker.Linux.csproj
#	src/Linux/UnitTests/Core/Impl/Microsoft.UnitTests.Core.Linux.csproj
#	src/Mocks/Editor/project.json
#	src/Mocks/VisualStudio/project.json
#	src/Package/Impl/Shell/VsAppShell.Services.cs
#	src/Package/Impl/project.json
#	src/Package/Impl/source.extension.vsixmanifest
#	src/Package/Test/Properties/AssemblyInfo.cs
#	src/Package/Test/Shell/VsAppShellTestSetup.cs
#	src/Package/Test/project.json
#	src/Package/TestApp/Microsoft.VisualStudio.R.Interactive.Test.csproj
#	src/Package/TestApp/Properties/AssemblyInfo.cs
#	src/Package/TestApp/project.json
#	src/ProjectSystem/Impl/Microsoft.VisualStudio.ProjectSystem.FileSystemMirroring.csproj
#	src/ProjectSystem/Impl/project.json
#	src/ProjectSystem/Test/Microsoft.VisualStudio.ProjectSystem.FileSystemMirroring.Test.csproj
#	src/ProjectSystem/Test/Properties/AssemblyInfo.cs
#	src/ProjectSystem/Test/project.json
#	src/R.Build.Version.targets
#	src/R.Settings.props
#	src/R.sln
#	src/R/Components/Impl/Microsoft.R.Components.csproj
#	src/R/Editor/Impl/Functions/PackageIndex.cs
#	src/R/Sql/Impl/project.json
#	src/UnitTests/Core/Impl/Microsoft.UnitTests.Core.csproj
#	src/UnitTests/Core/Impl/XUnit/AssemblyLoaderAttribute.cs
#	src/UnitTests/Core/Impl/XUnit/AssemblyRunner.cs
#	src/UnitTests/Core/Impl/XUnit/Categories.cs
#	src/UnitTests/Core/Impl/XUnit/CompositeTestDiscoverer.cs
#	src/UnitTests/Core/Impl/XUnit/TestMethodRunner.cs
#	src/Unix/Host/Broker/Impl/Services/UnixRHostProcessService.cs
#	src/Windows/Containers/Test/WindowsContainerServiceTest.cs
#	src/Windows/Editor/Impl/project.json
#	src/Windows/Editor/Test/project.json
#	src/Windows/Host/Broker/Impl/Startup/Program.cs
#	src/Windows/Host/Broker/Impl/project.json
#	src/Windows/Host/Client/Impl/Microsoft.R.Host.Client.Windows.csproj
#	src/Windows/Host/Client/Test/Fixtures/RemoteBrokerFixture.cs
#	src/Windows/Markdown/Editor/Impl/Microsoft.Markdown.Editor.Windows.csproj
#	src/Windows/Markdown/Editor/Impl/project.json
#	src/Windows/Markdown/Editor/Test/project.json
#	src/Windows/R/Components/Impl/ConnectionManager/Implementation/ViewModel/ConnectionManagerViewModel.cs
#	src/Windows/R/Components/Impl/Microsoft.R.Components.Windows.csproj
#	src/Windows/R/Components/Impl/Resources.resx
#	src/Windows/R/Components/Impl/Security/WindowsSecurityService.cs
#	src/Windows/R/Components/Impl/project.json
#	src/Windows/R/Components/Test/Fixtures/RComponentServicesFixture.cs
#	src/Windows/R/Components/Test/Microsoft.R.Components.Test.csproj
#	src/Windows/R/Components/Test/project.json
#	src/Windows/R/Editor/Application.Test/project.json
#	src/Windows/R/Editor/Impl/project.json
#	src/Windows/R/Editor/Test/Fixtures/REditorServicesFixture.cs
#	src/Windows/R/Editor/Test/QuickInfo/QuickInfoSourceTest.cs
#	src/Windows/R/Editor/Test/project.json
#	src/Windows/R/Platform.Core/Test/Fakes/Shell/TestCoreShell.cs
#	src/Windows/R/Platform.Core/Test/Fakes/Shell/TestTaskService.cs
This commit is contained in:
REDMOND\alsher 2017-11-10 16:33:28 -08:00
Родитель 52b64a0fbe 2014ddf982
Коммит b3f8ee72b5
370 изменённых файлов: 14294 добавлений и 4986 удалений

5
.gitignore поставляемый
Просмотреть файл

@ -106,3 +106,8 @@ TestFiles/
*.tmp_proj
*.ide
*.ide-journal
*.lock
/src/.vs/R/v15/sqlite3/storage.ide-wal
/src/.vs/R/v15/sqlite3/storage.ide-shm
/src/.vs/R/v15/Server/sqlite3/storage.ide-wal
/src/.vs/R/v15/Server/sqlite3/storage.ide-shm

Просмотреть файл

@ -12,12 +12,17 @@ If your contribution is large enough, you will be asked to sign the Microsoft CL
### Prerequisites
1. Visual Studio 2015 Update 1 or higher.
- You must have C++, Web Tools, and VS Extensibility components (VS SDK) installed.
1. R 3.2.2 or later; either one of:
1. Visual Studio 2017 [Preview](https://www.visualstudio.com/vs/preview/) or at least the latest available release.
You must install C++, .NET Desktop, .NET Core (currently 1.1) and VS Extensibility components (VS SDK).
**Release/1_0** *is the last branch buildable with Visual Studio 2015. Update 3 is required.*
2. MSYS2. See instructions at the [R-Host submodule](https://github.com/Microsoft/R-Host/blob/master/BUILDING-WIN32.md).
3. R 3.4.0 or later; either one of:
- [CRAN R](https://cran.r-project.org/bin/windows/);
- [Microsoft R Open](https://mran.revolutionanalytics.com/open/).
1. [Wix Tools 3.10](https://wix.codeplex.com/releases/view/617257) (only needed if you want to build the installer).
4. [Wix Tools 3.11](http://wixtoolset.org/releases/) (only needed if you want to build the remote services installer for Windows).
### Getting the source code
@ -30,35 +35,15 @@ git clone --recursive https://github.com/Microsoft/RTVS.git
The remaining dependencies are referenced as NuGet packages, and will be automatically downloaded by VS during the build.
### First build and switching between Visual Studio versions
RTVS can be built for *Visual Studio 2015* aka *VS14* and *Visual Studio 15 Preview* aka *VS15*.
Accordingly, to build for the former, R.sln must be opened in VS14, and to build the latter, it has to be opened in VS15.
Some of the nuget dependencies for VS14 and VS15 are incompatible:
| Nuget package | VS14 | VS15 | Dependent projects
| ------------------------------------ |---------------:| ------------------------:| ------------------
| Microsoft.VSSDK.BuildTools | 14.2.25201 | 15.0.25201-Dev15Preview2 | <ul><li>Microsoft.VisualStudio.R.Package</li></ul>
| Microsoft.VisualStudio.ProjectSystem | 14.0.50617-pre | 15.0.183-pre | <ul><li>Microsoft.VisualStudio.ProjectSystem.FileSystemMirroring</li><li>Microsoft.VisualStudio.ProjectSystem.FileSystemMirroring.Test</li><li>Microsoft.VisualStudio.R.Package</li><li>Microsoft.VisualStudio.R.Package.Test</li><li>Microsoft.VisualStudio.Shell.Mocks</li></ul>
Because of that, `project.json` in the dependent projects has to be updated before they can be built. This can be done:
- By running `msbuild src/build.proj /t:ResetNuget` from the root folder in *Developer Command Prompt for VS2015* for *VS14* or in *Developer Command Prompt for VS15* for *VS15*. Executing `msbuild build.proj /t:Reset` will also erase `bin` and `obj` folders.
- By rebuilding solution several times.
- During first run, `project.json` will be replaced by either `project.14.0.json` or `project.15.0.json` in projects that require replacement.
- During second run, nuget will update its `project.lock.json` files and related `*.nuget.props` and `*.nuget.targets` files
- During third run, projects will be built
- Manually by replacing `project.json` content and deleting all `project.lock.json`, `*.nuget.props` and `*.nuget.targets` files
This step is required before first build and every time R.sln is opened in the different version of Visual Studio.
### Building and running the product
1. Open `R.sln` solution file in Visual Studio 2015 or Visual Studio 15 Preview.
1. Open `R.sln` solution file in Visual Studio 2017.
1. Set `Microsoft.VisualStudio.R.Package` as a startup project.
1. If you are not planning to build the installer MSI (see next section), you can also unload `Setup`, `SetupRHost` and `SetupCustomActions` projects.
1. If you are not planning to build the installer MSI (see next section), you can also unload `SetupRemote` and `SetupRHost` projects.
1. Build the solution. Note that this will _not_ build `Setup` by default.
1. Start Debugging (F5).
1. VS experimental instance should start, and you should see "R Tools" entry in the main menu.
### Building the installer
### Building the remote services installer
1. Build `Setup` project specifically (right-click on it in Solution Explorer and select "Build").
1. Look for the MSI that it generates under `bin`. Running it will install the product.

Просмотреть файл

@ -6,16 +6,16 @@ beware! This release is meant for evaluation purposes only, and not for producti
### Installation
Do you already have **VS2015 with Update 1** and a **64-bit R interpreter** installed?
Latests RTVS ships with Visual Studio 2017 as part of the Data Science workload.
You can either install release from https://www.visualstudio.com/downloads/ or
Preview from the https://www.visualstudio.com/vs/preview/. Preview channel has the latest RTVS.
If you do, then [just install RTVS](https://aka.ms/rtvs-current)!
Otherwise, please see the [VS, RTVS and R Installation guide](http://microsoft.github.io/RTVS-docs/installation.html).
You can still use older extension with VS 2015 Update 3 but it is no longer being updated.
You can install it from https://aka.ms/rtvs-current
### Documentation
The interim docs are available here:
* [RTVS Documentation](http://microsoft.github.io/RTVS-docs/)
### Bugs and feature requests
@ -26,6 +26,8 @@ made by using search, and if so, then upvote it by
to it. Feel free to comment on any existing issues and feature requests with any additional feedback, clarifications,
or questions.
You can also submit feedback via VS 2017 feedback tool.
When filing a bug, you can also use the **R Tools | Send Feedback | Send Frown** feature to send us the product
logs to help us diagnose the problem better. This command will launch your email client with a prepopulated message,
and will gather the logs and highlight them in Windows Explorer, so that they can be conveniently attached to the
@ -34,16 +36,10 @@ and the logs may contain private information.
If you need to reach the team directly, email us at rtvsuserfeedback@microsoft.com.
### Support and roadmap
### Roadmap
RTVS is created and fully supported by Microsoft (and the community!). Currently, support is via GitHub and email
only, but we hope to add more channels soon.
We are planning approximately monthly releases (with both bug fixes and features) as we march toward 1.0 RTM later
this calendar year.
If you'd like to see what features are likely to go in each milestone, you can filter the bug/feature list by that
milestone. If you have a key bug or feature that should be attended to, please thumbs up / comment on it.
If you install [ZenHub](https://github.com/marketplace/zenhub) extension for Chrome,
you should be able to see our milestones, releases and the overall progress.
### Builds and pull requests

Двоичные данные
doc/rtvsd/media/containers-window-create-fill.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичные данные
doc/rtvsd/media/containers-window-create-new.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.6 KiB

Двоичные данные
doc/rtvsd/media/containers-window-created.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Двоичные данные
doc/rtvsd/media/containers-window.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Двоичные данные
doc/rtvsd/media/remote-logon-window.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Двоичные данные
doc/rtvsd/media/workspaces-window-container-connected.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 26 KiB

Двоичные данные
doc/rtvsd/media/workspaces-window-containers.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.7 KiB

Двоичные данные
doc/rtvsd/media/workspaces-window-running-containers.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.4 KiB

Просмотреть файл

@ -0,0 +1,187 @@
# Remote R Service for Linux
Remote R Service for Linux is currently packaged as rtvs-daemon. The daemon is supported and tested on Ubuntu 16.04, 16.10 LTS desktop, server, and Windows Subsystem for Linux running Ubuntu.
## Setting up Remote R Service
### On physical Ubuntu machine
After starting up follow these steps:
1. Log on to the machine and download rtvs-daemon tarball:
```
wget -O rtvs-daemon.tar.gz https://aka.ms/r-remote-services-linux-binary-current
tar -xvzf rtvs-daemon.tar.gz
```
2. Run the install script:
```
sudo ./rtvs-install
```
3. Enable and start the service:
```
sudo systemctl enable rtvsd
```
4. [required for production] Configure SSL certificate:
By default, `rtvs-daemon` uses the `ssl-cert-snakeoil.pem` and `ssl-cert-snakeoil.pem` generated by `ssl-cert` package. During installation we combine them into `ssl-cert-snakeoil.pfx`. For production purposes use the SSL certificate provided by your admin. SSL certificate can be configured by providing a PFX file and optional import password, in: `/etc/rtvs/rtvsd.config.json`
5. [optional] Check service is running:
```
ps -A -f | grep rtvsd
```
If you dont see a process running under the user name `rtvssvc`. Start it using the following command:
```
sudo systemctl start rtvsd
```
### On Ubuntu Server VM on Azure
You will need Putty for Windows, or other SSH client.
1. Log into https://portal.azure.com
2. Go to Virtual Machines and click on Add.
3. This should bring up available VM images. Search for `Ubuntu Server 16.04 LTS`
4. Select it and set the deployment model as `Resource manager` and hit create.
5. Choose a name for the VM, type in username and password (password is required, we dont support SSH public key login). Make changes as needed to the VM configuration.
6. In the next tab choose a VM size. Verify the configuration and hit create. It will take a while to build the VM.
7. Once it is done, in the Networking tab for the VM add `5444` as an allowed inbound port. If you want to use a different port, you can configure that in config file for rtvs daemon which can be found here: `/etc/rtvs/rtvsd.config.json`.
8. [optional] Set a DNS name, you can also use the IP address.
9. Connect to the VM using SSH client, and download the rtvs daemon tarball.
```
wget -O rtvs-daemon.tar.gz https://aka.ms/r-remote-services-linux-binary-current
tar -xvzf rtvs-daemon.tar.gz
```
10. Run the install script:
```
sudo ./rtvs-install
```
11. Enable and start the service:
```
sudo systemctl enable rtvsd
```
12. [required for production] Configure SSL certificate:
By default, `rtvs-daemon` uses the `ssl-cert-snakeoil.pem` and `ssl-cert-snakeoil.pem` generated by `ssl-cert` package. During installation we combine them into `ssl-cert-snakeoil.pfx`. For production purposes use the SSL certificate provided by your admin. SSL certificate can be configured by providing a PFX file and optional import password, in: `/etc/rtvs/rtvsd.config.json`
13. [optional] Check service is running:
```
ps -A -f | grep rtvsd
```
If you dont see a process running under the user name rtvssvc. Start it using the following command:
```
sudo systemctl start rtvsd
```
### On Ubuntu DSVM on Azure
You will need Putty for Windows, or other SSH client.
1. Log into https://portal.azure.com
2. Go to Virtual Machines and click on Add.
3. This should bring up available VM images. Search for `Linux Data Science`.
4. Select the linux DSVM iamge and set the deployment model as `Resource manager` and hit create.
5. Choose a name for the VM, type in username and password (password is required, we dont support SSH public key login). Make changes as needed to the VM configuration.
6. In the next tab choose a VM size. Verify the configuration and hit create. It will take a while to build the VM.
7. Once it is done, in the Networking tab for the VM add `5444` as an allowed inbound port. If you want to use a different port, you can configure that in config file for rtvs daemon which can be found here: `/etc/rtvs/rtvsd.config.json`.
8. [optional] Set a DNS name, you can also use the IP address.
9. Connect to the VM using SSH client, and download the rtvs daemon tarball:
```
wget -O rtvs-daemon.tar.gz https://aka.ms/r-remote-services-linux-binary-current
tar -xvzf rtvs-daemon.tar.gz
```
10. Run the install script:
```
sudo ./rtvs-install
```
11. Enable and start the service:
```
sudo systemctl enable rtvsd
```
12. [required for production] Configure SSL certificate:
By default, `rtvs-daemon` uses the `ssl-cert-snakeoil.pem` and `ssl-cert-snakeoil.pem` generated by `ssl-cert` package. During installation we combine them into `ssl-cert-snakeoil.pfx`. For production purposes use the SSL certificate provided by your admin. SSL certificate can be configured by providing a PFX file and optional import password, in: `/etc/rtvs/rtvsd.config.json`
13. [optional] Check service is running:
```
ps -A -f | grep rtvsd
```
If you dont see a process running under the user name rtvssvc. Start it using the following command:
```
sudo systemctl start rtvsd
```
### On Windows Subsystem for Linux (WSL)
1. Instructions to setup WSL.
https://msdn.microsoft.com/en-us/commandline/wsl/install_guide
2. Start bash on Windows and download rtvs daemon tarball:
```
wget -O rtvs-daemon.tar.gz https://aka.ms/r-remote-services-linux-binary-current
tar -xvzf rtvs-daemon.tar.gz
```
3. Run the install script:
```
sudo ./rtvs-install
```
4. [required for production] Configure SSL certificate:
By default, `rtvs-daemon` uses the `ssl-cert-snakeoil.pem` and `ssl-cert-snakeoil.pem` generated by `ssl-cert` package. During installation we combine them into `ssl-cert-snakeoil.pfx`. For production purposes use the SSL certificate provided by your admin. SSL certificate can be configured by providing a PFX file and optional import password, in: `/etc/rtvs/rtvsd.config.json`
5. Start rtvs daemon, execute the following command:
```
rtvsd
```
Note: WSL currently does not support systemd/systemctl interfaces.
### In a Docker container running locally (clean build)
1. Dockerfile contents:
```
FROM ubuntu:16.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y software-properties-common python-software-properties \
&& apt-get install -y apt-transport-https \
&& rm -rf /var/lib/apt/lists/*
RUN sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list' \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893 \
&& sh -c 'echo "deb https://cran.revolutionanalytics.com/bin/linux/ubuntu xenial/" > /etc/apt/sources.list.d/cran-r.list' \
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
RUN apt-get update --fix-missing && apt-get update \
&& apt-get install -y dotnet-dev-1.0.4 libexplain51 libzip4 libc6 git lshw ssl-cert wget \
&& rm -rf /var/lib/apt/lists/*
# install R
RUN apt-get update && apt-get install -y r-base-dev
RUN apt upgrade -y
# install rtvs-daemon
RUN wget -O rtvs-daemon.tar.gz https://aka.ms/r-remote-services-linux-binary-current && tar -xvzf rtvs-daemon.tar.gz && ./rtvs-install -s
RUN useradd --create-home ruser1
RUN echo "ruser1:foobar" | chpasswd
EXPOSE 5444
```
This will install Remote R service daemon and the latest version of R. Note the **username** and **password**, you will need this to connect to the container.
1. Build and run the above docker file:
```
docker build -t myrimage .
docker run -p 5444:5444 myrimage rtvsd
```
2. You can connect to this container from RTVS. Use `https://localhost:5444` as the path, username `ruser1`, and password `foobar`. If the docker container is running on the remote machine then use `https://remote-host-name:5444`. The port can be changed by updating `/etc/rtvs/rtvsd.config.json`
### In a container running on Azure Container Instances
Use instructions from running in docker container to create a image.
1. Push the container to docker hub or Azure Container Repository.
3. Start the Azure CLI and logon to azure using `az login` command.
4. Use `az container create` command to create the container. Use `--command-line "rtvsd"`, if you have not setup the container to run `rtvsd` as a `systemd` service. In the command below the image is expected to be on docker hub. You can also use Azure ACR for this, by adding ACR login arguments to the command line.
```
az container create --image myimage:latest --name myaz-container --resource-group myaz-container-res --ip-address public --port 5444 --cpu 2 --memory 4 --command-line "rtvsd"
```
5. Use `az container list` command to check the status. Look for `provisioningState`: `Succeeded`.
6. If the provisioning succeeded, you can now connect to the container. Look for the public IP address, in the `ipAddress` field. Use that to connect to the container from RTVS. Rememeber to use username and password as it was in the docker file.
## Connecting from RTVS
1. Open workspaces window from R Tools > Windows > Workspaces.
2. Click on Add Connection.
3. Give the connection a name and add the path. Example for WSL `https://localhost:5444`, Example for acure container `https://public-ip:5444`. Hit Save.
4. Click on connect icon or double click on the connection item.
5. Username should be entered in the following format: `<<unix>>\ruser1`. Do not forget the `<<unix>>\` prefix for all connections to Linux remotes.
6. If you are using self-signed certificate you may see a warning. Follow the instrcutions in the message box.
7. You should now be connected to the Linux rtvs daemon.

Просмотреть файл

@ -0,0 +1,55 @@
# Using Docker Container with RTVS
RTVS client v1.3 onwards supports working with docker containers. Please install `Docker for Windows`, before using this feature.
## Creating a container
1. Click on the **Containers...** button on the right hand corner of the **Workspaces** window.
![Workspaces window in R Tools for Visual Studio (VS2017)](media/workspaces-window-containers.png)
2. That should bring you to the **Containers** window.
![Containers window in R Tools for Visual Studio (VS2017)](media/containers-window.png)
3. Click on *Create* button.
![Containers window in R Tools for Visual Studio (VS2017)](media/containers-window-create-new.png)
4. Enter a name for the container, a username , and a password. The username and password will be used to create an account on linux which you will connect to in the later step. Click on *Create* button at the bottom after you are done.
![Containers window in R Tools for Visual Studio (VS2017)](media/containers-window-create-fill.png)
5. RTVS will build the image and start the container. You can Stop, Remove, or Restart the container from the **Containers** window.
![Containers window in R Tools for Visual Studio (VS2017)](media/containers-window-created.png)
## Connecting to a container
1. A container that is running RTVS daemon on port 5444 will show up in the **Local Running Containers** section of the **Workspaces** window.
![Workspaces window in R Tools for Visual Studio (VS2017)](media/workspaces-window-running-containers.png)
2. You can connect to any container listed here by double clicking or clicking on the connect button.
![Workspaces window and REPL window in R Tools for Visual Studio (VS2017)](media/workspaces-window-container-connected.png)
## Using custom built images
RTVS Container feature will detect and allow management of containers created using custom built images. Here is a sample docker image built using microsoft/rtvs image. The base image used below has rtvs-daemon, R 3.4.2, and common R packages pre-installed. Change the **username** and **password** in the Dockerfile below as needed.
```
FROM microsoft/rtvs:1.3-ub1604-r3.4.2
RUN useradd --create-home ruser1
RUN echo "ruser1:foobar" | chpasswd
```
Note the username and password. Build the image using following commands. Change the container **name** as needed:
```
docker build -t my-rtvs-image:latest .
docker run -p 6056:5444 --name my-rtvs-container my-rtvs-image:latest rtvsd
```
In the `docker run` command, we used port 6056 to map to internal port 5444. RTVS uses this to detect rtvs-daemon. Any container which uses exposes container port 5444 will be listed in the RTVS Container UI. You can now connect to `my-rtvs-container` from the workspaces window. You will need to use `<<unix>>\ruser1` as the username while connecting.
![Remote Logon Window](media/remote-logon-window.png)

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[未能加载 SSL 证书: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[远程 R 请求打开 {0},但远程连接仅支持 http:// URI。]]></Val>
<Val><![CDATA[远程 R 请求打开 {0},但远程连接仅支持 http:// 或 file:// URI。]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[在 {0} 中找不到资源]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[無法載入 SSL 憑證: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[遠端 R 已要求開啟 {0},但對遠端僅支援 http:// URI。]]></Val>
<Val><![CDATA[遠端 R 已要求開啟 {0},但對遠端僅支援 http:// 或 file:// URI。]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[於 {0} 處找不到資源]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30827.920]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30827.0920]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30827.0920]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nepovedlo se načíst certifikát protokolu SSL: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30911.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Vzdálená služba R žádala o otevření adresy {0}, ale pro vzdálenou službu jsou podporovány jen identifikátory URI formátu http://.]]></Val>
<Val><![CDATA[Vzdálená služba R žádala o otevření adresy {0}, ale pro vzdálenou službu jsou podporovány jen identifikátory URI formátu http:// nebo file://.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Prostředek se v {0} nepovedlo najít]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Fehler beim Laden des SSL-Zertifikats: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30911.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Remote-R-Anforderung zum Öffnen von {0} ist eingegangen, aber nur http://-URIs werden für Remotesitzungen unterstützt.]]></Val>
<Val><![CDATA[R-Remoteanforderung zum Öffnen von {0} ist eingegangen, aber für Remotesitzungen werden nur http://- oder file://-URIs unterstützt.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Die Ressource wurde unter "{0}" nicht gefunden.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[No se pudo cargar el certificado SSL: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30911.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[R remoto ha solicitado abrir {0}, pero solo se admiten los URI http:// de remoto.]]></Val>
<Val><![CDATA[R remoto ha solicitado abrir {0}, pero solo se admiten los URI http:// o file:// de remoto.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[No se encuentra el recurso en {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Échec du chargement du certificat SSL : {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30913.957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30913.0957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30913.0957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Remote R Services a demandé d'ouvrir {0}, mais seuls les URI http:// sont pris en charge pour l'accès à distance.]]></Val>
<Val><![CDATA[Remote R a demandé d'ouvrir {0}, mais seuls les URI http:// et file:// sont pris en charge pour l'accès à distance.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ressource introuvable à l'emplacement {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30930.303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30930.0303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30930.0303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Non è stato possibile caricare il certificato SSL: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[L'installazione di R remota ha richiesto l'apertura di {0}, ma in remoto sono supportati solo gli URI http://.]]></Val>
<Val><![CDATA[R remoto ha richiesto l'apertura di {0}, ma in remoto sono supportati solo gli URI http:// o file://.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Non è stato possibile trovare la risorsa in {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[SSL 証明書を読み込めませんでした: {0} ]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30911.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[リモート R により {0} を開くよう要求されましたが、リモートでは http:// URI のみがサポートされています。]]></Val>
<Val><![CDATA[リモート R により {0} を開くよう要求されましたが、リモートでは http:// または file:// の URI のみがサポートされています。]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} にリソースが見つかりませんでした]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[SSL 인증서를 로드하지 못했습니다. {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30911.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30911.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[원격 R이 {0}을(를) 열도록 요청했지만 원격에 대해서는 http:// URI만 지원됩니다.]]></Val>
<Val><![CDATA[원격 R이 {0}을(를) 열도록 요청했지만 원격에 대해서는 http:// 또는 file:// URI만 지원됩니다.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0}에서 리소스를 찾을 수 없습니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nie można załadować certyfikatu SSL: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Usługa zdalna języka R żądała otwarcia adresu {0}, ale w przypadku elementów zdalnych obsługiwane są tylko identyfikatory URI http://.]]></Val>
<Val><![CDATA[Usługa zdalna języka R żądała otwarcia adresu {0}, ale w przypadku elementów zdalnych obsługiwane są tylko identyfikatory URI http:// lub file://.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Nie można znaleźć zasobu w lokalizacji {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Falha ao carregar o Certificado SSL: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[O R Remoto solicitou que {0} fosse aberto, mas apenas as URIs http:// têm suporte remoto.]]></Val>
<Val><![CDATA[O R remoto solicitou a abertura de {0}, mas somente os URIs http:// ou file:// têm suporte remoto.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Não foi possível encontrar o recurso em {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30928.1017]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Не удалось загрузить сертификат SSL: {0}.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30913.957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -346,7 +355,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30913.0957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -382,7 +391,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30913.0957]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Удаленный R запросил открыть {0}, однако в удаленном режиме поддерживаются только URI http://.]]></Val>
<Val><![CDATA[Удаленная служба R запросила открытие {0}, но в удаленном режиме поддерживаются только URI-коды http:// или file://.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Не удалось найти ресурс по адресу {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30930.303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -403,7 +415,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30930.0303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -439,7 +451,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30930.0303]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -13,6 +13,15 @@
<Disp Icon="Expand" Expand="true" Disp="true" LocTbl="false" Path=" \ ;Managed Resources \ 0 \ 0" />
<Item ItemId=";Strings" ItemType="0" PsrId="211" Leaf="false">
<Disp Icon="Str" Disp="true" LocTbl="false" />
<Item ItemId=";Critical_CertificateLoadFailed" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Failed to load SSL Certificate: {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[SSL Sertifikası yüklenemedi: {0}]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Critical_InvalidPipeHandle" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Requested to write 'urls' to pipe '{0}', but it is not a valid pipe handle]]></Val>
@ -322,7 +331,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.2.30909.305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -343,7 +352,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -379,7 +388,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.2.30909.0305]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Просмотреть файл

@ -159,10 +159,13 @@
</Item>
<Item ItemId=";Error_RemoteUriNotSupported" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
<Val><![CDATA[Remote R requested to open {0}, but only http:// or file:// URIs are supported for remote.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Uzak R, {0} öğesini açmak istedi ancak uzak konumlar için yalnızca http:// URI'leri destekleniyor.]]></Val>
<Val><![CDATA[Uzak R, {0} öğesini açmak istedi ancak uzak konumlar için yalnızca http:// veya file:// URI'leri desteklenir.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Remote R requested to open {0}, but only http:// URIs are supported for remote.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
@ -283,6 +286,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Error_UriPathNotFound" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Could not find the resource at {0}]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Kaynak, {0} konumunda bulunamadı]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";HttpErrorCreatingSession" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[HTTP error while creating session on the machine '{0}'. Exception: {1}]]></Val>
@ -379,7 +391,7 @@
<Disp Icon="Ver" Disp="true" LocTbl="false" Path=" \ ;Version \ 8 \ 0" />
<Item ItemId=";AssemblyVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.306]]></Val>
<Val><![CDATA[1.3.30927.948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -400,7 +412,7 @@
</Item>
<Item ItemId=";FileVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
@ -436,7 +448,7 @@
</Item>
<Item ItemId=";ProductVersion" ItemType="0" PsrId="211" Leaf="true">
<Str Cat="Text" DevLk="true">
<Val><![CDATA[1.2.30816.0306]]></Val>
<Val><![CDATA[1.3.30927.0948]]></Val>
</Str>
<Disp Icon="Str" />
</Item>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -11,9 +11,10 @@ namespace Microsoft.Common.Core.Disposables {
private readonly string _message;
private ConcurrentStack<Action> _disposables;
public static DisposableBag Create<T>(IDisposable disposable) where T : IDisposable => Create<T>().Add(disposable);
public static DisposableBag Create<T>(Action action) where T : IDisposable => Create<T>().Add(action);
public static DisposableBag Create<T>() where T : IDisposable => new DisposableBag(typeof(T).Name, FormattableString.Invariant($"{typeof(T).Name} instance is disposed"));
public static DisposableBag Create(IDisposable instance) => Create(instance.GetType());
public static DisposableBag Create<T>() where T : IDisposable => Create(typeof(T));
private static DisposableBag Create(Type type) => new DisposableBag(type.Name, FormattableString.Invariant($"{type.Name} instance is disposed"));
public DisposableBag(string objectName, string message = null) {
_objectName = objectName;

Просмотреть файл

@ -16,11 +16,12 @@ namespace Microsoft.Common.Core.Disposables {
private DisposeToken(Type type) {
_type = type;
_cts = new CancellationTokenSource();
CancellationToken = _cts.Token;
}
public bool IsDisposed => _cts.IsCancellationRequested;
public CancellationToken CancellationToken => _cts.Token;
public CancellationToken CancellationToken { get; }
public void ThrowIfDisposed() {
if (!_cts.IsCancellationRequested) {
@ -32,14 +33,14 @@ namespace Microsoft.Common.Core.Disposables {
public IDisposable Link(ref CancellationToken token) {
if (!token.CanBeCanceled) {
token = _cts.Token;
token = CancellationToken;
token.ThrowIfCancellationRequested();
return Disposable.Empty;
}
CancellationTokenSource linkedCts;
try {
linkedCts = CancellationTokenSource.CreateLinkedTokenSource(_cts.Token, token);
linkedCts = CancellationTokenSource.CreateLinkedTokenSource(CancellationToken, token);
} catch (ObjectDisposedException) {
throw CreateException();
}

Просмотреть файл

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Common.Core.Services;
using Microsoft.Common.Core.Threading;
using Microsoft.Common.Core.UI;
@ -19,9 +20,9 @@ namespace Microsoft.Common.Core.Shell {
coreShell.UI().ShowErrorMessage(message);
}
public static async Task<MessageButtons> ShowMessageAsync(this ICoreShell coreShell, string message, MessageButtons buttons, CancellationToken cancellationToken = default(CancellationToken)) {
await coreShell.SwitchToMainThreadAsync(cancellationToken);
return coreShell.UI().ShowMessage(message, buttons);
public static async Task<MessageButtons> ShowMessageAsync(this IServiceContainer services, string message, MessageButtons buttons, CancellationToken cancellationToken = default(CancellationToken)) {
await services.MainThread().SwitchToAsync(cancellationToken);
return services.UI().ShowMessage(message, buttons);
}
[Conditional("TRACE")]

Просмотреть файл

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Net;
using System.Net.Sockets;
namespace Microsoft.Common.Core.Net {
public static class PortUtil {
private static Random _rand = new Random();
public static int GetAvailablePort(int minPort, int maxPort) {
int port = _rand.Next(minPort, maxPort + 1);
while (!IsPortAvailable(port)) {
port = _rand.Next(minPort, maxPort + 1);
}
return port;
}
public static bool IsPortAvailable(int port) {
try {
TcpListener listener = new TcpListener(IPAddress.Loopback, port);
listener.Start();
// port is available
listener.Stop();
return true;
} catch (SocketException ex) when (ex.SocketErrorCode == SocketError.AddressAlreadyInUse) {
return false;
}
}
}
}

Просмотреть файл

@ -1,4 +1,7 @@
using System.Threading;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Common.Core.Tasks;

Просмотреть файл

@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Microsoft.R.Common.Core.Output {
public interface IOutput {
void Write(string text);
void WriteError(string text);
}
}

Просмотреть файл

@ -0,0 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Microsoft.R.Common.Core.Output{
public interface IOutputService {
IOutput Get(string name);
}
}

Просмотреть файл

@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace Microsoft.R.Common.Core.Output {
public static class OutputExtensions {
public static void WriteLine(this IOutput output, string value) => output.Write(value + Environment.NewLine);
public static void WriteErrorLine(this IOutput output, string value) => output.WriteError(value + Environment.NewLine);
}
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace Microsoft.Common.Core.Services {
/// Adds on-demand created service
/// </summary>
/// <param name="factory">Service factory</param>
IServiceManager AddService<T>(Func<IServiceManager, T> factory) where T : class;
IServiceManager AddService<T>(Func<IServiceContainer, T> factory) where T : class;
/// <summary>
/// Removes service from container by instance

Просмотреть файл

@ -2,8 +2,9 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Common.Core.IO;
@ -19,6 +20,8 @@ using Microsoft.Common.Core.UI.Commands;
namespace Microsoft.Common.Core.Services {
public static class ServiceContainerExtensions {
public static IServiceManager Extend(this IServiceContainer serviceContainer) => new ServiceManagerExtension(serviceContainer);
public static IActionLog Log(this IServiceContainer sc) => sc.GetService<IActionLog>();
public static IFileSystem FileSystem(this IServiceContainer sc) => sc.GetService<IFileSystem>();
public static IProcessServices Process(this IServiceContainer sc) => sc.GetService<IProcessServices>();
@ -29,16 +32,6 @@ namespace Microsoft.Common.Core.Services {
public static IMainThread MainThread(this IServiceContainer sc) => sc.GetService<IMainThread>();
public static IIdleTimeService IdleTime(this IServiceContainer sc) => sc.GetService<IIdleTimeService>();
/// <summary>
/// Displays application-specific modal progress window
/// </summary>
public static IProgressDialog ProgressDialog(this IServiceContainer sc) => sc.UI().ProgressDialog;
/// <summary>
/// Displays platform-specific file selection window
/// </summary>
public static IFileDialog FileDialog(this IServiceContainer sc) => sc.UI().FileDialog;
/// <summary>
/// Switches to UI thread asynchonously and then displays the message
/// </summary>
@ -65,10 +58,41 @@ namespace Microsoft.Common.Core.Services {
public static MessageButtons ShowMessage(this IServiceContainer sc, string message, MessageButtons buttons, MessageType messageType = MessageType.Information)
=> sc.UI().ShowMessage(message, buttons, messageType);
[Conditional("TRACE")]
public static void Assert(this IMainThread mainThread, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) {
if (mainThread.ThreadId != Thread.CurrentThread.ManagedThreadId) {
Debug.Fail(FormattableString.Invariant($"{memberName} at {sourceFilePath}:{sourceLineNumber} was incorrectly called from a background thread."));
public static T CreateInstance<T>(this IServiceContainer s) where T : class => InstanceFactory<T>.New(s);
private static class InstanceFactory<T> where T : class {
private static readonly Func<IServiceContainer, T> _factory;
static InstanceFactory() => _factory = CreateFactory()
?? throw new InvalidOperationException($"Type {typeof(T)} should have either default constructor or constructor that accepts IServiceContainer");
public static T New(IServiceContainer services) => _factory(services);
private static Func<IServiceContainer, T> CreateFactory() {
var constructors = typeof(T).GetTypeInfo().DeclaredConstructors
.Where(c => c.IsPublic)
.ToList();
foreach (var constructor in constructors) {
var parameters = constructor.GetParameters();
if (parameters.Length == 1 && typeof(IServiceContainer) == parameters[0].ParameterType) {
var parameter = Expression.Parameter(typeof(IServiceContainer), "services");
return Expression
.Lambda<Func<IServiceContainer, T>>(Expression.New(constructor, parameter), parameter)
.Compile();
}
}
foreach (var constructor in constructors) {
if (constructor.GetParameters().Length == 0) {
var parameter = Expression.Parameter(typeof(IServiceContainer), "services");
return Expression
.Lambda<Func<IServiceContainer, T>>(Expression.New(constructor), parameter)
.Compile();
}
}
return null;
}
}
}

Просмотреть файл

@ -39,7 +39,7 @@ namespace Microsoft.Common.Core.Services {
/// Adds on-demand created service
/// </summary>
/// <param name="factory">Service factory</param>
public virtual IServiceManager AddService<T>(Func<IServiceManager, T> factory) where T : class {
public virtual IServiceManager AddService<T>(Func<IServiceContainer, T> factory) where T : class {
_disposeToken.ThrowIfDisposed();
var lazy = new Lazy<object>(() => factory(this));
@ -73,24 +73,6 @@ namespace Microsoft.Common.Core.Services {
public virtual IEnumerable<Type> AllServices => _s.Keys.ToList();
public virtual IEnumerable<T> GetServices<T>() where T : class {
if (_disposeToken.IsDisposed) {
yield break;
}
var type = typeof(T);
foreach (var value in _s.Values.OfType<T>()) {
CheckDisposed(value);
yield return value;
}
// Perhaps someone is asking for IFoo that is implemented on class Bar
// but Bar was added as Bar, not as IFoo
foreach (var kvp in _s.Where(kvp => kvp.Value is Lazy<object> && type.GetTypeInfo().IsAssignableFrom(kvp.Key))) {
yield return (T)CheckDisposed(((Lazy<object>)kvp.Value).Value);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private object CheckDisposed(object service) {
if (_disposeToken.IsDisposed) {

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Common.Core.Services {
internal sealed class ServiceManagerExtension : ServiceManager {
private readonly IServiceContainer _parent;
public override IEnumerable<Type> AllServices => _parent.AllServices.Union(base.AllServices);
public ServiceManagerExtension(IServiceContainer parent) {
_parent = parent;
}
public override T GetService<T>(Type type = null) {
return base.GetService<T>(type) ?? _parent.GetService<T>(type);
}
}
}

Просмотреть файл

@ -1,62 +1,19 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace Microsoft.Common.Core.Services {
public static class ServiceManagerExtensions {
public static IServiceManager AddService<TService>(this IServiceManager services)
where TService : class
=> AddService<TService, TService>(services);
public static IServiceManager AddService<TService>(this IServiceManager services, TService instance)
where TService : class
=> services.AddService(instance, typeof(TService));
public static IServiceManager AddService<TService, TImplementation>(this IServiceManager services)
where TService : class
where TImplementation : class, TService
=> services.AddService<TService>(CreateInstance<TImplementation>);
private static T CreateInstance<T>(IServiceContainer s) where T : class {
return InstanceFactory<T>.New(s);
}
private static class InstanceFactory<T> where T : class {
private static readonly Func<IServiceContainer, T> _factory;
static InstanceFactory() {
_factory = CreateFactory()
?? throw new InvalidOperationException($"Type {typeof(T)} should have either default constructor or constructor that accepts IServiceContainer");
}
public static T New(IServiceContainer services) => _factory(services);
private static Func<IServiceContainer, T> CreateFactory() {
var constructors = typeof(T).GetTypeInfo().DeclaredConstructors
.Where(c => c.IsPublic)
.ToList();
foreach (var constructor in constructors) {
var parameters = constructor.GetParameters();
if (parameters.Length == 1 && typeof(IServiceContainer) == parameters[0].ParameterType) {
var parameter = Expression.Parameter(typeof(IServiceContainer), "services");
return Expression
.Lambda<Func<IServiceContainer, T>>(Expression.New(constructor, parameter), parameter)
.Compile();
}
}
foreach (var constructor in constructors) {
if (constructor.GetParameters().Length == 0) {
var parameter = Expression.Parameter(typeof(IServiceContainer), "services");
return Expression
.Lambda<Func<IServiceContainer, T>>(Expression.New(constructor), parameter)
.Compile();
}
}
return null;
}
}
=> services.AddService<TService>(ServiceContainerExtensions.CreateInstance<TImplementation>);
}
}

Просмотреть файл

@ -28,12 +28,12 @@ namespace Microsoft.Common.Core.Shell {
/// <summary>
/// Displays application-specific modal progress window
/// </summary>
public static IProgressDialog ProgressDialog(this ICoreShell shell) => shell.Services.ProgressDialog();
public static IProgressDialog ProgressDialog(this ICoreShell shell) => shell.Services.UI().ProgressDialog;
/// <summary>
/// Displays platform-specific file selection window
/// </summary>
public static IFileDialog FileDialog(this ICoreShell shell) => shell.Services.FileDialog();
public static IFileDialog FileDialog(this ICoreShell shell) => shell.Services.UI().FileDialog;
/// <summary>
/// Displays error message in a host-specific UI

Просмотреть файл

@ -1,11 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Common.Core.Tasks {
public interface ITaskService {
bool Wait(Task task, CancellationToken cancellationToken = default(CancellationToken), int ms = Timeout.Infinite);
bool Wait(Func<Task> method, int ms = Timeout.Infinite, CancellationToken cancellationToken = default(CancellationToken));
bool Wait<T>(Func<Task<T>> method, out T result, int ms = Timeout.Infinite, CancellationToken cancellationToken = default(CancellationToken));
}
}

Просмотреть файл

@ -11,6 +11,7 @@ namespace Microsoft.Common.Core.Telemetry {
public enum TelemetryArea {
// Keep these sorted
Build,
Containers,
Configuration,
DataGrid,
Debugger,

Просмотреть файл

@ -16,7 +16,11 @@ namespace Microsoft.Common.Core.Threading {
/// Posts cancellable action on UI thread.
/// </summary>
/// <param name="action"></param>
/// <param name="cancellationToken"></param>
void Post(Action action, CancellationToken cancellationToken = default(CancellationToken));
void Post(Action action);
/// <summary>
/// Creates main thread awaiter implementation
/// </summary>
IMainThreadAwaiter CreateMainThreadAwaiter(CancellationToken cancellationToken);
}
}

Просмотреть файл

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace Microsoft.Common.Core.Threading {
public interface IMainThreadAwaiter {
bool IsCompleted { get; }
void OnCompleted(Action continuation);
void GetResult();
}
}

Просмотреть файл

@ -8,32 +8,23 @@ using System.Threading;
using Microsoft.Common.Core.Diagnostics;
namespace Microsoft.Common.Core.Threading {
public struct MainThreadAwaiter : ICriticalNotifyCompletion {
public struct MainThreadAwaiter : INotifyCompletion {
private readonly IMainThread _mainThread;
private readonly CancellationToken _cancellationToken;
private readonly IMainThreadAwaiter _awaiterImpl;
public MainThreadAwaiter(IMainThread mainThread, CancellationToken cancellationToken) {
Check.ArgumentNull(nameof(mainThread), mainThread);
_mainThread = mainThread;
_cancellationToken = cancellationToken;
_awaiterImpl = _mainThread.CreateMainThreadAwaiter(cancellationToken);
}
public bool IsCompleted => Thread.CurrentThread.ManagedThreadId == _mainThread.ThreadId;
public bool IsCompleted => _awaiterImpl.IsCompleted;
public void OnCompleted(Action continuation) {
Trace.Assert(continuation != null);
_mainThread.Post(continuation, _cancellationToken);
_awaiterImpl.OnCompleted(continuation);
}
public void UnsafeOnCompleted(Action continuation) {
Trace.Assert(continuation != null);
_mainThread.Post(continuation, _cancellationToken);
}
public void GetResult() {
if (Thread.CurrentThread.ManagedThreadId != _mainThread.ThreadId) {
_cancellationToken.ThrowIfCancellationRequested();
}
}
public void GetResult() => _awaiterImpl.GetResult();
}
}

Просмотреть файл

@ -2,7 +2,10 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.Common.Core.Threading {
public static class MainThreadExtensions {
@ -12,12 +15,30 @@ namespace Microsoft.Common.Core.Threading {
public static bool CheckAccess(this IMainThread mainThread)
=> Thread.CurrentThread.ManagedThreadId == mainThread.ThreadId;
public static void ExecuteOrPost(this IMainThread mainThread, Action action, CancellationToken cancellationToken = default(CancellationToken)) {
[Conditional("TRACE")]
public static void Assert(this IMainThread mainThread, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0) {
if (mainThread.ThreadId != Thread.CurrentThread.ManagedThreadId) {
Debug.Fail(FormattableString.Invariant($"{memberName} at {sourceFilePath}:{sourceLineNumber} was incorrectly called from a background thread."));
}
}
public static void ExecuteOrPost(this IMainThread mainThread, Action action) {
if (mainThread.CheckAccess()) {
action();
} else {
mainThread.Post(action, cancellationToken);
mainThread.Post(action);
}
}
public static async Task SendAsync(this IMainThread mainThread, Action action, CancellationToken cancellationToken = default(CancellationToken)) {
await mainThread.SwitchToAsync(cancellationToken);
action();
}
public static async Task<T> SendAsync<T>(this IMainThread mainThread, Func<T> action, CancellationToken cancellationToken = default(CancellationToken)) {
await mainThread.SwitchToAsync(cancellationToken);
return action();
}
}
}

Просмотреть файл

@ -73,7 +73,7 @@ namespace Microsoft.Common.Core.Test.Disposables {
_disposeToken.TryMarkDisposed();
var token = default(CancellationToken);
Action a = () => _disposeToken.Link(ref token);
a.ShouldThrow<ObjectDisposedException>();
a.ShouldThrow<OperationCanceledException>();
}
public void Dispose() {

Просмотреть файл

@ -0,0 +1,40 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Concurrent;
using Microsoft.Common.Core.Logging;
using Microsoft.Common.Core.Services;
using Microsoft.R.Common.Core.Output;
namespace Microsoft.Common.Core.Test.Fakes.Shell {
public class TestOutputService : IOutputService {
private readonly IServiceContainer _services;
private readonly ConcurrentDictionary<string, IOutput> _outputs;
public TestOutputService(IServiceContainer services) {
_services = services;
_outputs = new ConcurrentDictionary<string, IOutput>();
}
public IOutput Get(string name)
=> _outputs.GetOrAdd(name, prefix => new TestOutput(prefix, _services.Log()));
private class TestOutput : IOutput {
private readonly string _prefix;
private readonly IActionLog _log;
public TestOutput(string prefix, IActionLog log) {
_prefix = prefix;
_log = log;
}
public void Write(string text) {
_log.Write(LogVerbosity.Minimal, MessageCategory.General, $"[{_prefix} output]: {text}");
}
public void WriteError(string text) {
_log.Write(LogVerbosity.Minimal, MessageCategory.Error, $"[{_prefix} output]: {text}");
}
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Windows;
namespace Microsoft.Common.Wpf {
public static class AttachedProperties {
public static readonly DependencyProperty IsValidProperty = DependencyProperty.RegisterAttached("IsValid", typeof(bool), typeof(AttachedProperties), new PropertyMetadata(false));
public static bool GetIsValid(FrameworkElement fe) => (bool)(fe.GetValue(IsValidProperty) ?? false);
public static void SetIsValid(FrameworkElement fe, bool value) => fe.SetValue(IsValidProperty, value);
}
}

Просмотреть файл

@ -1,16 +1,36 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System.Collections.Generic;
namespace Microsoft.R.Containers {
public class BuildImageParameters {
public string Image { get; }
public string Tag { get; }
public IReadOnlyDictionary<string, string> Params { get; }
public string Name { get; }
public string DockerfilePath { get; }
public int Port { get; }
public BuildImageParameters(string dockerFile, string imageName, string imageTag) {
public BuildImageParameters(string dockerFile, string imageName, string imageTag, string name, int port)
: this(dockerFile, imageName, imageTag, new Dictionary<string, string>(), name, port) { }
public BuildImageParameters(string dockerFile, string imageName, string imageTag, IReadOnlyDictionary<string, string> imageParams, string name, int port) {
DockerfilePath = dockerFile;
Image = imageName;
Tag = imageTag;
Params = imageParams;
Name = name;
Port = port;
}
public void Deconstruct(out string dockerFile, out string imageName, out string imageTag, out IReadOnlyDictionary<string, string> imageParams, out string name, out int port) {
dockerFile = DockerfilePath;
imageName = Image;
imageTag = Tag;
imageParams = Params;
name = Name;
port = Port;
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
namespace Microsoft.R.Containers {
public class ContainerImage {
public string Id { get; }
public string Name { get; }
public string Tag { get; }
public ContainerImage(string id, string name, string tag) {
Id = id;
Name = name;
Tag = tag;
}
public void Deconstruct(out string id, out string name, out string tag) {
id = Id;
name = Name;
tag = Tag;
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace Microsoft.R.Containers {
public class ContainerServiceNotReadyException : ContainerException {
public ContainerServiceNotReadyException() { }
public ContainerServiceNotReadyException(string message) : base(message) { }
public ContainerServiceNotReadyException(string message, Exception innerException) : base(message, innerException) { }
}
}

Просмотреть файл

@ -5,10 +5,18 @@ using System;
namespace Microsoft.R.Containers {
public class ContainerServiceNotRunningException : ContainerException {
public ContainerServiceNotRunningException() { }
public ContainerServiceNotRunningException(string serviceName) {
ServiceName = serviceName;
}
public ContainerServiceNotRunningException(string message) : base(message) { }
public ContainerServiceNotRunningException(string serviceName, string message) : base(message) {
ServiceName = serviceName;
}
public ContainerServiceNotRunningException(string message, Exception innerException) : base(message, innerException) { }
public ContainerServiceNotRunningException(string serviceName, string message, Exception innerException) : base(message, innerException) {
ServiceName = serviceName;
}
public string ServiceName { get; }
}
}

Просмотреть файл

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using System;
namespace Microsoft.R.Containers {
public class ContainerServicePermissionException : ContainerException {
public ContainerServicePermissionException() { }
public ContainerServicePermissionException(string message) : base(message) { }
public ContainerServicePermissionException(string message, Exception innerException) : base(message, innerException) { }
}
}

Просмотреть файл

@ -10,16 +10,17 @@ namespace Microsoft.R.Containers.Docker {
public interface IDockerService {
Task<string> BuildImageAsync(string buildOptions, CancellationToken ct);
Task<IEnumerable<IContainer>> ListContainersAsync(bool getAll = true, CancellationToken ct = default(CancellationToken));
Task<IEnumerable<ContainerImage>> ListImagesAsync(bool getAll = true, CancellationToken ct = default(CancellationToken));
Task<IContainer> GetContainerAsync(string containerId, CancellationToken ct);
Task<JArray> InspectContainerAsync(IEnumerable<string> containerIds, CancellationToken ct);
Task<JArray> InspectAsync(IEnumerable<string> objectIds, CancellationToken ct);
Task<string> RepositoryLoginAsync(string username, string password, string server, CancellationToken ct);
Task<string> RepositoryLoginAsync(RepositoryCredentials auth, CancellationToken ct);
Task<string> RepositoryLogoutAsync(RepositoryCredentials auth, CancellationToken ct);
Task<string> RepositoryLogoutAsync(string server, CancellationToken ct);
Task<string> PullImageAsync(string fullImageName, CancellationToken ct);
Task<string> CreateContainerAsync(string createOptions, CancellationToken ct);
Task<string> DeleteContainerAsync(IContainer container, CancellationToken ct);
Task<string> StartContainerAsync(IContainer container, CancellationToken ct);
Task<string> StopContainerAsync(IContainer container, CancellationToken ct);
Task<string> DeleteContainerAsync(string containerId, CancellationToken ct);
Task<string> StartContainerAsync(string containerId, CancellationToken ct);
Task<string> StopContainerAsync(string containerId, CancellationToken ct);
}
}

Просмотреть файл

@ -3,23 +3,19 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.Common.Core;
using Newtonsoft.Json.Linq;
namespace Microsoft.R.Containers.Docker {
public class LocalDockerContainer : IContainer {
private static readonly Regex _containerIdMatcher64 = new Regex("[0-9a-f]{64}", RegexOptions.IgnoreCase);
private static readonly Regex _containerIdMatcher12 = new Regex("[0-9a-f]{12}", RegexOptions.IgnoreCase);
public string Id { get; }
public string Name { get; }
/// <summary>
/// Possible values for Docker Container:
/// "created", "restarting", "running", "removing", "paused", "exited", "dead"
/// </summary>
public string Status { get; }
public bool IsRunning => Status.EqualsOrdinal("running");
public bool IsShortId => Id.Length < 64;
public IEnumerable<int> HostPorts { get; }
@ -38,10 +34,12 @@ namespace Microsoft.R.Containers.Docker {
private IEnumerable<int> GetHostPorts(JToken containerObject) {
var hostPorts = new List<int>();
try {
dynamic portMap = ((dynamic)containerObject).NetworkSettings.Ports["5444/tcp"];
foreach (dynamic pm in portMap) {
if (int.TryParse(pm.HostPort.Value, out int port)) {
hostPorts.Add(port);
dynamic portMap = ((dynamic)containerObject).HostConfig.PortBindings["5444/tcp"];
if (portMap != null) {
foreach (dynamic pm in portMap) {
if (int.TryParse(pm.HostPort.Value, out int port)) {
hostPorts.Add(port);
}
}
}
} catch (Exception ex) when (!ex.IsCriticalException()) {

Просмотреть файл

@ -4,34 +4,55 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Common.Core;
using Microsoft.Common.Core.Logging;
using Microsoft.Common.Core.OS;
using Microsoft.Common.Core.Services;
using Microsoft.R.Common.Core.Output;
using Newtonsoft.Json.Linq;
using static System.FormattableString;
namespace Microsoft.R.Containers.Docker {
public abstract class LocalDockerService : IDockerService {
public const string ContainerOutputName = "R Containers";
private readonly IProcessServices _ps;
private readonly IActionLogWriter _outputLogWriter;
private readonly IOutputService _outputService;
private readonly Regex _containerIdMatcher64 = new Regex("[0-9a-f]{64}", RegexOptions.IgnoreCase);
private readonly Regex _containerIdMatcher12 = new Regex("[0-9a-f]{12}", RegexOptions.IgnoreCase);
private readonly int _defaultTimeout = 500;
private volatile IOutput _output;
protected IOutput Output => _output ?? (_output = _outputService.Get(ContainerOutputName));
protected LocalDockerService(IServiceContainer services) {
_ps = services.Process();
_outputLogWriter = services.GetService<IActionLogWriter>();
// TODO: No instance of IActionLogWriter is exported in default IServiceContainer. Need scope support.
_outputService = services.GetService<IOutputService>();
}
public async Task<IContainer> CreateContainerFromFileAsync(BuildImageParameters buildParams, CancellationToken ct) {
await TaskUtilities.SwitchToBackgroundThread();
var (dockerFile, imageName, imageTag, imageParams, containerName, containerPort) = buildParams;
var images = await ListImagesAsync(true, ct);
if (!images.Any(i => i.Name.EqualsOrdinal(imageName) && i.Tag.EqualsOrdinal(imageTag))) {
var buildArgs = string.Join(" ", imageParams.Select(p => $"--build-arg {p.Key}={p.Value}"));
var buildOptions = $"-t {imageName}:{imageTag} {buildArgs} \"{Path.GetDirectoryName(dockerFile)}\"";
await BuildImageAsync(buildOptions, ct);
}
var createOptions = Invariant($"-p {containerPort}:5444 --name {containerName} {imageName}:{imageTag} rtvsd");
var containerId = await CreateContainerAsync(createOptions, ct);
return await GetContainerAsync(containerId, ct);
}
public Task<string> BuildImageAsync(string buildOptions, CancellationToken ct) {
var command = "build";
return ExecuteCommandAsync(Invariant($"{command} {buildOptions}"), -1, true, ct);
return ExecuteCommandAsync(Invariant($"{command} {buildOptions}"), command, -1, true, ct);
}
public async Task<IEnumerable<IContainer>> ListContainersAsync(bool getAll = true, CancellationToken ct = default(CancellationToken)) {
@ -39,19 +60,46 @@ namespace Microsoft.R.Containers.Docker {
var command = "ps";
var commandOptions = getAll ? "-a -q" : "-q";
var output = await ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), _defaultTimeout, true, ct);
var lines = output.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var output = await ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), null, _defaultTimeout, true, ct);
var lines = output.Split(new[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var ids = lines.Where(line => _containerIdMatcher12.IsMatch(line) || _containerIdMatcher64.IsMatch(line));
var arr = await InspectContainerAsync(ids, ct);
var arr = await InspectAsync(ids, ct);
return arr.Select(c => new LocalDockerContainer(c));
}
public async Task<IEnumerable<ContainerImage>> ListImagesAsync(bool getAll = true, CancellationToken ct = default(CancellationToken)) {
await TaskUtilities.SwitchToBackgroundThread();
var command = "images";
var commandOptions = getAll ? "-a -q" : "-q";
var output = await ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), null, _defaultTimeout, true, ct);
var lines = output.Split(new[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var ids = lines.Where(line => _containerIdMatcher12.IsMatch(line) || _containerIdMatcher64.IsMatch(line));
var arr = await InspectAsync(ids, ct);
return arr.Select(GetContainerImage);
}
private ContainerImage GetContainerImage(JToken c) {
var obj = (dynamic)c;
var objId = ((string)obj.Id);
int idx = objId.IndexOf(':');
var id = idx < 0 ? objId : objId.Substring(idx + 1);
var name = string.Empty;
var tag = string.Empty;
if (((JArray)obj.RepoTags).Any()) {
string[] split = ((string)obj.RepoTags[0]).Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
name = split[0];
tag = split.Length == 2 ? split[1] : string.Empty; ;
}
return new ContainerImage(id, name, tag);
}
public async Task<IContainer> GetContainerAsync(string containerId, CancellationToken ct) {
await TaskUtilities.SwitchToBackgroundThread();
var ids = (await ListContainersAsync(true, ct)).Where(container => containerId.StartsWithIgnoreCase(container.Id));
if (ids.Any()) {
var arr = await InspectContainerAsync(new string[] { containerId }, ct);
var arr = await InspectAsync(new string[] { containerId }, ct);
if (arr.Count == 1) {
return new LocalDockerContainer(arr[0]);
}
@ -60,14 +108,14 @@ namespace Microsoft.R.Containers.Docker {
return null;
}
public async Task<JArray> InspectContainerAsync(IEnumerable<string> containerIds, CancellationToken ct) {
public async Task<JArray> InspectAsync(IEnumerable<string> containerIds, CancellationToken ct) {
await TaskUtilities.SwitchToBackgroundThread();
var ids = containerIds.AsList();
if (ids.Any()) {
var command = "container inspect";
var command = "inspect";
var commandOptions = string.Join(" ", ids);
var result = await ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), _defaultTimeout, false, ct);
var result = await ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), null, _defaultTimeout, false, ct);
return JArray.Parse(result);
}
@ -77,62 +125,60 @@ namespace Microsoft.R.Containers.Docker {
public Task<string> RepositoryLoginAsync(string username, string password, string server, CancellationToken ct) {
var command = "login";
var commandOptions = $"-u {username} -p {password} {server}";
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), $"{command} {server}", -1, true, ct);
}
public Task<string> RepositoryLoginAsync(RepositoryCredentials auth, CancellationToken ct)
=> RepositoryLoginAsync(auth.Username, auth.Password, auth.RepositoryServer, ct);
public Task<string> RepositoryLogoutAsync(string server, CancellationToken ct) {
var command = "logout";
var commandOptions = server;
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
var command = $"logout {server}";
return ExecuteCommandAsync(command, command, -1, true, ct);
}
public Task<string> RepositoryLogoutAsync(RepositoryCredentials auth, CancellationToken ct)
=> RepositoryLogoutAsync(auth.RepositoryServer, ct);
public Task<string> PullImageAsync(string fullImageName, CancellationToken ct) {
var command = "pull";
var commandOptions = fullImageName;
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
var command = $"pull {fullImageName}";
return ExecuteCommandAsync(command, command, -1, true, ct);
}
public async Task<string> CreateContainerAsync(string createOptions, CancellationToken ct) {
await TaskUtilities.SwitchToBackgroundThread();
var command = "create";
var output = await ExecuteCommandAsync(Invariant($"{command} {createOptions}"), -1, true, ct);
var output = await ExecuteCommandAsync(Invariant($"{command} {createOptions}"), command, -1, true, ct);
var matches = _containerIdMatcher64.Matches(output);
return matches.Count >= 1 ? matches[0].Value : string.Empty;
}
public Task<string> DeleteContainerAsync(IContainer container, CancellationToken ct) {
var command = "rm";
var commandOptions = $"{container.Id}";
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
public Task<string> DeleteContainerAsync(string containerId, CancellationToken ct) {
var command = Invariant($"rm {containerId}");
return ExecuteCommandAsync(command, command, -1, true, ct);
}
public Task<string> StartContainerAsync(IContainer container, CancellationToken ct) {
var command = "start";
var commandOptions = $"{container.Id}";
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
public Task<string> StartContainerAsync(string containerId, CancellationToken ct) {
var command = Invariant($"start {containerId}");
return ExecuteCommandAsync(command, command, -1, true, ct);
}
public Task<string> StopContainerAsync(IContainer container, CancellationToken ct) {
var command = "stop";
var commandOptions = $"{container.Id}";
return ExecuteCommandAsync(Invariant($"{command} {commandOptions}"), -1, true, ct);
public Task<string> StopContainerAsync(string containerId, CancellationToken ct) {
var command = Invariant($"stop {containerId}");
return ExecuteCommandAsync(command, command, -1, true, ct);
}
protected abstract LocalDocker GetLocalDocker();
private async Task<string> ExecuteCommandAsync(string arguments, int timeoutms, bool failOnTimeout = true, CancellationToken ct = default(CancellationToken)) {
private async Task<string> ExecuteCommandAsync(string arguments, string outputPrefix, int timeoutms, bool failOnTimeout = true, CancellationToken ct = default(CancellationToken)) {
var printOutput = outputPrefix != null;
await TaskUtilities.SwitchToBackgroundThread();
var docker = GetLocalDocker();
ProcessStartInfo psi = new ProcessStartInfo {
var psi = new ProcessStartInfo {
CreateNoWindow = true,
FileName = docker.DockerCommandPath,
Arguments = arguments,
RedirectStandardError = true,
@ -142,20 +188,45 @@ namespace Microsoft.R.Containers.Docker {
};
var process = _ps.Start(psi);
var result = new StringBuilder();
try {
while (!process.StandardOutput.EndOfStream) {
var line = await process.StandardOutput.ReadLineAsync();
if (printOutput) {
Output.WriteLine(Invariant($"{outputPrefix}> {line}"));
}
result.AppendLine(line);
}
await process.WaitForExitAsync(timeoutms, ct);
} catch(IOException) {
if (printOutput) {
Output.WriteError(Resources.LocalDockerErrorFormat.FormatInvariant(outputPrefix, Resources.LocalDockerOutputStreamException));
}
throw new ContainerException(Resources.LocalDockerOutputStreamException);
} catch(OperationCanceledException) when (!failOnTimeout && !ct.IsCancellationRequested){
}
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
if (!string.IsNullOrEmpty(error)) {
_outputLogWriter?.Write(MessageCategory.Error, error);
throw new ContainerException(error);
if (!string.IsNullOrEmpty(error) && !IsSecurityWarning(error)) {
Output.WriteError(Resources.LocalDockerErrorFormat.FormatInvariant(outputPrefix, error));
if (IsServiceNotReady(error)) {
throw new ContainerServiceNotReadyException(error);
} else {
throw new ContainerException(error);
}
}
return result.ToString();
}
_outputLogWriter?.Write(MessageCategory.General, output);
return output;
private bool IsSecurityWarning(string error) {
return error.ContainsIgnoreCase("SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host.");
}
private bool IsServiceNotReady(string error) {
return error.ContainsIgnoreCase("open //./pipe/docker_engine: The system cannot find the file specified") ||
error.ContainsIgnoreCase("docker daemon is not running");
}
}
}

Просмотреть файл

@ -9,5 +9,6 @@ namespace Microsoft.R.Containers {
string Name { get; }
IEnumerable<int> HostPorts { get; }
string Status { get; }
bool IsRunning { get; }
}
}

Просмотреть файл

@ -10,9 +10,11 @@ namespace Microsoft.R.Containers {
ContainerServiceStatus GetServiceStatus();
Task<IContainer> GetContainerAsync(string containerId, CancellationToken ct);
Task<IEnumerable<IContainer>> ListContainersAsync(bool allContainers, CancellationToken ct);
Task<IEnumerable<ContainerImage>> ListImagesAsync(bool allImages, CancellationToken ct);
Task<IContainer> CreateContainerFromFileAsync(BuildImageParameters buildOptions, CancellationToken ct);
Task<IContainer> CreateContainerAsync(ContainerCreateParameters createParams, CancellationToken ct);
Task DeleteContainerAsync(IContainer container, CancellationToken ct);
Task StartContainerAsync(IContainer container, CancellationToken ct);
Task StopContainerAsync(IContainer container, CancellationToken ct);
Task DeleteContainerAsync(string containerId, CancellationToken ct);
Task StartContainerAsync(string containerId, CancellationToken ct);
Task StopContainerAsync(string containerId, CancellationToken ct);
}
}

82
src/Containers/Impl/Resources.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,82 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.R.Containers {
using System;
using System.Reflection;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.R.Containers.Resources", typeof(Resources).GetTypeInfo().Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to {0}&gt; ERROR: {1}.
/// </summary>
internal static string LocalDockerErrorFormat {
get {
return ResourceManager.GetString("LocalDockerErrorFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Can&apos;t read from Docker process output stream.
/// </summary>
internal static string LocalDockerOutputStreamException {
get {
return ResourceManager.GetString("LocalDockerOutputStreamException", resourceCulture);
}
}
}
}

Просмотреть файл

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="LocalDockerOutputStreamException" xml:space="preserve">
<value>Can't read from Docker process output stream</value>
</data>
<data name="LocalDockerErrorFormat" xml:space="preserve">
<value>{0}> ERROR: {1}</value>
</data>
</root>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше