After I disconnect from the vpn using this code System.Diagnostics.Process.Start("rasdial.exe", "My_VPN /d"); It still shows on the VPN Connection list. How can I remove it from there through my program?
If you want to delete VPN connection you need to delete file "rasphone.pbk" or section with [VPN Name] in this file. The file is INI file with extension PBK.
By default the file located in %APPDATA%\Microsoft\Network\Connections\Pbk\rasphone.pbk
After delete operation you will need to restart "explorer.exe"
You can remove it by using WMI's PS_VpnConnection class.
using System.Management; // need to add a reference to the assembly [System.Management]
public class Program
{
public static void Main()
{
const string WMIScope = "root/Microsoft/Windows/RemoteAccess/Client";
const string WMIClass = "PS_VpnConnection";
using (var cls = new ManagementClass(WMIScope, WMIClass, null))
using (var methodParams = cls.GetMethodParameters("Remove"))
{
methodParams["Name"] = new[]{"your_vpn_name"};
methodParams["Force"] = true;
cls.InvokeMethod("Remove", methodParams, null);
}
}
}
Related
I've read the tutorial and I'm able to generate the .cs file but it doesn't include any of my service or rpc definitions.
I've added protoc to my PATH and from inside the project directory.
protoc project1.proto --csharp_out="C:\output" --plugin=protoc-gen-grpc="c:\Users\me\.nuget\packages\grpc.tools\1.8.0\tools\windows_x64\grpc_csharp_plugin.exe"
No errors output in console
You need to add the --grpc_out command line option, e.g. add
--grpc_out="C:\output\"
Note that it won't write any files if you don't have any services.
Here's a complete example. From a root directory, create:
An empty output directory
A tools directory with protoc.exe and grpc_csharp_plugin.exe
A protos directory with test.proto as shown below:
test.proto:
syntax = "proto3";
service StackOverflowService {
rpc GetAnswer(Question) returns (Answer);
}
message Question {
string text = 1;
string user = 2;
repeated string tags = 3;
}
message Answer {
string text = 1;
string user = 2;
}
Then run (all on one line; I've broken it just for readability here):
tools\protoc.exe -I protos protos\test.proto --csharp_out=output
--grpc_out=output --plugin=protoc-gen-grpc=tools\grpc_csharp_plugin.exe
In the output directory, you'll find Test.cs and TestGrpc.cs
Just an idle comment here for other that find this, the documentation about this is terribly out of date and just flat out wrong.
Installing Grpc.Tools does not install anything in a packages folder; that is legacy behaviour which is no longer true even on windows.
When you install Grpc.Tools it will be hidden away in your local package cache, which you can see by calling:
$ dotnet nuget locals all --list
info : http-cache: /Users/doug/.local/share/NuGet/v3-cache
info : global-packages: /Users/doug/.nuget/packages/
info : temp: /var/folders/xx/s2hnzbrj3yn4hp1bg8q9gb_m0000gn/T/NuGetScratch
The binaries you want will be in one of these folders.
The easiest way to do this is to download the Grpc.Tools package directly from nuget, and install it locally.
I've hacked up this little helper script to do that, which works on windows/mac/linux, which may ease the difficulty of getting starting with this for others:
using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Mono.Unix;
namespace BuildProtocol
{
public class Program
{
private const string ToolsUrl = "https://www.nuget.org/api/v2/package/Grpc.Tools/";
private const string Service = "Greeter";
private static string ProtocolPath = Path.Combine("..", "protos");
private static string Protocol = Path.Combine(ProtocolPath, "helloworld.proto");
private static string Output = Path.Combine("..", "Greeter");
public static void Main(string[] args)
{
RequireTools().Wait();
var protoc = ProtocPath();
var plugin = ProtocPluginPath();
Console.WriteLine($"Using: {protoc}");
Console.WriteLine($"Using: {plugin}");
var command = new string[]
{
$"-I{ProtocolPath}",
$"--csharp_out={Output}",
$"--grpc_out={Output}",
$"--plugin=protoc-gen-grpc=\"{plugin}\"",
Protocol,
};
Console.WriteLine($"Exec: {protoc} {string.Join(' ', command)}");
var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
FileName = protoc,
Arguments = string.Join(' ', command)
}
};
process.Start();
process.WaitForExit();
Console.WriteLine($"Completed status: {process.ExitCode}");
}
public static async Task RequireTools()
{
if (!Directory.Exists("Tools"))
{
Console.WriteLine("No local tools found, downloading binaries from nuget...");
Directory.CreateDirectory("Tools");
await DownloadTools();
ExtractTools();
}
}
private static void ExtractTools()
{
ZipFile.ExtractToDirectory(Path.Combine("Tools", "tools.zip"), Path.Combine("Tools", "bin"));
}
private static async Task DownloadTools()
{
using (var client = new HttpClient())
{
Console.WriteLine($"Fetching: {ToolsUrl}");
using (var result = await client.GetAsync(ToolsUrl))
{
if (!result.IsSuccessStatusCode) throw new Exception($"Unable to download tools ({result.StatusCode}), check URL");
var localArchive = Path.Combine("Tools", "tools.zip");
Console.WriteLine($"Saving to: {localArchive}");
File.WriteAllBytes(localArchive, await result.Content.ReadAsByteArrayAsync());
}
}
}
private static string ProtocPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "protoc");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static string ProtocPluginPath()
{
var path = Path.Combine("Tools", "bin", "tools", DetermineArch(), "grpc_csharp_plugin");
RequireExecutablePermission(path);
return WithExeExtensionIfRequired(path);
}
private static void RequireExecutablePermission(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return;
Console.WriteLine($"Ensuring +x on {path}");
var unixFileInfo = new UnixFileInfo(path);
unixFileInfo.FileAccessPermissions = FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute;
}
private static string WithExeExtensionIfRequired(string path)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
path += ".exe";
}
return path;
}
private static string DetermineArch()
{
var arch = RuntimeInformation.OSArchitecture;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return WithArch("windows_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return WithArch("macosx_", arch);
}
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return WithArch("linux_", arch);
}
throw new Exception("Unable to determine runtime");
}
private static string WithArch(string platform, Architecture arch)
{
switch (arch)
{
case Architecture.X64:
return $"{platform}x86";
case Architecture.X86:
return $"{platform}x64";
default:
throw new ArgumentOutOfRangeException(nameof(arch), arch, null);
}
}
}
}
the following approach helped me :
Create a gRPC client and server in ASP.NET Core
in project, where .proto file located, edit the .csproj file
<ItemGroup>
....
<Protobuf Include="Shipping.proto" GrpcServices="Server" />
</ItemGroup>
rebuild the project, the all necessary .cs files will be added automaticaly
\obj\Debug\[TARGET_FRAMEWORK]\Shipping.cs
\obj\Debug\[TARGET_FRAMEWORK]\ShippingGrpc.cs
I have been trying to figure out how is possible to create a query folder via VSO api, but I always the "Method not allowed" message.
I'm using Microsoft.TeamFoundationServer.Client package to connect VSO. This page says that this library is needed for me. I can query data, but it seems something is missing to create data. This library is fit for me because I have a WebApi whihch manages the communication to VSO API.
Here is my code:
public QueryHierarchyItem CreateFolderAsync(string folderName)
{
QueryHierarchyItem newFolder = new QueryHierarchyItem()
{
Name = folderName,
IsFolder = true,
//Path = "Queries/Shared Queries/" + folderName,
IsPublic = true
};
QueryHierarchyItem item = witClient.CreateQueryAsync(newFolder, _projectName, null).Result;
return item;
}
I have tried to play with the Path property but it did not help.
I have checked the user rights. My user is member of "Project Administrators", and
rights are also set up to manage query folders (Click the chevron next to the "Shared Queries" folder -> select "Security") as group and as single user. It did not help.
I use a free account. The strange is that I have logged in with the same user from Visual Studio and I can manage the folders. Is this functionality available for free accounts?
You can refer to this blog from MSDN for details: http://blogs.msdn.com/b/team_foundation/archive/2010/06/16/work-item-tracking-queries-object-model-in-2010.aspx
Quote the code here:
using System;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
namespace QueryAPI
{
class Program
{
private static Project myproject = null;
public static QueryFolder GetMyQueriesFolder()
{
foreach (QueryFolder folder in myproject.QueryHierarchy)
{
if (folder.IsPersonal == true)
return folder;
}
throw new Exception("Cannot find the My Queries folder");
}
public static QueryFolder AddNewFolder(string folderName)
{
QueryFolder folder = new QueryFolder(folderName, GetMyQueriesFolder());
myproject.QueryHierarchy.Save();
return folder;
}
static void Main(string[] args)
{
TfsTeamProjectCollection coll = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("Your TFS Server URI"));
WorkItemStore store = new WorkItemStore(coll);
myproject = store.Projects["Your project name"];
QueryFolder myNewfolder = AddNewFolder("Your folder name");
}
}
}
Iam trying to get the dht implementation of monotorrent to work but i just cant seem to find any peers.
ive tried most of the examplecode code availeble on the net like the testclient and dhttest.
I have tried with several diffrent infohashes.
Anyone here got it working? or do you know where i can find the devs?
This is how my code looks atm:
using System;
using System.Collections.Generic;
using System.Text;
using MonoTorrent.Dht;
using MonoTorrent.Dht.Listeners;
using System.Net;
using System.IO;
using MonoTorrent.Common;
using MonoTorrent.Tracker.Listeners;
namespace SampleClient
{
class Program
{
static void Main(string[] args)
{
string basePath = Environment.CurrentDirectory;
string torrentsPath = Path.Combine(basePath, "Torrents");
Torrent torrent = null;
// If the torrentsPath does not exist, we want to create it
if (!Directory.Exists(torrentsPath))
Directory.CreateDirectory(torrentsPath);
// For each file in the torrents path that is a .torrent file, load it into the engine.
foreach (string file in Directory.GetFiles(torrentsPath))
{
if (file.EndsWith(".torrent"))
{
try
{
// Load the .torrent from the file into a Torrent instance
// You can use this to do preprocessing should you need to
torrent = Torrent.Load(file);
Console.WriteLine(torrent.InfoHash.ToString());
}
catch (Exception e)
{
Console.Write("Couldn't decode {0}: ", file);
Console.WriteLine(e.Message);
continue;
}
}
}
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
DhtEngine engine = new DhtEngine(listener);
//engine.RegisterDht(dht);
byte[] nodes = null;
if (File.Exists("mynodes"))
nodes = File.ReadAllBytes("mynodes");
listener.Start();
int i = 0;
bool running = true;
StringBuilder sb = new StringBuilder(1024);
while (running)
{
engine.Start(nodes);
while (Console.ReadLine() != "q")
{
engine.GetPeers(torrent.InfoHash);
}
File.WriteAllBytes("mynodes", engine.SaveNodes());
}
}
}
}
I know it's very old question, I'm not sure why it's still noone has answer it, anyway. The problem seem to be this line:
DhtListener listener = new DhtListener(new IPEndPoint(IPAddress.Parse("192.168.2.3"), 10000));
This ip is not the real ip, so you actually asl peers to send the respone to unkonw adress.
What to do? register your own adress.
I want to get the current directory path but not of the application location but of it's shortcut location.
I tried these but they return the application's location.
Directory.GetCurrentDirectory();
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]);
According to the process API reference in MSDN, the process STARTUPINFO struct for a given process contains the information about the shortcut .lnk file in the title member. There is a flag present in the dwFlags struct member that is set when this is the case - so it appears that this is not always set (im guessing if you ran the exe directly)
From MSDN:
STARTF_TITLEISLINKNAME: 0x00000800
The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked
to start this process. This is typically set by the shell when a .lnk file pointing to
the launched application is invoked. Most applications will not need to set this value.
This flag cannot be used with STARTF_TITLEISAPPID.
Reference here.
If adding a COM Object reference is not a problem , Add COM Object Reference - Windows Script Host Object Model
i ran this code in my desktop folder and it did work. for current folder use - Environment.CurrentDirectory
using System;
using System.IO;
using IWshRuntimeLibrary; //COM object -Windows Script Host Object Model
namespace csCon
{
class Program
{
static void Main(string[] args)
{
// Folder is set to Desktop
string dir = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
var di = new DirectoryInfo(dir);
FileInfo[] fis = di.GetFiles();
if (fis.Length > 0)
{
foreach (FileInfo fi in fis)
{
if (fi.FullName.EndsWith("lnk"))
{
IWshShell shell = new WshShell();
var lnk = shell.CreateShortcut(fi.FullName) as IWshShortcut;
if (lnk != null)
{
Console.WriteLine("Link name: {0}", lnk.FullName);
Console.WriteLine("link target: {0}", lnk.TargetPath);
Console.WriteLine("link working: {0}", lnk.WorkingDirectory);
Console.WriteLine("description: {0}", lnk.Description);
}
}
}
}
}
}
}
Code Reference from Forum : http://www.neowin.net/forum/topic/658928-c%23-resolve-lnk-files/
Try this:
Environment.CurrentDirectory
From MSDN:
Gets or sets the fully qualified path of the current working directory.
I think you will need to use COM and add a reference to "Microsoft Shell Control And Automation", as described in this blog post:
Here's an example using the code provided there:
namespace Shortcut
{
using System;
using System.Diagnostics;
using System.IO;
using Shell32;
class Program
{
public static string GetShortcutTargetFile(string shortcutFilename)
{
string pathOnly = System.IO.Path.GetDirectoryName(shortcutFilename);
string filenameOnly = System.IO.Path.GetFileName(shortcutFilename);
Shell shell = new Shell();
Folder folder = shell.NameSpace(pathOnly);
FolderItem folderItem = folder.ParseName(filenameOnly);
if (folderItem != null)
{
Shell32.ShellLinkObject link = (Shell32.ShellLinkObject)folderItem.GetLink;
return link.Path;
}
return string.Empty;
}
static void Main(string[] args)
{
const string path = #"C:\link to foobar.lnk";
Console.WriteLine(GetShortcutTargetFile(path));
}
}
}
using System.Reflection;
string currentAssemblyDirectoryName = Path.GetDirectoryName(
Assembly.GetExecutingAssembly()
.Location
);
Also for webapplications you can use:
Web Applications:
Request.PhysicalApplicationPath
http://msdn.microsoft.com/en-us/library/system.web.httprequest.physicalapplicationpath.aspx
to grap the applicationpath :)
Since creating the shortcut is part of the workflow, just set the working directory to "%cd%" for the shortcut then, in the app, use:
Environment.CurrentDirectory
Obviously, you would want to capture this value before any code your app calls can change it.
When creating a shortcut using Windows Explorer, you don't have the option of setting the working directory. So, after creating it, open its property page by right-clicking on it and selecting Properties, then set the Start in field to %cd%. After creating such a shortcut, you can move or copy it to the folders in which you want the app to run.
If you do not want to use a COM object as suggested in the other answers
You can open the file as a regular text file, split on the \x00 0 char, and inspect the resulting string array. One of them will be obviously the link target: something like "C:\path\to\file" or in case of UNC "\\computers\path\to\file".
string lnkFilePath "...";
var file = System.IO.File.ReadAllText(lnkFilePath);
var contents = Regex.Split(file, "[\x00]+");
var paths = contents.Where(line => Regex.IsMatch(line, #"^([A-Z]:\\|^\\\\)\S+.*?"));
Use GetStartupInfoW, it will tell you the .lnk file that was launched to start the program.
I have a library that handles reading and writing a cache file. This library is used by a Windows Service and several instances of a console application on the same machine. The console application runs when a user logs in.
I am getting occasional IO errors saying the cache file is in use by another process. I assume that collisions are occurring between the different application instances and service trying to read and write at the same time.
Is there a way to lock the file when it is in use and force all other requests to "wait in line" to access the file?
private void SaveCacheToDisk(WindowsUser user) {
string serializedCache = SerializeCache(_cache);
//encryt
serializedCache = AES.Encrypt(serializedCache);
string path = user == null ? ApplicationHelper.CacheDiskPath() :
_registry.GetCachePath(user);
string appdata = user == null ? ApplicationHelper.ClientApplicationDataFolder() :
_registry.GetApplicationDataPath(user);
if (Directory.Exists(appdata) == false) {
Directory.CreateDirectory(appdata);
}
if (File.Exists(path) == false) {
using (FileStream stream = File.Create(path)) { }
}
using (FileStream stream = File.Open(path, FileMode.Truncate)) {
using (StreamWriter writer = new StreamWriter(stream)) {
writer.Write(serializedCache);
}
}
}
private string ReadCacheFromDisk(WindowsUser user) {
//cache file path
string path = user == null ? ApplicationHelper.CacheDiskPath() :
_registry.GetCachePath(user);
using (FileStream stream = File.Open(path, FileMode.Open)) {
using (StreamReader reader = new StreamReader(stream)) {
string serializedCache = reader.ReadToEnd();
//decrypt
serializedCache = AES.Decrypt(serializedCache);
return serializedCache;
}
}
}
Sure, you could use a mutex and permit access only when holding the mutex.
You could use a cross-process EventWaitHandle. This lets you create and use a WaitHandle that's identified across processes by name. A thread is notified when it's its turn, does some work, and then indicates it's done allowing another thread to proceed.
Note that this only works if every process/thread is referring to the same named WaitHandle.
The EventWaitHandle constructors with strings in their signature create named system synchronization events.
One option you could consider is having the console applications route their file access through the service, that way there's only one process accessing the file and you can synchronise access to it there.
One way of implementing this is by remoting across an IPC channel (and here's another example from weblogs.asp.net). We used this technique in a project for the company I work for and it works well, with our specific case providing a way for a .net WebService to talk to a Windows Service running on the same machine.
Sample based on the weblogs.asp.net example
Basically what you need to do with the code below is create a Solution, add two Console Apps (one called "Server" and the other called "Client" and one Library to it. Add a reference to the Library to both console apps, paste the code below in and add a reference to System.Runtime.Remoting to both Server & Console.
Run the Server app, then run the client app. Observe the fact that the server app has a message passed to it by the client. You can extend this to any number of messages/tasks
// Server:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
namespace RemotingSample
{
public class Server
{
public Server()
{
}
public static int Main(string[] args)
{
IpcChannel chan = new IpcChannel("Server");
//register channel
ChannelServices.RegisterChannel(chan, false);
//register remote object
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemotingSample.RemoteObject),
"RemotingServer",
WellKnownObjectMode.SingleCall);
Console.WriteLine("Server Activated");
Console.ReadLine();
return 0;
}
}
}
// Client:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using RemotingSample;
namespace RemotingSample
{
public class Client
{
public Client()
{
}
public static int Main(string[] args)
{
IpcChannel chan = new IpcChannel("Client");
ChannelServices.RegisterChannel(chan);
RemoteObject remObject = (RemoteObject)Activator.GetObject(
typeof(RemotingSample.RemoteObject),
"ipc://Server/RemotingServer");
if (remObject == null)
{
Console.WriteLine("cannot locate server");
}
else
{
remObject.ReplyMessage("You there?");
}
return 0;
}
}
}
// Shared Library:
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
namespace RemotingSample
{
public class RemoteObject : MarshalByRefObject
{
public RemoteObject()
{
Console.WriteLine("Remote object activated");
}
public String ReplyMessage(String msg)
{
Console.WriteLine("Client : " + msg);//print given message on console
return "Server : I'm alive !";
}
}
}
Check out the TextWriter.Synchronized method.
http://msdn.microsoft.com/en-us/library/system.io.textwriter.synchronized.aspx
This should let you do this:
TextWriter.Synchronized(writer).Write(serializedCache);