I scanned through my local home network using Bonjour 1.0(.NET) for services with regtype = "_http._tcp":
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
DNSSDService browse = service.Browse(0, 0, "_http._tcp", null, eventManager);
When I find the service the method: static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain) is invoked.
Then in that method I want to use method: DNSSDService GetAddrInfo(DNSSDFlags glags, uint ifIndex, DNSSDAddressFamily addressFamily,string hostname, DNSSDEventManager eventManager) to get to know service's ip address and port.
The problem is that I do not know know what string hostname should be and thus I do not get any results: ** Please look at the: ???WHAT HERE?? in the code**
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain) {
Console.WriteLine("browser: " + browser + "\nDNSSDFlags " + flags+ "\nifIndex " + ifIndex +"\nserviceName: " + serviceName + "\nregtype: " +regtype+ "\ndomain: "+ domain);
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.AddressFound += new _IDNSSDEvents_AddressFoundEventHandler(eventManager_AddressFound);
DNSSDAddressFamily family = new DNSSDAddressFamily();
browser.GetAddrInfo(flags, ifIndex, family, ???WHAT HERE???, eventManager);
}
private static void eventManager_AddressFound(DNSSDService service, DNSSDFlags flags, uint ifIndex, string hostname, DNSSDAddressFamily addressFamily, string address, uint ttl) {
Console.WriteLine("----------------------------------------");
Console.WriteLine("FOUND THE ADDRESS");
Console.WriteLine("----------------------------------------");
}
Output:
browser: System.__ComObject
DNSSDFlags 2
ifIndex 32
serviceName: AXIS M1011-W - 00408CBEEAE5
regtype: _http._tcp.
domain: local.
Full code:
using Bonjour;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1 {
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
DNSSDService service = new DNSSDService();
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
// DNSSDService browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
DNSSDService browse = service.Browse(0, 0, "_http._tcp", null, eventManager);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain) {
Console.WriteLine("browser: " + browser + "\nDNSSDFlags " + flags+ "\nifIndex " + ifIndex +"\nserviceName: " + serviceName + "\nregtype: " +regtype+ "\ndomain: "+ domain);
DNSSDEventManager eventManager = new DNSSDEventManager();
eventManager.AddressFound += new _IDNSSDEvents_AddressFoundEventHandler(eventManager_AddressFound);
DNSSDAddressFamily family = new DNSSDAddressFamily();
browser.GetAddrInfo(flags, ifIndex, family, ?????WHAT HERE?????, eventManager);
}
private static void eventManager_AddressFound(DNSSDService service, DNSSDFlags flags, uint ifIndex, string hostname, DNSSDAddressFamily addressFamily, string address, uint ttl) {
Console.WriteLine("----------------------------------------");
Console.WriteLine("FOUND ADDRESS");
Console.WriteLine("----------------------------------------");
}
}
}
Something that I'd check first is the TXT record associated with the _http._tcp record. From the screenshot you have the _axis-video._tcp selected and it shows you the macaddress associated with it. Many _http._tcp entries record the url needed to get to it, or the port/ipaddress needed. I'd dig into that first.
Otherwise you may have to resolve the macaddress into an ipaddress. I googled and come with http://www.mostthingsweb.com/2011/11/reading-arp-entries-with-c/
Related
I have done a virtual printer by using some sample code. But I don't know how to get data from it when it starts printing.
When it starts printing It gives notification that ERROR IN PRITNING.
And Why there is "C:/MyLocalPort.txt".
Anyone Help me to get data this virtual printer sets to print.
Here is the Sample Code:
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Management;
namespace virtualPrinter
{
public static class PrinterClass // class which carries SetDefaultPrinter function
{
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool SetDefaultPrinter(string Printer);
}
class myPrinterClass
{
public static void getPrinterNames()
{
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
MessageBox.Show(printer);
}
}
public static void installPrinter(string printerName) //works on win 7,8,8.1,10 on both x84 and x64
{
Winspool.AddLocalPort(#"C:\MyLocalPort.txt");
//https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/rundll32-printui
// /if Installs a printer by using an .inf file.
// /b[name] Specifies the base printer name.
// /#[file] Specifies a command-line argument file and directly inserts the text in that file into the command line.
// /f[file] Species the Universal Naming Convention (UNC) path and name of the .inf file name or the output file name, depending on the task that you are performing. Use /F[file] to specify a dependent .inf file.
// /r[port] Specifies the port name.
// /m[model] Specifies the driver model name. (This value can be specified in the .inf file.)
string arg;
arg = "printui.dll , PrintUIEntry /if /b " + "\"" + printerName + "\"" + #" /f C:\Windows\inf\ntprint.inf /r " + "\"" + #"C:\MyLocalPort.txt" + "\"" + " /m " + "\"" + "Generic / Text Only" + "\""; //initial arg
ProcessStartInfo p = new ProcessStartInfo();
p.FileName = "rundll32.exe";
p.Arguments = arg;
p.WindowStyle = ProcessWindowStyle.Hidden;
try
{
Process.Start(p);
MessageBox.Show(printerName + " installed succesfully!");
}
catch (Exception ex)
{
MessageBox.Show("Something went wrong. Try again!" );
}
}
public static bool printerExists(string printerName)
{
bool res = false;
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
if (printer == printerName)
{
res = true;
}
}
return res;
}
public static void uninstallPrinter(string printerName)
{
string arg;
ProcessStartInfo p = new ProcessStartInfo();
arg = "printui.dll, PrintUIEntry /dl /n " + "\"" + printerName + "\"";
if (printerExists(printerName))
{
p.FileName = "rundll32.exe";
p.Arguments = arg;
p.WindowStyle = ProcessWindowStyle.Hidden;
try
{
Process.Start(p);
MessageBox.Show(printerName + " unistalled successfully");
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.ToString());
}
p = null;
}
}
public static string GetLocalIPAddress() //erxomeno feature
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
return ip.ToString();
}
}
throw new Exception("No network adapters with an IPv4 address in the system!");
}
public static class Winspool
{
[StructLayout(LayoutKind.Sequential)]
private class PRINTER_DEFAULTS
{
public string pDatatype;
public IntPtr pDevMode;
public int DesiredAccess;
}
[DllImport("winspool.drv", EntryPoint = "XcvDataW", SetLastError = true)]
private static extern bool XcvData(
IntPtr hXcv,
[MarshalAs(UnmanagedType.LPWStr)] string pszDataName,
IntPtr pInputData,
uint cbInputData,
IntPtr pOutputData,
uint cbOutputData,
out uint pcbOutputNeeded,
out uint pwdStatus);
[DllImport("winspool.drv", EntryPoint = "OpenPrinterA", SetLastError = true)]
private static extern int OpenPrinter(
string pPrinterName,
ref IntPtr phPrinter,
PRINTER_DEFAULTS pDefault);
[DllImport("winspool.drv", EntryPoint = "ClosePrinter")]
private static extern int ClosePrinter(IntPtr hPrinter);
public static int AddLocalPort(string portName)
{
PRINTER_DEFAULTS def = new PRINTER_DEFAULTS();
def.pDatatype = null;
def.pDevMode = IntPtr.Zero;
def.DesiredAccess = 1; //Server Access Administer
IntPtr hPrinter = IntPtr.Zero;
int n = OpenPrinter(",XcvMonitor Local Port", ref hPrinter, def);
if (n == 0)
return Marshal.GetLastWin32Error();
if (!portName.EndsWith("\0"))
portName += "\0"; // Must be a null terminated string
// Must get the size in bytes. Rememeber .NET strings are formed by 2-byte characters
uint size = (uint)(portName.Length * 2);
// Alloc memory in HGlobal to set the portName
IntPtr portPtr = Marshal.AllocHGlobal((int)size);
Marshal.Copy(portName.ToCharArray(), 0, portPtr, portName.Length);
uint needed; // Not that needed in fact...
uint xcvResult; // Will receive de result here
XcvData(hPrinter, "AddPort", portPtr, size, IntPtr.Zero, 0, out needed, out xcvResult);
ClosePrinter(hPrinter);
Marshal.FreeHGlobal(portPtr);
return (int)xcvResult;
}
}
}
}
Ok, I Can't do this that way.
First I have to create a port monitor I have used mfilemon.dll
Then I created a port with that port monitor
Then Pasted All Driver files in System Driver Dictionary.
Then finally Added Printer And Done.
You can refer this
https://github.com/Gohulan/Virtual-Printer/blob/main/PrinterSetup/SpoolerHelper.cs
This contains all the steps to create a virtual printer to make a print to pdf virtual printer
"System.UnauthorizedAccessException" - I've seen this message on my screen for 2 days and just couldn't figured out why.
I've checked all the possible reasons in my knowledge to make it work but fail. Here is the summary of what I have checked:
The file in the shared drive (mapped drive in the local network) is not ready only and the full access permissions are granted to everyone. The folders in the file path are also been set to grant full access permissions to everyone.
I can delete the file manually
the file was created by the same user (me) and I need to delete it when there is a revision. (delete the old one and put the new one in)
when I change the destination folder to local drive (c:..), everything works well. No problems to delete files. But it won't work (System.UnauthorizedAccessException) when I change it to the shared drive (H: drive).
Here are the codes related to the exception:
fdname = inipath + Convert.ToString(ynum);
if (! Directory.Exists(fdname))
System.IO.Directory.CreateDirectory(fdname);
fdname = inipath + Convert.ToString(ynum) + "\\" + Convert.ToString(fpathnum);
if (!Directory.Exists(fdname))
System.IO.Directory.CreateDirectory(fdname);
fdname = inipath + Convert.ToString(ynum) + "\\" + Convert.ToString(fpathnum) + "\\" + Convert.ToString(salodrnum);
if (!Directory.Exists(fdname))
{
System.IO.Directory.CreateDirectory(fdname);
File.SetAttributes(fdname, FileAttributes.Normal);
// File.SetAttributes(fdname, File.GetAttributes(fdname) & ~FileAttributes.ReadOnly); //remove read ony
}
if (File.Exists(fdname + #"\PS" + salodrnum + ".pdf"))
{
File.SetAttributes(fdname + #"\PS" + salodrnum + ".pdf", FileAttributes.Normal);
File.Delete(fdname + #"\PS" + salodrnum + ".pdf");
}
doc.ExportToDisk(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat, fdname + #"\PS" + salodrnum + ".pdf");
File.SetAttributes(fdname + #"\PS" + salodrnum + ".pdf", FileAttributes.Normal);
procForm.Close();
It is a permission issue but I just couldn't figure out where the problem is. Here is the debugging details:
System.UnauthorizedAccessException
HResult=0x80070005
Message=Access to the path 'H:\OrderFiles\21\21003\2100337\PS2100337.pdf' is denied.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.File.InternalDelete(String path, Boolean checkHost)
at System.IO.File.Delete(String path)
at OpenOrder.PSForm.crystalReportViewer1_Load(Object sender, EventArgs
e) in C:\SG100sys\Source Codes\OpenOrder\OpenOrder\PSForm.cs:line 188
This exception was originally thrown at this call stack:
[External Code]
OpenOrder.PSForm.crystalReportViewer1_Load(object, System.EventArgs) in PSForm.cs
Probably off-topic, but in case it helps.
I remember having that headache a while ago while trying to replace files on a mapped drive in a machine that had to interact with that and other network locations, often with different credentials. I ended up using a custom impersonation context and passing the domain and credentials each time. I have this method in my FileUtil lib:
public static void InteractWithNetworkFolder(Action MethodThatInteractsWithTheFolder, string Domain, string Username, string Password)
{
var ImpersonationContext = new WrappedImpersonationContext(Domain, Username, Password);
ImpersonationContext.Enter();
MethodThatInteractsWithTheFolder.Invoke();
ImpersonationContext.Leave();
}
In your case, you'd use it like this:
FileUtil.InteractWithNetworkFolder(() => File.Delete(PathToYourFile), Domain, Username, Password)
And the impersonation context (credit to it's creator) looks like this:
public sealed class WrappedImpersonationContext
{
public enum LogonType : int
{
Interactive = 2,
Network = 3,
Batch = 4,
Service = 5,
Unlock = 7,
NetworkClearText = 8,
NewCredentials = 9
}
public enum LogonProvider : int
{
Default = 0, // LOGON32_PROVIDER_DEFAULT
WinNT35 = 1,
WinNT40 = 2, // Use the NTLM logon provider.
WinNT50 = 3 // Use the negotiate logon provider.
}
[DllImport("advapi32.dll", EntryPoint = "LogonUserW", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain,
String lpszPassword, LogonType dwLogonType, LogonProvider dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll")]
public extern static bool CloseHandle(IntPtr handle);
private string _domain, _password, _username;
private IntPtr _token;
private WindowsImpersonationContext _context;
private bool IsInContext
{
get { return _context != null; }
}
public WrappedImpersonationContext(string domain, string username, string password)
{
_domain = String.IsNullOrEmpty(domain) ? "." : domain;
_username = username;
_password = password;
}
// Changes the Windows identity of this thread. Make sure to always call Leave() at the end.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Enter()
{
if (IsInContext)
return;
_token = IntPtr.Zero;
bool logonSuccessfull = LogonUser(_username, _domain, _password, LogonType.NewCredentials, LogonProvider.WinNT50, ref _token);
if (!logonSuccessfull)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
WindowsIdentity identity = new WindowsIdentity(_token);
_context = identity.Impersonate();
Debug.WriteLine(WindowsIdentity.GetCurrent().Name);
}
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Leave()
{
if (!IsInContext)
return;
_context.Undo();
if (_token != IntPtr.Zero)
{
CloseHandle(_token);
}
_context = null;
}
}
Please try to check for less convoluted solutions before jumping into this one.
I am using the following code to get and set environment variables.
public static string Get( string name, bool ExpandVariables=true ) {
if ( ExpandVariables ) {
return System.Environment.GetEnvironmentVariable( name );
} else {
return (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey( #"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\" ).GetValue( name, "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames );
}
}
public static void Set( string name, string value ) {
System.Environment.SetEnvironmentVariable( name, value );
}
The problem I face, is even when the program is running as administrator, the environment variable lasts only as long as the program is running. I have confirmed this by running a Get on the variable I set in a previous instance.
Example usage of above
Set("OPENSSL_CONF", #"c:\openssl\openssl.cfg");
And to retrieve
MessageBox.Show( Get("OPENSSL_CONF") );
While the program is running, after using Set, the value is returned using Get without any issue. The problem is the environment variable isn't permanent (being set on the system).
It also never shows up under advanced properties.
Thanks in advance.
While the program is running, after using Set, the value is returned
using Get without any issue. The problem is the environment variable
isn't permanent (being set on the system).
Thats because the overload of SetEnvironmentVariable that you're using stores in the process variables. From the docs:
Calling this method is equivalent to calling the
SetEnvironmentVariable(String, String, EnvironmentVariableTarget)
overload with a value of EnvironmentVariableTarget.Process for the
target argument.
You need to use the overload specifying EnvironmentVariableTarget.Machine instead:
public static void Set(string name, string value)
{
Environment.SetEnvironmentVariable(name, value, EnvironmentVariableTarget.Machine);
}
According to MSDN the method you are using is just modifying the variable for the runtime of the process.
Try the overload described here: https://msdn.microsoft.com/library/96xafkes%28v=vs.110%29.aspx
This kind of question has already been asked multiple times, check the following links for more information:
Set Env Variable - 1
Set Env Variable - 2
Set Env Variable - Tutorial
Here's an example that permanently updates the User PATH variable by programmatically editing the registry:
// Admin Permission not-required:
// HKCU\Environment\Path
// Admin Permission required:
// HKLM\SYSTEM\CurrentControlSet\Control
// \Session Manager\Environment\Path
public static void UserPathAppend(string path, int verbose=1) {
string oldpath = UserPathGet();
List<string> newpathlist = oldpath.Split(';').ToList();
newpathlist.Add(path);
string newpath = String.Join(";", newpathlist.ToArray());
UserPathSet(newpath);
UpdateEnvPath();
if (verbose!=0) {
System.Windows.MessageBox.Show(
"PATH APPEND:\n\n"
+ path + "\n\n"
+ "OLD HKCU PATH:\n\n"
+ oldpath + "\n\n"
+ "NEW HKCU PATH:\n\n"
+ newpath + "\n\n"
+ "REGISTRY KEY MODIFIED:\n\n"
+ "HKCU\\Environment\\Path\n\n"
+ "NOTE:\n\n"
+ "'Command Path' is a concat of 'HKLM Path' & 'HKCU Path'.\n",
"Updated Current User Path Environment Variable"
);
}
}
public static void UserPathPrepend(string path, int verbose=1) {
string oldpath = UserPathGet();
List<string> newpathlist = oldpath.Split(';').ToList();
newpathlist.Insert(0, path);
string newpath = String.Join(";", newpathlist.ToArray());
UserPathSet(newpath);
UpdateEnvPath();
if (verbose != 0) {
System.Windows.MessageBox.Show(
"PATH PREPEND:\n\n"
+ path + "\n\n"
+ "OLD HKCU PATH:\n\n"
+ oldpath + "\n\n"
+ "NEW HKCU PATH:\n\n"
+ newpath + "\n\n"
+ "REGISTRY KEY MODIFIED:\n\n"
+ "HKCU\\Environment\\Path\n\n"
+ "NOTE:\n\n"
+ "'Command Path' is a concat of 'HKLM Path' & 'HKCU Path'.\n",
"Updated Current User Path Environment Variable"
);
}
}
public static string UserPathGet()
{
// Reads Registry Path "HKCU\Environment\Path"
string subKey = "Environment";
Microsoft.Win32.RegistryKey sk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(subKey);
if (sk == null)
return null;
else
return sk.GetValue("Path").ToString();
}
public static void UserPathSet(string newpath)
{
// Writes Registry Path "HKCU\Environment\Path"
string subKey = "Environment";
Microsoft.Win32.RegistryKey sk1 = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(subKey);
sk1.SetValue("Path", newpath);
}
//===========================================================
// Private: This part required if you don't want to logout
// and login again to see Path Variable update
//===========================================================
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr SendMessageTimeout(IntPtr hWnd,
uint Msg, UIntPtr wParam, string lParam,
SendMessageTimeoutFlags fuFlags,
uint uTimeout, out UIntPtr lpdwResult);
private enum SendMessageTimeoutFlags : uint
{
SMTO_NORMAL = 0x0, SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2, SMTO_NOTIMEOUTIFNOTHUNG = 0x8
}
private static void UpdateEnvPath() {
// SEE: https://support.microsoft.com/en-us/help/104011/how-to-propagate-environment-variables-to-the-system
// Need to send WM_SETTINGCHANGE Message to
// propagage changes to Path env from registry
IntPtr HWND_BROADCAST = (IntPtr)0xffff;
const UInt32 WM_SETTINGCHANGE = 0x001A;
UIntPtr result;
IntPtr settingResult
= SendMessageTimeout(HWND_BROADCAST,
WM_SETTINGCHANGE, (UIntPtr)0,
"Environment",
SendMessageTimeoutFlags.SMTO_ABORTIFHUNG,
5000, out result);
}
I have event method eventManager_ServiceFound then inside that method there is event assigned to the method eventManager_ServiceResolved and I would like to pass to that method some additional parameters from method eventManager_ServiceFound.
Something like:
static void eventManager_ServiceResolved(parameters which are already there, string domain(form eventManager_ServiceFound)).
How the code looks:
public static void ScanService() {
try {
service = new DNSSDService();
eventManager = new DNSSDEventManager();
eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(eventManager_ServiceFound);
browse = service.Browse(0, 0, "_axis-video._tcp", null, eventManager);
} catch (Exception e) {
Console.WriteLine("--------------------EXCEPTION-----------------");
Console.WriteLine(e);
Console.WriteLine("--------------------EXCEPTION-----------------");
}
}
static void eventManager_ServiceFound(DNSSDService browser, DNSSDFlags flags, uint ifIndex, string serviceName, string regtype, string domain) {
try {
Console.WriteLine("---------------- eventManager_ServiceFound------------------------");
Console.WriteLine("browser: " + browser + "\nDNSSDFlags " + flags + "\nifIndex " + ifIndex + "\nserviceName: " + serviceName + "\nregtype: " + regtype + "\ndomain: " + domain);
Console.WriteLine("----------------------------------------");
// DNSSDService service2 = new DNSSDService();
eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(eventManager_ServiceResolved);
browser.Resolve(flags, ifIndex, serviceName, regtype, domain, eventManager);
} catch (Exception e) {
Console.WriteLine("--------------------EXCEPTION--------eventManager_ServiceFound---------");
Console.WriteLine(e);
Console.WriteLine("--------------------EXCEPTION-----------------");
}
}
private static void eventManager_ServiceResolved(DNSSDService service, DNSSDFlags flags, uint ifIndex, string fullname, string hostname, ushort port, TXTRecord record) {
try {
Console.WriteLine("-------------------eventManager_ServiceResolved---------------------");
Console.WriteLine("DNSSDService " + service + "\nDNSSDFlags " + flags + "\nifindex " + ifIndex + "\nfullname " + fullname + "hostname " + hostname + "\nport " + port + "\nrecord " + record);
var str = System.Text.Encoding.Default.GetString(record.GetValueForKey("macaddress"));
Console.WriteLine("mac " + str);
Console.WriteLine("----------------------------------------");
// DNSSDService service2 = new DNSSDService();
eventManager.AddressFound += new _IDNSSDEvents_AddressFoundEventHandler(eventManager_AddressFound);
DNSSDAddressFamily family = new DNSSDAddressFamily();
service.GetAddrInfo(flags, ifIndex, family, hostname, eventManager);
} catch (Exception e) {
Console.WriteLine("--------------------EXCEPTION--------eventManager_ServiceResolved---------");
Console.WriteLine(e);
Console.WriteLine("--------------------EXCEPTION-----------------");
}
}
EDIT:
eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(eventManager_ServiceResolved);//how to convert this line into this one below
eventManager.ServiceResolved += (x, y, z) => eventManager_ServiceResolved(x, y, z, a, b, c);
browser.Resolve(flags, ifIndex, serviceName, regtype, domain, eventManager);
EDIT2:
There will be only one fire of service resolved for one fire of service found. But there will be many service found fires
Use a lambda:
eventManager.ServiceResolved += (x, y, z) => eventManager_ServiceResolved(x, y, z, a, b, c);
I'm currently working on a script (using NAnt and C#) running on a TeamCity server, which is to create and deploy an MSI file on a remote computer. The remote computer is set up with a shared folder which the TeamCity server is to connect to and copy the MSI file into, though the script. And it works the first time I run it without any problem.
But when I run the script a second time, it throws an exception with the following the message when it tries to connect to the share on the remote computer;
"A specified logon session does not exist. It may already have been terminated."
I use the solution from this thread to copy the MSI file from the TeamCity server to the remote computer using logon cridentials.
The following is the C# script in my NAnt file which does the file copy:
//Script main entry point
public static void ScriptMain(Project project)
{
NetworkCredential deployTargetCridentials = new NetworkCredential(project.Properties["deploy.remotesvr.username"],
project.Properties["deploy.remotesvr.password"]);
string connection = #"\\" + project.Properties["deploy.remotesvr"] + project.Properties["deploy.remotesvr.sharepath"];
string sourceFile = project.Properties["wix.output.dir"] + #"\" + project.Properties["wix.output.file"] + ".msi";
string destinationFile = #"\\" + project.Properties["deploy.remotesvr"] +
project.Properties["deploy.remotesvr.sharepath"] + #"\" +
project.Properties["deploy.remotesvr.deployfile"];
//Copy installation file to deploy share
Copy(project
, project.Properties["wix.output.dir"]
, project.Properties["wix.output.file"] + ".msi"
, #"\\" + project.Properties["deploy.remotesvr"] + project.Properties["deploy.remotesvr.sharepath"]
, project.Properties["deploy.remotesvr.deployfile"]
, deployTargetCridentials);
////
}
//Copy MSI
public static void Copy(Project project, string sourcePath, string sourceFile, string destinationPath, string destinationFile, NetworkCredential cridentials)
{
string source = sourcePath + #"\" + sourceFile;
string destination = destinationPath + #"\" + destinationFile;
try
{
project.Log(Level.Info, " ");
project.Log(Level.Info, "Copying " + source + " to " + destination);
project.Log(Level.Info, " Connecting to copy share: " + destinationPath);
using (new NetworkConnection(destinationPath, cridentials))
{
project.Log(Level.Info, " Copying file");
File.Copy(source, destination, true);
}
project.Log(Level.Info, "Copy successfull!");
}
catch (Exception ex)
{
project.Log(Level.Warning, "WARNING: Could not copy file: " + ex.Message.ToString().Trim().Replace("\r\n", ""));
}
}
////
//NetworkConnection class
public class NetworkConnection : IDisposable
{
string _networkName;
public NetworkConnection(string networkName, NetworkCredential credentials)
{
_networkName = networkName;
NetResource netResource = new NetResource();
netResource.Scope = ResourceScope.GlobalNetwork;
netResource.ResourceType = ResourceType.Disk;
netResource.DisplayType = ResourceDisplaytype.Share;
netResource.RemoteName = networkName;
int result = WNetAddConnection2(netResource, credentials.Password, credentials.UserName, 0);
if (result != 0 && result != 1219)
{
throw new Win32Exception(result);
}
}
~NetworkConnection()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
WNetCancelConnection2(_networkName, 0, true);
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2(NetResource netResource, string password, string username, int flags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2(string name, int flags, bool force);
}
[StructLayout(LayoutKind.Sequential)]
public class NetResource
{
public ResourceScope Scope;
public ResourceType ResourceType;
public ResourceDisplaytype DisplayType;
public int Usage;
public string LocalName;
public string RemoteName;
public string Comment;
public string Provider;
}
public enum ResourceScope : int
{
Connected = 1,
GlobalNetwork,
Remembered,
Recent,
Context
};
public enum ResourceType : int
{
Any = 0,
Disk = 1,
Print = 2,
Reserved = 8
}
public enum ResourceDisplaytype : int
{
Generic = 0x0,
Domain = 0x01,
Server = 0x02,
Share = 0x03,
File = 0x04,
Group = 0x05,
Network = 0x06,
Root = 0x07,
Shareadmin = 0x08,
Directory = 0x09,
Tree = 0x0a,
Ndscontainer = 0x0b
}
The exception occurs at the following line in Copy;
using (new NetworkConnection(destinationPath, cridentials))
When I tried to run the same copy code in a test application, it copied the file every time. Its only when I run it through the script that the exception occurs.
Does anyone have any idea to why this is?
Have you tried testing for / closing any existing connections prior to opening a new one?