I've a WPF application written in c# that use microphone device with naudio libraries, which on Windows 10 update build 1803 has added privacy setting to access at microphone.
If user has allow privacy flag, my application work fine otherwise my application not working. So how can I to check this privacy setting by c#?
There doesn't seem to be a direct way to figure out whether your application has these permissions, so your best option is to try to access the microphone and catch the error when it occurs.
try
{
// code to access microphone
}
catch (System.UnauthorizedAccessException e)
{
// notify user application can't work without microphone permission
}
To my knowledge, this is one way to solve it. Unfortunately it might catch other errors not related to the Microphone Privacy Settings.
/// <summary>
/// With Windows 10 update 1803 came an option to deny access to the microphones on an OS level.
/// The option covers all soundcards installed into the PC (Magnum/Callisto is a soundcard)
/// </summary>
public static class MicrophonePrivacyProbe
{
/// <summary>
/// Test if Microphone Privacy Settings are to restrictive for microphone access.
/// </summary>
/// <returns>True if microphone is accessible</returns>
public static bool Allowed()
{
bool access = false;
var devices = new CaptureDevicesCollection();
if ( devices?.Count <= 0 ) return false;
var captureDevice = new Capture(devices[0].DriverGuid);
CaptureBuffer applicationBuffer = null;
var inputFormat = new WaveFormat();
inputFormat.AverageBytesPerSecond = 8000;
inputFormat.BitsPerSample = 8;
inputFormat.BlockAlign = 1;
inputFormat.Channels = 1;
inputFormat.FormatTag = WaveFormatTag.Pcm;
inputFormat.SamplesPerSecond = 8000;
CaptureBufferDescription bufferdesc = new CaptureBufferDescription();
bufferdesc.BufferBytes = 200;
bufferdesc.Format = inputFormat;
try
{
applicationBuffer = new CaptureBuffer(bufferdesc, captureDevice);
access = true;
}
catch (SoundException e)
{
}
finally
{
applicationBuffer?.Dispose();
captureDevice?.Dispose();
}
return access;
}
}
Related
I want to kill a running IIS Instance programmatically that is occupying a specific port, but it seems there is no way to figure out what IIS Instance is using a specific port.
netstat.exe just shows that the process is having the PID 4, but that's the system process. "netsh http show urlacl" does not display the occupied port at all.
The IIS Express Tray program knows this somehow. When I try to start another IIS Express instance while the port is occupied I get the following error:
"Port '40000' is already being used by process 'IIS Express' (process ID '10632').
Anyone got a clue how I can get this information?
It seems like the PID is 4 (System) because the actual listening socket is under a service called http.
I looked at what iisexpresstray.exe was using to provide a list of all running IISExpress applications. Thankfully it's managed .NET code (all in iisexpresstray.dll) that's easily decompiled.
It appears to have at least three different ways of getting the port number for a process:
Reading /port from the command-line arguments (unreliable as we know)
Running netsh http show servicestate view=requestq and parsing the output
Calling Microsoft.Web.RuntimeStatusClient.GetWorkerProcess(pid) and parsing the site URL
Unfortunately, most of the useful stuff in iisexpresstray.dll like the IisExpressHelper class is declared internal (although I imagine there're tools to generate wrappers or copy the assembly and publicize everything).
I opted to use Microsoft.Web.dll. It was in my GAC, though for some reason wasn't appearing in the list of assemblies available to add as a reference in Visual Studio, so I just copied the file out from my GAC. Once I had Microsoft.Web.dll it was just a matter of using this code:
using (var runtimeStatusClient = new RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetWorkerProcess(process.Id);
// Apparently an IISExpress process can run multiple sites/applications?
var apps = workerProcess.RegisteredUrlsInfo.Select(r => r.Split('|')).Select(u => new { SiteName = u[0], PhysicalPath = u[1], Url = u[2] });
// If we just assume one app
return new Uri(apps.FirstOrDefault().Url).Port;
}
You can also call RuntimeClient.GetAllWorkerProcesses to retrieve only actual worker processes.
I looked into RegisteredUrlsInfo (in Microsoft.Web.dll) as well and found that it's using two COM interfaces,
IRsca2_Core (F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD)
IRsca2_WorkerProcess (B1341209-7F09-4ECD-AE5F-3EE40D921870)
Lastly, I read about a version of Microsoft.Web.Administration apparently being able to read IISExpress application info, but information was very scarce, and the one I found on my system wouldn't even let me instantiate ServerManager without admin privileges.
Here is a C# implementation of calling netsh.exe as recommended within the answer by #makhdumi:
Usage:
static public bool TryGetCurrentProcessRegisteredHttpPort(out List<int> ports, out Exception ex)
{
NetshInvoker netsh = new NetshInvoker();
return netsh.TryGetHttpPortUseByProcessId(Process.GetCurrentProcess().Id, out ports, out ex);
}
Implementation:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace YourCompanyName.Server.ServerCommon.Utility
{
/// <summary>
/// Invoke netsh.exe and extract information from its output.
/// Source: #crokusek, https://stackoverflow.com/questions/32196188
/// #GETah, https://stackoverflow.com/a/8274758/538763
/// </summary>
public class NetshInvoker
{
const string NetshHttpShowServiceStateViewRequestqArgs = "http show servicestate view=requestq";
public NetshInvoker()
{
}
/// <summary>
/// Call netsh.exe to determine the http port number used by a given windowsPid (e.g. an IIS Express process)
/// </summary>
/// <param name="windowsPid">For example an IIS Express process</param>
/// <param name="port"></param>
/// <param name="ex"></param>
/// <returns></returns>
public bool TryGetHttpPortUseByProcessId(Int32 windowsPid, out List<Int32> ports, out Exception ex)
{
ports = null;
try
{
if (!TryQueryProcessIdRegisteredUrls(out Dictionary<Int32, List<string>> pidToUrlMap, out ex))
return false;
if (!pidToUrlMap.TryGetValue(windowsPid, out List<string> urls))
{
throw new Exception(String.Format("Unable to locate windowsPid {0} in '{1}' output.",
windowsPid, "netsh " + NetshHttpShowServiceStateViewRequestqArgs));
}
if (!urls.Any())
{
throw new Exception(String.Format("WindowsPid {0} did not reference any URLs in '{1}' output.",
windowsPid, "netsh " + NetshHttpShowServiceStateViewRequestqArgs));
}
ports = urls
.Select(u => new Uri(u).Port)
.ToList();
return true;
}
catch (Exception ex_)
{
ex = ex_;
return false;
}
}
private bool TryQueryProcessIdRegisteredUrls(out Dictionary<Int32, List<string>> pidToUrlMap, out Exception ex)
{
if (!TryExecNetsh(NetshHttpShowServiceStateViewRequestqArgs, out string output, out ex))
{
pidToUrlMap = null;
return false;
}
bool gotRequestQueueName = false;
bool gotPidStart = false;
int currentPid = 0;
bool gotUrlStart = false;
pidToUrlMap = new Dictionary<int, List<string>>();
foreach (string line in output.Split('\n').Select(s => s.Trim()))
{
if (!gotRequestQueueName)
{
gotRequestQueueName = line.StartsWith("Request queue name:");
}
else if (!gotPidStart)
{
gotPidStart = line.StartsWith("Process IDs:");
}
else if (currentPid == 0)
{
Int32.TryParse(line, out currentPid); // just get the first Pid, ignore others.
}
else if (!gotUrlStart)
{
gotUrlStart = line.StartsWith("Registered URLs:");
}
else if (line.ToLowerInvariant().StartsWith("http"))
{
if (!pidToUrlMap.TryGetValue(currentPid, out List<string> urls))
pidToUrlMap[currentPid] = urls = new List<string>();
urls.Add(line);
}
else // reset
{
gotRequestQueueName = false;
gotPidStart = false;
currentPid = 0;
gotUrlStart = false;
}
}
return true;
}
private bool TryExecNetsh(string args, out string output, out Exception exception)
{
output = null;
exception = null;
try
{
// From #GETah, https://stackoverflow.com/a/8274758/538763
Process p = new Process();
p.StartInfo.FileName = "netsh.exe";
p.StartInfo.Arguments = args;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
output = p.StandardOutput.ReadToEnd();
return true;
}
catch (Exception ex)
{
exception = ex;
return false;
}
}
}
}
In my case I just output "Command line" column in Task manager and it's getting obvious, which IISExpress is that:
You can run below command to get the information of the executable and its PID
netstat -a -n -o -b | find "iisexpress.exe"
Hi Stack Overflow and sorry for my non-native English level
Currently programming an UPnP discovery service for a project in C# using .NET 4.0 on Visual Studio 2010.
I'm using the official Microsoft UPnP COM API and it's my first time using UPnP. My problem is that I'm trying to iterate on the services of the devices discovered by the library and a COM HRESUT:0X80040500 exception is thrown.
Here is a sample of my code:
IList<UpnpDevice> result = new List<UpnpDevice>();
UPnPDevices upnpDiscoveryResult = m_UPnPFinder.FindByType(upnpType, 0);
var upnpDiscoveryResultEnumerator = upnpDiscoveryResult.GetEnumerator();
while (upnpDiscoveryResultEnumerator.MoveNext())
{
var upnpDiscoveryDevice = (IUPnPDevice)upnpDiscoveryResultEnumerator.Current;
UPnPServices services = upnpDiscoveryDevice.Services;
var allServices = services.GetEnumerator();
// ------ Exception is thrown just below
while (allServices.MoveNext())
{
UPnPService service = allServices.Current as UPnPService;
if (service.Id == "urn:schemas-upnp-org:service:WANIPConnection:1")
{
}
else if (service.Id == "urn:schemas-upnp-org:service:WANPPPConnection:1")
{
}
}
I am lost on what to do.
According to these people which I think I may be having the same error...
How do I access services of UPnP device?
http://social.msdn.microsoft.com/Forums/en-US/b16a1e3b-9e85-480a-8240-82a2af73b924/could-not-iterate-upnp-services-of-a-device-using-microsoft-upnpdll)
...the problem may come from the official DLL and I guess I should better use a new one, but I wanted to ask here first. It seems weird to me that such an obvious bug could indeed come from the API.
I'll answer my own question for posterity, with "UpnpDevice " being a class in my own project.
/// <summary>
/// Converts the native class UPnP device to a generic UPnP device.
/// </summary>
/// <param name="nativeDevice">The native device.</param>
/// <returns>
/// The converted <see cref="UpnpDevice"/>
/// </returns>
private UpnpDevice ConvertNativeUPnPDeviceToGenericUpnpDevice(IUPnPDevice nativeDevice)
{
UpnpDevice genericDevice = null;
if (nativeDevice != null)
{
IList<UpnpDevice> genericDeviceChildren = new List<UpnpDevice>();
IList<String> genericDeviceServices = new List<String>();
// Converting recursively the children of the native device
if (nativeDevice.HasChildren)
{
foreach (IUPnPDevice nativeDeviceChild in nativeDevice.Children)
{
genericDeviceChildren.Add(ConvertNativeUPnPDeviceToGenericUpnpDevice(nativeDeviceChild));
}
}
try
{
// Converting the services, it may break on some modems like old Orange Liveboxes thus the try/catch
foreach (IUPnPService nativeDeviceService in nativeDevice.Services)
{
genericDeviceServices.Add(nativeDeviceService.ServiceTypeIdentifier);
}
}
catch (Exception exception)
{
string msg = this.GetType().Name + " - Method ConvertNativeUPnPDeviceToGenericUpnpDevice - Reading the services threw an exception: " + exception.Message;
m_Logger.Error(msg);
}
genericDevice = new UpnpDevice(nativeDevice.UniqueDeviceName,
nativeDevice.Description,
nativeDevice.FriendlyName,
nativeDevice.HasChildren,
nativeDevice.IsRootDevice,
nativeDevice.ManufacturerName,
nativeDevice.ManufacturerURL,
nativeDevice.ModelName,
nativeDevice.ModelNumber,
nativeDevice.ModelURL,
nativeDevice.PresentationURL,
nativeDevice.SerialNumber,
nativeDevice.Type,
nativeDevice.UPC,
genericDeviceServices,
genericDeviceChildren);
}
return genericDevice;
}
Not an exceptionnal answer, but it was the only way for me to get all the services from the device. It will frown on some devices and move on, but at least it'll get all it can without breaking the whole discovery.
This code works well on Windows 7, but not on Windows 8. Does anyone know why?
I don't know how to solve it.
The function to restart network
private static void RestartNetWork()
{
string manage = "SELECT * FROM Win32_NetworkAdapter";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(manage);
ManagementObjectCollection collection = searcher.Get();
List<string> netWorkList = new List<string>();
foreach (ManagementObject obj in collection)
{
if (obj["Name"].ToString() == "Qualcomm Atheros AR5B97 Wireless Network Adapter")
{
DisableNetWork(obj);//disable network
Thread.Sleep(3000);
EnableNetWork(obj);//enable network
return;
}
}
}
The function to disable the network
/// <summary>
/// 禁用网卡
/// </summary>5
/// <param name="netWorkName">网卡名</param>
/// <returns></returns>
private static bool DisableNetWork(ManagementObject network)
{
try
{
network.InvokeMethod("Disable", null);
return true;
}
catch
{
return false;
}
}
The function to enable the network
/// <summary>
/// 启用网卡
/// </summary>
/// <param name="netWorkName">网卡名</param>
/// <returns></returns>
private static bool EnableNetWork(ManagementObject network)
{
try
{
network.InvokeMethod("Enable", null);
return true;
}
catch
{
return false;
}
}
Assuming you are using the Win32_NetworkAdapter WMI class, make sure the current process is running in elevated mode. On top of that, you may want to just avoid catching every exception like you are doing and, instead, analyze the eventual exception which may be thrown, for additional details.
my code works well in Windows 10 so i think win8 is available but remember that it needs administrator permission please remember run as admin by right click .
here is my code:
if (manage["Name"].ToString() == "Realtek RTL8192DE Wireless LAN 802.11N PCI-E NIC MAC1")
{
Console.WriteLine(manage["Name"].ToString() + "\n");
try
{
//先enable再disable且要管理员权限执行
manage.InvokeMethod("Enable", null);
manage.InvokeMethod("Disable", null);
Console.WriteLine("设置成功");
}
catch
{
Console.WriteLine("设置失败");
}
}
}
I found the answer to my comment and wanted to share for anyone having similar problems...
Rather than "Enabling" the service, I changed the start mode to manual (you can use automatic if you prefer as well) and that solved my issue.
ManagementBaseObject startMode = service.GetMethodParameters("ChangeStartMode");
startMode["startmode"] = "Manual";
service.InvokeMethod("ChangeStartMode", startMode, null);
This did the trick for me!
I've just had the same issue. It turns out that when the same app I run as an administrator in Windows 8, everything started to work properly.
Win32_NetworkAdapter is deprecated. For Windows 8 / Server 2012 and forward you need to use MSFT_NetAdapter.
https://msdn.microsoft.com/en-us/library/hh968170(v=vs.85).aspx
Statement:
"The Win32_NetworkAdapter class is deprecated. Use the MSFT_NetAdapter class instead."
https://msdn.microsoft.com/en-us/library/aa394216%28v=vs.85%29.aspx
Azure is changing so quickly so could someone give me some suggestions on how could I could log:
Errors
Exceptions
User Actions
I would like to be able to log these to table storage so they can be retrieved with code and viewed on administrative web pages. I am not looking so much for code but what I really want is to know where I should look. Azure changes so fast I want to be sure to use what's best.
Thank you
Azure has built in functionality logging and tracing, see
http://msdn.microsoft.com/en-us/magazine/ff714589.aspx
for more information on the subject.
Here is how I have used Azure diagnostics myself:
Code:
using System;
using Microsoft.WindowsAzure.Diagnostics;
namespace CrossCuttingConcerns
{
/// <summary>
/// This class handles diagnostics and stores the logs in the Azure table and blog storage.
/// Note: Basically all logs are turned on here, this can be expensive and you may want to change several settings here before going live
/// </summary>
public class AzureDiagnostics
{
/// <summary>
/// Sets how often diagnostics data is transferred to the Azure table storage or blob storage
/// Note: Change to a period that fits your need, commenting out one of these lines disables it
/// </summary>
/// <param name="diagnosticMonitorConfiguration"></param>
void SetDiagnositcManagerScheduledTransferPeriods(DiagnosticMonitorConfiguration diagnosticMonitorConfiguration)
{
diagnosticMonitorConfiguration.Directories.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
diagnosticMonitorConfiguration.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
diagnosticMonitorConfiguration.WindowsEventLog.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
diagnosticMonitorConfiguration.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
diagnosticMonitorConfiguration.PerformanceCounters.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);
}
/// <summary>
/// Will add a full crashdump.
/// Note: Full crashdumps are not available in asp.net roles
/// </summary>
void AddFullCrashDumps()
{
CrashDumps.EnableCollection(true);
}
/// <summary>
/// Enables performance counters
/// Note: PerformanceCounterConfiguration.CounterSpecifier is language specific and depends on your OS language.
/// Note: For a complete list of possible PerformanceCounterConfiguration.CounterSpecifier values run "typeperf.exe /Q"
/// </summary>
/// <param name="diagnosticMonitorConfiguration"></param>
void AddPerformanceCounterMonitoring(DiagnosticMonitorConfiguration diagnosticMonitorConfiguration)
{
var performanceCounterConfiguration =
new PerformanceCounterConfiguration
{
CounterSpecifier = #"\Processor(*)\% Processor Time",
SampleRate = TimeSpan.FromSeconds(15)
};
diagnosticMonitorConfiguration.PerformanceCounters.DataSources.Add(performanceCounterConfiguration);
}
/// <summary>
/// By default all Windows events to the Application and System logs are stored in the Azure table storage
/// Note: Decide here what Windows event logs you are interested in seeing, you can also filter out events
/// </summary>
/// <param name="diagnosticMonitorConfiguration"></param>
void AddEventLoggingFromWindowsEventLog(DiagnosticMonitorConfiguration diagnosticMonitorConfiguration)
{
// Syntax: <channel>!XPath Query
// See: http://msdn.microsoft.com/en-us/library/dd996910(VS.85).aspx
diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("Application!*");
diagnosticMonitorConfiguration.WindowsEventLog.DataSources.Add("System!*");
}
void StartDiagnosticManager(DiagnosticMonitorConfiguration diagnosticMonitorConfiguration)
{
DiagnosticMonitor.Start("DiagnosticsConnectionString", diagnosticMonitorConfiguration);
}
public void EnableAzureDiagnostics()
{
var diagnosticMonitorConfiguration = DiagnosticMonitor.GetDefaultInitialConfiguration();
SetDiagnositcManagerScheduledTransferPeriods(diagnosticMonitorConfiguration);
AddFullCrashDumps();
AddPerformanceCounterMonitoring(diagnosticMonitorConfiguration);
AddEventLoggingFromWindowsEventLog(diagnosticMonitorConfiguration);
StartDiagnosticManager(diagnosticMonitorConfiguration);
}
}
}
Config:
<system.diagnostics>
<trace>
<listeners>
<add type="Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="AzureDiagnostics">
</add>
</listeners>
</trace>
</system.diagnostics>
There have been further changes to Azure logging....
Logging via Trace.TraceXXXX (e.g. Trace.TraceInformation) will now be logged to the Windows Azure file system (~\LogFiles\Application*.txt).
You'll need to get ftp access to the Web Site (enable via Azure Management Portal/Dashboard/Deployment Credentials) to see these files.
Logging must first be enabled from the Settings page of the Web site which you can access either from Visual Studio (Server Explorer/Windows Azure Web Sites/Site Name/View Settings) or from the Azure Management Portal (under Configure/Application Diagnostics/Application Logging).
These logs can also been seen from the live Windows web Azure site from the Visual Studio Output Window (make sure you select "Windows Azure Logs - xxx" in the "Show Output From" dropdown) if you right click on the web site in the Visual Studio Server Explorer (under Windows Azure Web Sites) and select "View Streaming Logs in Output Window".
Logging to the Visual Studio Output window is covered in Scott Gu blog (http://weblogs.asp.net/scottgu/archive/2013/04/30/announcing-the-release-of-windows-azure-sdk-2-0-for-net.aspx)
NB: I've only tried this in VS2012. Not sure if it also works in VS2010.
I just did something similar on the weekend. I ended up just creating 1 table called "LogEvents" and used the provider key to separate the different types of log events and dates (e.g. the ProviderKey = "20111121_LoginEvent" when someone logged in on 21 Nov).
For me the queries can then be done quite easily on date/type and display the result on an admin page
Not sure if this is the best way but it seems to be working for me. I did search Google but couldn't find anything that really did this.
Update 1:
The class I use is called LogEvent:
public class LogEntry : TableServiceEntity
{
public LogEntry(string logType)
{
if (LogType == null || LogType.Length == 0)
{
if (logType.Length > 0)
LogType = logType;
else
LogType = "Default";
}
PartitionKey = string.Format("{0}_{1}", LogType, DateTime.UtcNow.ToString("yyyyMMdd"));
RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
}
public LogEntry()
{
}
public string Message { get; set; }
public DateTime LogDateTime { get; set; }
public string LogType { get; set; }
}
I just create a new instance of it and set the properties:
LogEntry le = new LogEntry("Default") { Message = "Default Page Loaded", LogDateTime=DateTime.Now };
LogEntryDataSource ds = new LogEntryDataSource();
ds.AddLogEntry(le);
To get the data back out again I just use a standard Linq query and pass in the date and LogType:
public IEnumerable<LogEntry> GetLogEntries(string eventType, DateTime logDate)
{
var results = from g in this.context.LogEntry
where g.PartitionKey == String.Format("{0}_{1}", eventType, logDate.ToString("yyyyMMdd"))
select g;
return results;
}
There's probably a better way but this was pretty simple to setup and it's working for me
Is there a way to automate the turning on or off of a Receive Location in BizTalk? It seems like there should be some kind of API or some such for this kind of thing. I would prefer to work in C#, but WMI or some kind of script would work too.
Besides ExplorerOM, as you've found out, you can also enable/disable receive locations (and control send ports) using WMI.
I have a sample PowerShell script that shows how to do those things here, if you're interested.
I found a solution. It appears that the Microsoft.BizTalk.ExplorerOM.dll is what I wanted. Here is an excerpt from the BizTalk documentation that should get anyone else started:
using System;
using Microsoft.BizTalk.ExplorerOM;
public static void EnumerateOrchestrationArtifacts()
{
// Connect to the local BizTalk Management database
BtsCatalogExplorer catalog = new BtsCatalogExplorer();
catalog.ConnectionString = "Server=.;Initial Catalog=BizTalkMgmtDb;Integrated Security=SSPI;";
// Enumerate all orchestrations and their ports/roles
Console.WriteLine("ORCHESTRATIONS: ");
foreach(BtsAssembly assembly in catalog.Assemblies)
{
foreach(BtsOrchestration orch in assembly.Orchestrations)
{
Console.WriteLine(" Name:{0}\r\n Host:{1}\r\n Status:{2}",
orch.FullName, orch.Host.Name, orch.Status);
// Enumerate ports and operations
foreach(OrchestrationPort port in orch.Ports)
{
Console.WriteLine("\t{0} ({1})",
port.Name, port.PortType.FullName);
foreach(PortTypeOperation operation in port.PortType.Operations)
{
Console.WriteLine("\t\t" + operation.Name);
}
}
// Enumerate used roles
foreach(Role role in orch.UsedRoles)
{
Console.WriteLine("\t{0} ({1})",
role.Name, role.ServiceLinkType);
foreach(EnlistedParty enlistedparty in role.EnlistedParties)
{
Console.WriteLine("\t\t" + enlistedparty.Party.Name);
}
}
// Enumerate implemented roles
foreach(Role role in orch.ImplementedRoles)
{
Console.WriteLine("\t{0} ({1})",
role.Name, role.ServiceLinkType);
}
}
}
}
One caveat, apparently this dll does not support 64 bit. Since I am only writing a simple utility it's not a big deal for me (just compiling as 32-bit), but it is something to be aware of.
Glad to see that you seem to have found a solution.
Wanted to mention a similar alternative which is also using Powershell, ExplorerOM, and the BizTalk API to set BizTalk artifacts to various statuses.
Receive Locations being one of them.
The script accepts XML configuration files, where you list the artifacts and what status you would like to set them to.
The script has been published to Microsoft Script Center:
http://gallery.technet.microsoft.com/scriptcenter/Set-Artifact-Status-270f43a0
In response to Alhambraeidos comment. Here's is some excerpts of code I used in a Windows app to disable a Receive Location remotely:
/// <summary>
/// Gets or sets the biz talk catalog.
/// </summary>
/// <value>The biz talk catalog.</value>
private BtsCatalogExplorer BizTalkCatalog { get; set; }
/// <summary>
/// Initializes the biz talk artifacts.
/// </summary>
private void InitializeBizTalkCatalogExplorer()
{
// Connect to the local BizTalk Management database
BizTalkCatalog = new BtsCatalogExplorer();
BizTalkCatalog.ConnectionString = "server=BiztalkDbServer;database=BizTalkMgmtDb;integrated security=true";
}
/// <summary>
/// Gets the location from biz talk.
/// </summary>
/// <param name="locationName">Name of the location.</param>
/// <returns></returns>
private ReceiveLocation GetLocationFromBizTalk(string locationName)
{
ReceivePortCollection receivePorts = BizTalkCatalog.ReceivePorts;
foreach (ReceivePort port in receivePorts)
{
foreach (ReceiveLocation location in port.ReceiveLocations)
{
if (location.Name == locationName)
{
return location;
}
}
}
throw new ApplicationException("The following receive location could not be found in the BizTalk Database: " + locationName);
}
/// <summary>
/// Turns the off receive location.
/// </summary>
/// <param name="vendorName">Name of the vendor.</param>
public void TurnOffReceiveLocation(string vendorName)
{
ReceiveLocation location = Locations[vendorName].ReceiveLocation;
location.Enable = false;
BizTalkCatalog.SaveChanges();
}
You'll notice that there is some I left out, like I was creating a dictionary of receive locations called "Locations", but you should be able to get the idea. The pattern pretty much holds true for any BizTalk object you want to interact with.