|
I have a method that creates a new process and calls the command line. I can get standardoutput into the procResults strings for most of my calls. But for some reason when I use this method to call devenv to build a c# solution I don't get anything in standardoutput. It seems like it finishes the call because all new files are built and I can see the last modified date is the current time, but the procResults string is empty. Here is my call:
'devenv alphacetui.sln /rebuild "debug|x86"'
it seems like it finishes ok because I get a p.Exitcode = 0;
Does anyone have experience calling devenv from system.process or know why I'm not getting output?
when I run devenv alphacetui.sln /rebuild "debug|x86" from the command line it works fine and I can see the output in the command window.
public void method()
{
Process p = new Process();
p.StartInfo.FileName = "devenv";
p.StartInfo.Arguments = "alphacetui.sln /rebuild \"debug|x86\"";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.Start();
string procResults = p.StandardOutput.ReadToEnd();
p.WaitForExit();
}
|
|
|
|
|
Hello All;
I am getting an exception when trying to load my XML file with C#.
Here is my XML:
<?xml version="1.0"?>
<CADLaunch>
<LastAutoCADVersion>AutoCAD MEP 2009</LastAutoCADVersion>
<LastProfile>ShopData Old</LastProfile>
</CADLaunch>
And the code to load it:
XmlDocument test = new XmlDocument();
if (File.Exists(supportDir + "\\LaunchCAD.xml"))
{
test.LoadXml(supportDir + "\\LaunchCAD.xml");
}
The load line is giving me this exception:
An unhandled exception of type 'System.Xml.XmlException' occured in System.Xml.dll
Additional Information: Data at the root level is invalid. Line 1, position 1.
I can't tell what I am doing wrong...
Thanks in advance.
|
|
|
|
|
|
...it's always the simplest answer you overlook the most...
I will try it. But do you know if I will still be able to search for nodes by just using 'Load'?
|
|
|
|
|
Once it's loaded into an XmlDocument, use methods like SelectSingleNode.
|
|
|
|
|
You're using the wrong function.
It's not loading LaunchCAD.xml... It's trying to load "LaunchCAD.xml"
LoadXml() is for when you've already read the document into a string... What you want is the Load() function.
|
|
|
|
|
|
ok...
I thought I uderstood it but apparently not... I am new to this stuff.
test.Load(supportDir += "\\LaunchCAD.xml");
string nResult = test.SelectSingleNode("LastAutoCADVersion").InnerText.ToString();
I get an 'Object reference not set to an instance of an object.' exception on the SelectSingleNode line. I am assuming that is because I am still loading the file incorrectly. But am at a loss as to the correct method.
|
|
|
|
|
Not really, LastAutoCADVersion isn't the root and you pretended that it was, you can use "//LastAutoCADVersion" instead
|
|
|
|
|
|
Hi everyone, I am currently looking for a solution to prevent a user from opening the CD drive during a cruicial burning process. I think I'm close, like real close but the last hurdle is keeping me back.
I've found the right api for the job, but it's unmanaged in C++ and porting to C# is real tricky. So essentially that is the answer I am after.
I've figured out that at some point my solution involves: IOCTL_STORAGE_EJECT_CONTROL and PREVENT_MEDIA_REMOVAL, being used with the function DeviceIoControl()
I have these snippets which I have edited into my code.
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool DeviceIoControl(
IntPtr hDevice,
uint dwIoControlCode,
ref long InBuffer,
int nInBufferSize,
ref long OutBuffer,
int nOutBufferSize,
ref int pBytesReturned,
[In] ref NativeOverlapped lpOverlapped);
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
string fileName,
[MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
[MarshalAs(UnmanagedType.U4)] FileShare fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
int flags,
IntPtr template);
private void SomethingMethod()
{
IntPtr tHandle = CreateFile(@"\\.\" + destVolume, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero,
FileMode.Open, 0, IntPtr.Zero);
Bool success = DeviceIoControl(something, IOCTL_STORAGE_EJECT_CONTROL, something, something,
something, and so on);
}
I'm sure most of you will recognise that I am importing the dll libraries but the issue I am having is the Structure or Enums (I'm not quite which which is which) as I believe that IOCTL_STORAGE_EJECT_CONTROL and PREVENT_MEDIA_REMOVAL are stored as 'structs' somewhere.
So in brief, all I need to know are what parameters I need to pass to DeviceIoControl to stop the drive from ejecting.
Many Thanks.
modified on Friday, August 28, 2009 4:18 AM
|
|
|
|
|
Hi,
all I have is some comments:
1. please use PRE tags to show readable code snippets.
2. don't confuse native and managed types, they sometimes have a different length (e.g. long and char)
3. the details of IOCTL_STORAGE_EJECT_CONTROL must be available on the web; make google your friend!
4. CreateFile at the device level is bound to fail (access denied) for regular users on Windows Vista and above.
5. I'm rather convinced I can always open the optical drive, that is a hardware function, something software might trigger, but AFAIK not prevent.
|
|
|
|
|
This shouldn't be too tricky. I found this VB code[^], which should be a good start and faily easy to 'translate' to C#.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
But there's this leeeetle hole on a CD/DVD drive; if you insert an unfolded paper clip you can eject the drive no matter what.
So you're after an unachievable goal; I doubt it's worth the trouble. Just put up a "Please don't eject the disc until this process is complete" message, with a progress bar.
|
|
|
|
|
By that logic software should never do anything to prevent the user from closing it instantly while it's writing a file or the like; afterall even if you use the malware coders guide to protect your process from being killed, the user could yank the power/battery no matter what you do. Personally I want my software to ignore a close message until they finish writing any files, etc (or the attempt times out over the lan).
The latest nation. Procrastination.
|
|
|
|
|
Not at all (even were it relevent); an application can account for its own behaviour -- if it's writing it can wait until it's done, or prompt for abort.
|
|
|
|
|
While the OP hasn't stated exactly what the critical activity the CD drive is doing, during a CD-R burning session ejecting the disk and terminating an application in mid file write only differ in that the ejected CD is ruined representing a financial loss as opposed to potentially recoverable data corruption.
The latest nation. Procrastination.
|
|
|
|
|
But given that the app will handle the case where it is asked to exit during the activity, I don't see the relevence.
I believe the OP is concerned about the user pressing the eject button, ejecting from Explorer, or perhaps another app accessing the drive.
It appears that blocking those is achievable, and perhaps enough for the OP.
My point (and I do have one) is that there is at least one other method of ejecting the disc without otherwise affecting the app and OS that can't be blocked.
The OP should merely be aware that he will not have 100% ensurance that the disc can't be ejected.
|
|
|
|
|
True, however not all drives have a pinhole to force an eject, and most non-power users have no idea about what it does. Your original post appear to be implying that because there was a hardware endrun around any protection that could could code in that writing code to cover the normalish methods wasn't a worthwhile objective. Apologies if I misunderstood your intent.
The latest nation. Procrastination.
|
|
|
|
|
Hi everyone, I really wasn't expecting such a big response. Thank you everyone for your replies.
It is true that all effort are futile due to the tiny weeny hole because the hole is an emergency overwrite incase a program locks the drive and shutdowns with releasing it or something, but PIEBALDconsult is correct in their assumsion that I wish to prevent the eject button from being accidently pressed (trust me it happens alot on laptops), or being ejected from explorer or even being eject by someone elses program.
DaveyM69, I found your link to the VB code excellent. I never stumbled across that page during my search. And I agree with you on hand-fed code, but wow that's some great work dude, I'll have to implement it now, so that your efforts aren't in vain. Many thanks. I hope that search engines point here after this because those are some really good answers.
|
|
|
|
|
I don't normally hand feed answers - but I found your problem interesting so I 've converted the VB code I linked to.
It's rough and ready and needs a bit of work - but it does what you want. Just call LockMedia("X", true); to lock, and LockMedia("X", false); to unlock where X = drive letter.
Sources (most MSDN - a good resource!):
CreateFile[^]
DeviceIoControl[^]
SECURITY_ATTRIBUTES[^]
CloseHandle[^]
VB Code[^]
public static class CDDriveControl
{
public static bool LockMedia(string driveLetter, bool lockDrive)
{
bool result = false;
string fullDrivePath = string.Format(@"\\.\{0}:", driveLetter);
SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
IntPtr hDrive = CreateFile(
fullDrivePath,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
ref securityAttributes,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if(hDrive != INVALID_HANDLE_VALUE)
{
IntPtr outBuffer;
int bytesReturned;
NativeOverlapped overlapped = new NativeOverlapped();
result = DeviceIoControl(
hDrive,
IOCTL_STORAGE_MEDIA_REMOVAL,
ref lockDrive,
1,
out outBuffer,
0,
out bytesReturned,
ref overlapped);
CloseHandle(hDrive);
}
return result;
}
private const uint GENERIC_READ = 0x80000000;
private const int FILE_SHARE_READ = 0x00000001;
private const int FILE_SHARE_WRITE = 0x00000002;
private const int OPEN_EXISTING = 3;
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int IOCTL_STORAGE_MEDIA_REMOVAL = 0x2D4804;
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateFile(
string lpFileName,
uint dwDesiredAccess,
int dwShareMode,
ref SECURITY_ATTRIBUTES lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool DeviceIoControl(
IntPtr hDevice,
int dwIoControlCode,
ref bool lpInBuffer,
int nInBufferSize,
out IntPtr lpOutBuffer,
int nOutBufferSize,
out int lpBytesReturned,
ref NativeOverlapped lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(
IntPtr hObject);
[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_ATTRIBUTES
{
int nLength;
IntPtr lpSecurityDescriptor;
bool bInheritHandle;
}
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Hi Dave,
Interesting. Does this work on Vista (and Win7)?
|
|
|
|
|
Untested - I don't have Win7 here, but will test on vista on my other box now
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Works fine on Vista without any UAC prompts
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Hi Dave,
Thanks. I just gave your code post a 5.
I'm surprised it works on Vista. I have been trying to get the real harddisk serial number, which can be attempted in a similar way: CreateFile at the device level, and do some reading. Vista doesn't let a regular user do that, and it is only reading that is needed!
I'll investigate further at some later time.
Still have to thinker about text file comparisons (see my sig).
cheers.
|
|
|
|
|