Running vshost.exe as a different user - c#

Can I start appname.vshost.exe from debug folder under different username than the one used to start VisualStudio?
There is appname.vshost.exe.config with the following content. Is there a config for username? I have tried searching for it but couldn't find anything.
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

If you're trying to run your debugg executable
You can try shift right click and Run as different user.
Or do you want to run as different user via configuration?

I don't think you can start vshost.exe under different user than the one you have used to start Visual Studio. So now I am starting main console app under different user from another console app and attaching debugger to it and it works.
I have copied my code below if it helps anyone.
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using EnvDTE80;
using Process = System.Diagnostics.Process;
namespace StartService
{
class Program
{
static void Main(string[] args)
{
var secure = new SecureString();
foreach (var c in "password-from-config")
{
secure.AppendChar(c);
}
Process process = null;
try
{
process = Process.Start(#"C:\Test Projects\WcfServiceTest\WcfServiceTest\bin\Debug\WcfServiceTest.exe",
"TestUser", secure, "DomainName");
Attach(GetCurrent());
Console.ReadKey();
}
finally
{
if (process != null && !process.HasExited)
{
process.CloseMainWindow();
process.Close();
}
}
}
public static void Attach(DTE2 dte)
{
var processes = dte.Debugger.LocalProcesses;
foreach (var proc in processes.Cast<EnvDTE.Process>().Where(proc => proc.Name.IndexOf("WcfServiceTest.exe") != -1))
proc.Attach();
}
internal static DTE2 GetCurrent()
{
var dte2 = (DTE2)Marshal.GetActiveObject("VisualStudio.DTE.12.0"); // Specific to VS2013
return dte2;
}
}
}

Related

Error executing SSIS package using C#

I try to execute a very simple SSIS Package using C#.
This package works fine when starting directly in Visual Studio 2015.
The name of the SSIS package is "Lesson 1.dtsx".
I try to start this process using C# with the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace run_ssis_project
{
public class ExecuteSSIS
{
public void exePackage()
{
String pkgLocation = #"C:\SSIS Tutorial\Lesson 1.dtsx";
Microsoft.SqlServer.Dts.Runtime.Package ssisPackage;
Microsoft.SqlServer.Dts.Runtime.Application app;
Microsoft.SqlServer.Dts.Runtime.DTSExecResult result;
app = new Microsoft.SqlServer.Dts.Runtime.Application();
ssisPackage = app.LoadPackage(pkgLocation,null);
result = ssisPackage.Execute();
if(result == Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success)
{
Console.WriteLine("Success");
}
else
{
Console.WriteLine("Failure");
}
}
}
}
When executing this code, I get an exception:
"Microsoft.SqlServer.Dts.Runtime.DtsRuntimeException", The package
failed to load due to error 0xC0011008 "Error loading from XML. No
further detailed error information.
The exception occurs in line: ssisPackage =
app.LoadPackage(pkgLocation,null);
I added two DLLs as references in this project:
Microsoft.SqlServer.DTSRuntimeWrap.dll
Microsoft.SqlServer.ManagedDTS.dll
Can someone help me please?
I didnt have any problem besides that i got an error about mix mode because it was running version 2.0 against a framework with version 4.0. So if this doesnt work you proberbly has an error in your ssis-package. Otherwise try to make a new ssis-packages which basically does nothing and see if you get success.
This is how my code looks like:
using Microsoft.SqlServer.Dts.Runtime;
namespace ConsoleApplication8
{
class Program
{
static void Main(string[] args)
{
string pkgLocation;
Package pkg;
Application app;
DTSExecResult pkgResults;
MyEventListener eventListener = new MyEventListener();
pkgLocation =
#"C:\Users\thoje\Documents\Visual Studio 2015\Projects\Integration Services Project8\Integration Services Project8\Package37.dtsx";
app = new Application();
pkg = app.LoadPackage(pkgLocation, eventListener);
pkgResults = pkg.Execute(null,null,eventListener,null,null);
Console.WriteLine(pkgResults.ToString());
Console.ReadKey();
}
}
class MyEventListener : DefaultEvents
{
public override bool OnError(DtsObject source, int errorCode, string subComponent,
string description, string helpFile, int helpContext, string idofInterfaceWithError)
{
// Output Error Message
Console.WriteLine("Error in {0}/{1} : {2}", source, subComponent, description);
return false;
}
}
}
And this is what i needed to correct in app.Config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>

How do you parse large SQL scripts into batches?

I have a very large sql file I want to break up into batches for execution.
I want to make sure I'm parsing it the same way that SSMS and SQLCMD do.
Microsoft has a great mixed mode assembly named Microsoft.SqlServer.BatchParser with a class named Parser that seams like it would do the trick.
It wants an implementation of IBatchSource as an argument to SetBatchSource before calling Parse().
Where can I find an implementation of IBatchSource, and more information on how to make use of this functionality?
I found the assembly Microsoft.SqlServer.BatchParser in the GAC along with it's friend Microsoft.SqlServer.BatchParserClient that contains implementations the interface IBatchSource.
namespace Microsoft.SqlServer.Management.Common
{
internal class BatchSourceFile : IBatchSource
internal class BatchSourceString : IBatchSource
}
The following conversation then occurred.
Assembly: Hello! My name is
Microsoft.SqlServer.Management.Common.ExecuteBatch. Would you like to StringCollection GetStatements(string sqlCommand)?
Me: Yes, I would, BatchParserClient assembly. Thanks for asking!
Repeatable Instructions (Do try this at home!)
Install Microsoft SQL Server 2008 R2 Shared Management Objects
Copy Microsoft.SqlServer.BatchParser.dll and Microsoft.SqlServer.BatchParserClient.dll from the GAC to a folder in your solution.
Reference Microsoft.SqlServer.BatchParser & Microsoft.SqlServer.BatchParserClient
Program.cs
using System;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using Microsoft.SqlServer.Management.Common;
namespace ScriptParser
{
class Program
{
static void Main(string[] args)
{
ExecuteBatch batcher = new ExecuteBatch();
string text = File.ReadAllText(#"Path_To_My_Long_Sql_File.sql");
StringCollection statements = batcher.GetStatements(text);
foreach (string statement in statements)
{
Console.WriteLine(statement);
}
}
}
}
App.Config
<?xml version="1.0"?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
</startup>
</configuration>
Another option is to use the ScriptDom as described in this answer: https://stackoverflow.com/a/32529415/26877.
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.SqlServer.TransactSql.ScriptDom;
namespace ScriptDomDemo
{
class Program
{
static void Main(string[] args)
{
TSql120Parser parser = new TSql120Parser(false);
IList<ParseError> errors;
using (StringReader sr = new StringReader(#"create table t1 (c1 int primary key)
GO
create table t2 (c1 int primary key)"))
{
TSqlFragment fragment = parser.Parse(sr, out errors);
IEnumerable<string> batches = GetBatches(fragment);
foreach (var batch in batches)
{
Console.WriteLine(batch);
}
}
}
private static IEnumerable<string> GetBatches(TSqlFragment fragment)
{
Sql120ScriptGenerator sg = new Sql120ScriptGenerator();
TSqlScript script = fragment as TSqlScript;
if (script != null)
{
foreach (var batch in script.Batches)
{
yield return ScriptFragment(sg, batch);
}
}
else
{
// TSqlFragment is a TSqlBatch or a TSqlStatement
yield return ScriptFragment(sg, fragment);
}
}
private static string ScriptFragment(SqlScriptGenerator sg, TSqlFragment fragment)
{
string resultString;
sg.GenerateScript(fragment, out resultString);
return resultString;
}
}
}

How do I compile a C# solution with Roslyn?

I have a piece of software that generates code for a C# project based on user actions. I would like to create a GUI to automatically compile the solution so I don't have to load up Visual Studio just to trigger a recompile.
I've been looking for a chance to play with Roslyn a bit and decided to try and use Roslyn instead of msbuild to do this. Unfortunately, I can't seem to find any good resources on using Roslyn in this fashion.
Can anyone point me in the right direction?
You can load the solution by using Roslyn.Services.Workspace.LoadSolution. Once you have done so, you need to go through each of the projects in dependency order, get the Compilation for the project and call Emit on it.
You can get the compilations in dependency order with code like below. (Yes, I know that having to cast to IHaveWorkspaceServices sucks. It'll be better in the next public release, I promise).
using Roslyn.Services;
using Roslyn.Services.Host;
using System;
using System.Collections.Generic;
using System.IO;
class Program
{
static void Main(string[] args)
{
var solution = Solution.Create(SolutionId.CreateNewId()).AddCSharpProject("Foo", "Foo").Solution;
var workspaceServices = (IHaveWorkspaceServices)solution;
var projectDependencyService = workspaceServices.WorkspaceServices.GetService<IProjectDependencyService>();
var assemblies = new List<Stream>();
foreach (var projectId in projectDependencyService.GetDependencyGraph(solution).GetTopologicallySortedProjects())
{
using (var stream = new MemoryStream())
{
solution.GetProject(projectId).GetCompilation().Emit(stream);
assemblies.Add(stream);
}
}
}
}
Note1: LoadSolution still does use msbuild under the covers to parse the .csproj files and determine the files/references/compiler options.
Note2: As Roslyn is not yet language complete, there will likely be projects that don't compile successfully when you attempt this.
I also wanted to compile a full solution on the fly. Building from Kevin Pilch-Bisson's answer and Josh E's comment, I wrote code to compile itself and write it to files.
Software Used
Visual Studio Community 2015 Update 1
Microsoft.CodeAnalysis v1.1.0.0 (Installed using Package Manager Console with command Install-Package Microsoft.CodeAnalysis).
Code
using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.MSBuild;
namespace Roslyn.TryItOut
{
class Program
{
static void Main(string[] args)
{
string solutionUrl = "C:\\Dev\\Roslyn.TryItOut\\Roslyn.TryItOut.sln";
string outputDir = "C:\\Dev\\Roslyn.TryItOut\\output";
if (!Directory.Exists(outputDir))
{
Directory.CreateDirectory(outputDir);
}
bool success = CompileSolution(solutionUrl, outputDir);
if (success)
{
Console.WriteLine("Compilation completed successfully.");
Console.WriteLine("Output directory:");
Console.WriteLine(outputDir);
}
else
{
Console.WriteLine("Compilation failed.");
}
Console.WriteLine("Press the any key to exit.");
Console.ReadKey();
}
private static bool CompileSolution(string solutionUrl, string outputDir)
{
bool success = true;
MSBuildWorkspace workspace = MSBuildWorkspace.Create();
Solution solution = workspace.OpenSolutionAsync(solutionUrl).Result;
ProjectDependencyGraph projectGraph = solution.GetProjectDependencyGraph();
Dictionary<string, Stream> assemblies = new Dictionary<string, Stream>();
foreach (ProjectId projectId in projectGraph.GetTopologicallySortedProjects())
{
Compilation projectCompilation = solution.GetProject(projectId).GetCompilationAsync().Result;
if (null != projectCompilation && !string.IsNullOrEmpty(projectCompilation.AssemblyName))
{
using (var stream = new MemoryStream())
{
EmitResult result = projectCompilation.Emit(stream);
if (result.Success)
{
string fileName = string.Format("{0}.dll", projectCompilation.AssemblyName);
using (FileStream file = File.Create(outputDir + '\\' + fileName))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(file);
}
}
else
{
success = false;
}
}
}
else
{
success = false;
}
}
return success;
}
}
}

Opening mp3 by not-default program C sharp

How can I open mp3 file with RealPlayer while the default is MediaPlayer
I know Process and ProcessStartInfo method, but I would like to know how to "open program with..."
Can you help me, plz?
Okay, so thought I'd make this possible for you before I clock off for the night. I have thrown together a working console application which loads (known) installed programs from the registry's App Path key. The solution is far from perfect, won't be the safest, fastest, or most reliable solution, and it certainly shouldn't be seen amongst any production code, but it is more than enough to aid you, hopefully, in developing what it is you need:
So, here is the code, minus the namespace...
using System;
using System.IO;
using Microsoft.Win32;
using System.Diagnostics;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
if (args.Length >= 0 && !string.IsNullOrEmpty(args[0]) && File.Exists(args[0]))
{
var programs = new InstalledPrograms();
var programKey = "RealPlay.exe".ToLowerInvariant();
if (programs.ContainsKey(programKey))
{
var programPath = programs[programKey];
if (!string.IsNullOrEmpty(programPath) && File.Exists(programPath))
{
var process = new Process();
process.StartInfo = new ProcessStartInfo(programPath);
process.StartInfo.Arguments = args[0];
if (process.Start())
{
Console.WriteLine("That was easy!");
}
else
{
Console.WriteLine("Hell's bells and buckets of blood, we seem to have hit a snag!");
}
}
}
}
else
{
Console.WriteLine("Specify a file as an argument, silly!");
}
Console.WriteLine();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
class InstalledPrograms : Dictionary<string, string>
{
static string PathKeyName = "Path";
static string RegistryKeyToAppPaths = #"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths";
public InstalledPrograms()
{
Refresh();
}
public void Refresh()
{
Clear();
using (var registryKey = Registry.LocalMachine.OpenSubKey(RegistryKeyToAppPaths))
{
var executableFullPath = string.Empty;
foreach (var registrySubKeyName in registryKey.GetSubKeyNames())
{
using (var registrySubKey = registryKey.OpenSubKey(registrySubKeyName))
{
executableFullPath = registrySubKey.GetValue(string.Empty) as string;
Add(registrySubKeyName.ToLowerInvariant(), executableFullPath);
}
}
}
}
}
}
Though we check for file existence, and other minor but necessary checks are made, you would still need to tighten this up further when plugged into the environment of your own code, including, among other things, exception handling for, but not limited to, registry access issues.

Retrieving Process Description Information

I am trying to retrieve process information and I'm aware that I can use:
Process[] myProcesses = Process.GetProcesses();
but how do I retrieve the process description? Is it via some Win32 API call? I'm running Vista and when I click under the Processes tab in Task Manager, I see the description.
What you see in Task Manager is actually the Description field of the executable image.
You can use the GetFileVersionInfo() and VerQueryValue() WinAPI calls to access various version informations, e.g. CompanyName or FileDescription.
For .Net way, use the FileDescription member of FileVersionInfo, instantiated with the executable name got via Process.MainModule.FileName.
Another way would be through Assembly. Load the Assembly from the executable image, then query the AssemblyDescriptionAttribute custom attribute.
You just have to go a bit further down the properties.
Suppose you have an instance of notepad running.
Process[] proc = Process.GetProcessesByName("notepad");
Console.WriteLine("Process version- " + proc[0].MainModule.FileVersionInfo.FileVersion);
Console.WriteLine("Process description- " + proc[0].MainModule.FileVersionInfo.FileDescription);
There you go !
This is the only way I could see to do it. I tried Process and Win32_Process, but no go.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Diagnostics;
namespace Management
{
class Program
{
static void Main(string[] args)
{
var ps = Process.GetProcesses();
foreach (var p in ps)
{
try
{
var desc = FileVersionInfo.GetVersionInfo(p.MainModule.FileName);
Console.WriteLine(desc.FileDescription);
}
catch
{
Console.WriteLine("Access Denied");
}
}
Console.ReadLine();
}
}
}

Categories